前言:
本片blog主要介绍基于这个项目的底层sensor驱动给应用层提供的接口过多,为了应用层能够方便的调用各sensor资源,故将sensor驱动接口进行了一定的封装,给应用层提供一个统一的接口便于读取数据。
代码分析:
get_pm.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <string.h>
#define UART_DEVICE_NAME "/dev/tty96B0"
#define BUF_LEN 256
static int fd = -1;
//设置串口通信速率9600 设置串口数据位8,停止位1 和 效验位无
static int open_dev(char *dev_name)
{
struct termios opt;
fd = open(dev_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0)
{
perror("open");
return fd;
}
tcgetattr(fd, &opt);
cfsetispeed(&opt, B9600);
cfsetospeed(&opt, B9600);
if(tcsetattr(fd, TCSANOW, &opt) != 0 )
{
perror("tcsetattr error");
return -1;
}
opt.c_cflag &= ~CSIZE;
opt.c_cflag |= CS8;
opt.c_cflag &= ~CSTOPB;
opt.c_cflag &= ~PARENB;
opt.c_cflag &= ~INPCK;
opt.c_cflag |= (CLOCAL | CREAD);
opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
opt.c_oflag &= ~OPOST;
opt.c_oflag &= ~(ONLCR | OCRNL); //添加的
opt.c_iflag &= ~(ICRNL | INLCR);
opt.c_iflag &= ~(IXON | IXOFF | IXANY); //添加的
opt.c_cc[VTIME] = 0;
opt.c_cc[VMIN] = 0;
tcflush(fd, TCIOFLUSH);
if(tcsetattr(fd, TCSANOW, &opt) != 0)
{
perror("serial error");
return -1;
}
return fd;
}
void addrs(int num)
{
int ret = -1;
if(num == 1 )
{
char buf_addrs[BUF_LEN]="0";
printf("THE DATA FROM pm2.5sensor 1 \n");
fd = open("/sys/class/gpio/gpio12/value",O_RDWR | O_NOCTTY | O_NONBLOCK);
if(fd < 0 )
{
perror("open");
exit(0);
}
ret = write(fd,buf_addrs,sizeof(buf_addrs));
if(ret < 0 )
{
printf("write buf_addrs1 error! \n");
exit(0);
}
close(fd);
}
else
{
char buf_addrs[BUF_LEN]="1";
printf("THE DATA FROM pm2.5sensor 2 \n");
fd = open("/sys/class/gpio/gpio12/value",O_RDWR | O_NOCTTY | O_NONBLOCK);
if(fd < 0 )
{
perror("open");
exit(0);
}
ret = write(fd,buf_addrs,sizeof(buf_addrs));
if(ret < 0 )
{
printf("write buf_addrs1 error! \n");
exit(0);
}
close(fd);
}
}
int get_pm(int num)
{
int fd;
int i;
int len;
int n = 0;
char buf_uart[BUF_LEN],grade;
int iRet = 0;
float pm_value = 0;
addrs(num);
fd = open_dev(UART_DEVICE_NAME);//init uart and open uart
if(fd == -1)
{
perror("open serial error\n");
exit(0);
}
while (1)
{
bzero(buf_uart, sizeof(buf_uart)); //类似于memset
len = read(fd, buf_uart, BUF_LEN);
if(len != 9)
continue;
buf_uart[len] = '\0';
if(len < 0)
{
perror("read");
exit(1);
}
pm_value = (int)buf_uart[3]+(int)buf_uart[4]*0.01;
break;
}
close(fd);
printf(" 当前空气质量: %4.2f %% \n", pm_value);
return pm_value;
}
pycall_v0.py
import os
import ctypes
class sensorManage():
def __init__(self):
self.mq2Value = self.mq2_data()
self.lightValue = self.light_data()
self.pm25Value1 = self.pm_data(1)
self.pm25Value2 = self.pm_data(2)
self.tempValue = self.temp_data()
self.humValue = self.humidity_data()
self.ultrValue = self.sonar_data()
self.fanStatus = self.fan_data("0")
self.buzzerStatus = self.beer_data("0")
self.sensorValueStatus = self.sensorStatus()
def pm_data(self,num):
ll = ctypes.cdll.LoadLibrary
lib = ll("./libget_pm.so")
data=lib.get_pm(num)
return data
def light_data(self):
fp = open("/sys/class/gpio/gpio24/value","w+")
return fp.read()
def mq2_data(self):
fp = open("/sys/class/gpio/gpio35/value","w+")
return fp.read()
def humidity_data(self):
fp = open("/sys/devices/platform/soc/soc:humidity_sensor/iio:device0/in_humidityrelative_input","w+")
return fp.read()
def temp_data(self):
fp = open("/sys/devices/platform/soc/soc:humidity_sensor/iio:device0/in_temp_input","w+")
return fp.read()
def sonar_data(self):
fp = open("/sys/devices/platform/soc/soc:sonar/value","w+")
return fp.read()
def fan_data(self,cmd):
fp = open("/sys/class/gpio/gpio16/value","w+")
fp.write(cmd)
return fp.read()
def beer_data(self,cmd):
fp = open("/sys/class/gpio/gpio18/value","w+")
fp.write(cmd)
return fp.read()