文章目录
本项目为阶段性练习,内容简洁实用,目的在于让初学者能够巩固前面知识,学以致用,逐步提升C++和Qt水平,为学习下面的教程做铺垫。本章节使用的资料已经放到了开发板网盘资料中,路径为“11_Linux系统开发进阶\Qt开发_章节使用资料”。
1 项目前准备
工具及环境:
1.开发环境:Ubuntu16.04
2.工具:Qt creator
3.迅为电子i.MX6ULL终结者开发板
MX6ULL终结者开发板已板载了DHT11传感器,且提供的Linux镜像和设备树已配置好了dht11接口,dht11驱动程序使用高版本Linux内核自带的稳定驱动程序,根文件系统使用网盘资料里的Yocto镜像,使用手册有详细的系统移植和 Qt5移植步骤。开发板要保证iio接口正常,如图 1.1:
cd /sys/bus/iio/devices/iio:device1
多cat几次, cat in_temp_input ,出现00为结尾的数字为正常
2 软件流程图
本实验目的是练习Qt的使用。把dht11采集的温度湿度显示在触摸屏的Qt上,并通过TCP传输到PC机的Qt界面上。应用程序将采集到的数据利用UDP网络套接字传输给终结者的 Qt进程,终结者的Qt将数据转发给PC端的Qt显示界面。流程图如图 2.1:
3 Linux应用程序
功能描述:
1.获取温湿度数据。
2.将温湿度封装成消息通过UDP发送到i.MX6ULL服务器。
高版本Linux内核自带了dht11 的驱动,使用者不用再去关心它的时序问题,可以用标准IO读取sysfs的/sys/bus/iio/devices/iio:device1/下的温湿度端口,测试读取成功后将数据发送到Qt进程。
为了让读者更好地理解Qt的 UDP,所以此处没有用到操作系统进程间通信机制,直接使用UDP网络套接字,代码在readDHT11.c:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
struct sockaddr_in serveraddr;
int len = sizeof(serveraddr);
/*
* 函数功能:读取温度
*/
int read_Humid(int * hum_Value)
{
int value, ret = 0;
FILE *fp;
char buf[20];
fp = fopen("/sys/bus/iio/devices/iio:device1/in_humidityrelative_input", "r" );
if( fp==NULL )
{
perror("fopen");
ret = -1;
return ret;
}
fread( buf, 1, sizeof(buf), fp );
fclose(fp);
sscanf( buf, "%d", &value );
*hum_Value = value;
return ret;
}
int read_Temp(int * tem_Value)
{
int value;
FILE *fp;
char buf[20];
fp = fopen("/sys/bus/iio/devices/iio:device1/in_temp_input", "r" );
if( fp==NULL )
{
perror("fopen");
return -1;
}
fread( buf, 1, sizeof(buf), fp );
fclose(fp);
sscanf( buf, "%d", &value );
*tem_Value = value;
return 0;
}
int mathDHT(int value)
{
return (value/1000);
}
/*
* 获取UDP socket
*/
int udpNet(void)
{
int sockfd;
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd <0){
perror("socket");
return -1;
}
return sockfd;
}
int main(int argc, const char *argv[])
{
int hum,tem,temNew,humiNew;
int temOld=0,humOld=-10;
int fdSocket = udpNet();//获取UDP套接字
char ts[6];
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons