基于GEC6818的QT开发之——通过不同按键控制DHT11模块的数据采集与动态显示

基于GEC6818的QT开发之——通过不同按键控制DHT11模块的数据采集与动态显示

使用环境:
ubantu16
QT5.7
开发板GEC6818
实现要求:
利用A53按键1、按键2与温湿度传感器完成QT界面动态显示温湿度记录,并指定温湿度记录超过指定范围,进行报警(LED,BEEP),按下key1时,允许进行采集;当key2按下,关闭数据采集。
效果演示视频:基于GEC6818的QT开发之——通过按键控制DHT11模块的数据采集与动态显示
视频效果为升级版。

文章目录

  • 基于GEC6818的QT开发之——通过不同按键控制DHT11模块的数据采集与动态显示
    • 一、驱动的加载
      • 1.1 dht11驱动加载
      • 1.2 按键驱动加载
      • 1.3蜂鸣器驱动加载
    • 二、DHT11引脚
    • 三、UI界面的设置
    • 四、DHT11
      • 4.1 DHT11使用的QTimer类的介绍
      • 4.2 dht11.cpp 代码
      • 4.3 dht11.h 代码
    • 五、按键
      • key 相关的代码
    • 六、蜂鸣器
    • 七、主类的完整代码

一、驱动的加载

我们在使用GEC6818开发板时,板上是没有DHT11的,而且与前面我们使用LED相同,我们同样需要一个与DHT11相配套的驱动,关于的撰写这里就不详细描述了,但是可以参考ARM开发之基于IIC协议的TM1650驱动实现,这篇文章是关于IIC协议的TM1605的驱动编写,可以仿照这些步骤对DHT11进行驱动编写。

将驱动下载到开发板并且进行加载

相关驱动已经与工程一起打包发在文章末尾的地址了。

1.1 dht11驱动加载


rx dht11_drv
rmmod dht11_drv.ko//先卸载,没有可以不用卸载insmod dht11_drv.ko//再加载

1.2 按键驱动加载

rx buttons_drv.kormmod buttons_drv.ko//先卸载,没有可以不用卸载insmod buttons_drv.ko//再加载

1.3蜂鸣器驱动加载


rx pwm.kormmod pwm.ko//先卸载,没有可以不用卸载insmod pwm.ko//再加载//****这个如果提示....busy 的话则执行*****rmmod gec6818_beep.ko再执行
insmod pwm.ko//再加载

二、DHT11引脚

有了相关驱动后,就可以对DHT11进行数据的读取啦,根据驱动:
在这里插入图片描述

可以看到GEC_6818的底板引脚图:
在这里插入图片描述

我们可以将DHT11的引脚如下图插入对应引脚。
在这里插入图片描述

三、UI界面的设置

一个简单的数据显示:
在这里插入图片描述

可以使用以上的方法,对应的控件名称如下:
在这里插入图片描述

关于如何对控件进命名,更换颜色等,可以参考博客:GEC6818的QT计算器计算的结果控制LED的亮灭的中间部分。

四、DHT11

4.1 DHT11使用的QTimer类的介绍

QTimer类提供了定时器信号单触发定时器。它在内部使用定时器事件来提供更通用的定时器。QTimer很容易使用:创建一个QTimer对象,使用start()来开始并且把它的timeout()连接到适当的槽函数。当这段时间过去了,它将会发射timeout()信号,对应的槽函数将被调用执行。值得注意的是当QTimer的父对象被销毁时,它也会被自动销毁。另外,QTimer的精确度依赖于底下的操作系统和硬件,绝大多数平台支持20毫秒的精确度,有些平台可以提供更高的,但是,如果您想获得更精确的毫秒级甚至微秒级的定时,不用考虑它了。

在主函数中的使用方法如下:

    QTimer *my_Timer;my_Timer = new QTimer;connect(my_Timer,SIGNAL(timeout()),this,SLOT(Main_Function()));my_Timer->setTimerType(Qt::PreciseTimer);my_Timer->start(500);

4.2 dht11.cpp 代码

由于这个案例涉及多个模块,所以我有多个cpp文件和.h文件,可以先看着理解一下,完整工程在文章末尾可以进行下载。


#include "dht11.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>#define GEC6818_GET_DHTDATA  _IOR('K', 0, unsigned int) //注册宏
unsigned char get_data[2];//存放数据的数组--(全局变量)
// ----------------------dht11 get data function-------
int dht11_get_data(void)
{int ret, cnt_yes=0, cnt_err=0;int ultrasonic_fd = open("/dev/dht11_dev", O_RDWR);//打开dht11的设备文件if(ultrasonic_fd < 0)//打开失败{perror("open dht11_dev driver");return -1;}printf("检测中\n");ret = ioctl(ultrasonic_fd, GEC6818_GET_DHTDATA, &get_data[0]);//读取if(ret != 0){cnt_err++;perror("GEC6818_GET_DHTDATA error");}else{cnt_yes++;printf("湿度= %hhd  温度=%hhd  错误%d  正确%d\n", get_data[1], get_data[0], cnt_err, cnt_yes);}sleep(1);close(ultrasonic_fd);//关闭设备文件return 0;
}

ps:我觉得这个驱动没写的很好,可以从上面的数据输出看出湿度的值太小了!

4.3 dht11.h 代码

#ifndef DHT11_H
#define DHT11_Hextern unsigned char get_data[4];
int dht11_get_data(void);#endif // DHT11_H

五、按键

一共有四个按键,如下:
在这里插入图片描述

key 相关的代码

    fd_key1=open("/dev/gecBt",O_RDONLY);if(fd_key1<0){printf("open  buttons fail!\n");}notifier = new QSocketNotifier(fd_key1,QSocketNotifier::Read,this);connect(notifier,SIGNAL(activated(int)),this,SLOT(key_get()));
//------------------------key----------
// 延时函数
void delay(unsigned value)
{while(value--);
}int beep_state=1;
int led_state=1;
void DHT11_KEY::key_get()
{char buttonValue[4];memset(buttonValue, 0, 4);::read( fd_key1, buttonValue, sizeof(buttonValue));for(int i=0;i < (int)sizeof(buttonValue); i++){switch(i){case 0://key1if(buttonValue[i]=='1'){state=1;printf("KEY1\n");}break;case 1://key2if(buttonValue[i]=='1'){state=0;printf("KEY2\n");}break;case 2://key4if(buttonValue[i]=='1'){beep_state=!beep_state;//反转printf("KEY3 press beep_state=%d\n",beep_state);}break;case 3://key4if(buttonValue[i]=='1'){led_state=!led_state;printf("KEY4 press led_state=%d\n",led_state);}break;}}Main_Function();
}

这段代码是一个简单的实现了读取嵌入式系统中按键状态的功能。

  1. fd_key1=open("/dev/gecBt",O_RDONLY);:这行代码打开了名为"/dev/gecBt"的设备文件,该设备文件用于读取按键状态。它返回一个文件描述符(file descriptor),如果打开失败,则文件描述符为负值。

  2. if(fd_key1<0):检查文件描述符是否有效。如果文件描述符小于0,则说明打开失败,输出错误消息。

  3. notifier = new QSocketNotifier(fd_key1,QSocketNotifier::Read,this);:创建一个QSocketNotifier对象,用于监听文件描述符fd_key1的读取事件。这样,当有数据可读取时,就会触发信号activated(int)。

  4. connect(notifier,SIGNAL(activated(int)),this,SLOT(key_get()));:将notifier的activated(int)信号连接到key_get()槽函数。这意味着当文件描述符fd_key1上有数据可读取时,将调用key_get()函数。

  5. void DHT11_KEY::key_get():key_get()函数是一个槽函数,用于处理文件描述符上的数据读取事件。它从文件描述符fd_key1中读取按键状态,并根据按键状态执行相应的操作。

  6. char buttonValue[4];:定义一个大小为4的字符数组,用于存储按键状态。

  7. ::read(fd_key1, buttonValue, sizeof(buttonValue));:从文件描述符fd_key1中读取4个字节的数据,即按键状态,并将其存储到buttonValue数组中。

  8. for(int i=0;i < (int)sizeof(buttonValue); i++):遍历buttonValue数组中的每个元素,以检查每个按键的状态。

  9. switch(i):根据当前迭代的索引值,选择不同的按键进行处理。

  10. case 0::处理第一个按键(key1)的状态。

  11. case 1::处理第二个按键(key2)的状态。

  12. case 2::处理第三个按键(key3)的状态。

  13. case 3::处理第四个按键(key4)的状态。

在每种情况下,根据按键的状态执行相应的操作,例如更改状态变量或输出调试信息。

六、蜂鸣器

在这里插入图片描述

#define  BUZZER_IOCTL_SET_FREQ 1
#define  BUZZER_IOCTL_STOP 0//---------------pwm----------------beep_fd = ::open("/dev/pwm", O_RDWR);if ( beep_fd < 0 )printf("open /dev/pwm  failed\n");
if(get_data[0]>25&&beep_state==1){::ioctl(beep_fd, BUZZER_IOCTL_SET_FREQ , freq );}else{::ioctl(beep_fd , BUZZER_IOCTL_STOP , freq);}

七、主类的完整代码

#include "dht11_key.h"
#include "ui_dht11_key.h"int state=0;
int beep_fd = -1;
int freq = 3000;
DHT11_KEY::DHT11_KEY(QWidget *parent) :QWidget(parent),ui(new Ui::DHT11_KEY)
{ui->setupUi(this);//---------------key-------fd_key1=open("/dev/gecBt",O_RDONLY);if(fd_key1<0){printf("open  buttons fail!\n");}notifier = new QSocketNotifier(fd_key1,QSocketNotifier::Read,this);connect(notifier,SIGNAL(activated(int)),this,SLOT(key_get()));//-------------led------------------Led_Init();//---------------pwm----------------beep_fd = ::open("/dev/pwm", O_RDWR);if ( beep_fd < 0 )printf("open /dev/pwm  failed\n");//-------DHT11--------------//my_Timer = new QTimer;connect(my_Timer,SIGNAL(timeout()),this,SLOT(Main_Function()));my_Timer->setTimerType(Qt::PreciseTimer);my_Timer->start(500);}DHT11_KEY::~DHT11_KEY()
{delete ui;if(beep_fd>0){::close(beep_fd);}if(fd_key1>0){::close(fd_key1);}}//------------------------key----------
// 延时函数
void delay(unsigned value)
{while(value--);
}int beep_state=1;
int led_state=1;
void DHT11_KEY::key_get()
{char buttonValue[4];memset(buttonValue, 0, 4);::read( fd_key1, buttonValue, sizeof(buttonValue));for(int i=0;i < (int)sizeof(buttonValue); i++){switch(i){case 0://key1if(buttonValue[i]=='1'){state=1;printf("KEY1\n");}break;case 1://key2if(buttonValue[i]=='1'){state=0;printf("KEY2\n");}break;case 2://key4if(buttonValue[i]=='1'){beep_state=!beep_state;//反转printf("KEY3 press beep_state=%d\n",beep_state);}break;case 3://key4if(buttonValue[i]=='1'){led_state=!led_state;printf("KEY4 press led_state=%d\n",led_state);}break;}}Main_Function();}//-----------------------main----------------void DHT11_KEY::Main_Function()
{if(state == 1){ui->Collect_State->setText(QString("open"));ui->Collect_State->setAlignment(Qt::AlignCenter);dht11_get_data();ui->humidity_data->setText(QString::number(get_data[1],10));ui->temperature_data->setText(QString::number(get_data[0],10));}else{ui->Collect_State->setText(QString("close"));ui->Collect_State->setAlignment(Qt::AlignCenter);}if(get_data[0]>25&&beep_state==1){::ioctl(beep_fd, BUZZER_IOCTL_SET_FREQ , freq );}else{::ioctl(beep_fd , BUZZER_IOCTL_STOP , freq);}if(get_data[1]>5&&led_state==1){Led2_open();Led1_open();
//            Led3_open();
//            Led4_open();}else{Led2_close();Led1_close();
//        Led3_close();
//        Led4_close();}}

本文中涉及的工程代码在我的github中可以进行下载03-DHT11简单版
升级版可以对数据以表格的形式展示,两个UI界面可以来回切换
地址:QT开发之两个UI界面切换与表格显示DHT11数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/755418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十五、ReentrantLock

synchronized本身是可重入锁 下述示例代码&#xff1a; 当i 2的时候会执行m2的synchronized锁 import java.util.concurrent.TimeUnit;public class T01_ReentrantLock1 {synchronized void m1() {for(int i0; i<10; i) {try {TimeUnit.SECONDS.sleep(1);} catch (Interr…

多模态:Vary-toy

文章目录 前言一、模型结构二、数据工程总结 前言 Vary的提出让大模型在OCR相关任务的能力有了很大突破&#xff0c;通过提出额外的视觉词汇表模块来弥补单一CLIP编码能力的不足&#xff0c;详情可参考我之前的文章——多模态&#xff1a;Vary。 最近Vary的团队开发了一个更小…

UE要收费?难道ue的使用成本要增加吗?

去年&#xff0c;Epic Games在裁员16%后&#xff0c;放出要对非游戏制作等行业使用UE进行收费的消息。3月12日&#xff0c;Epic Games正式宣布了对UE、实时可视化工具Twinmotio和摄影测量应用RealityCapture的新定价。 Epic Games将从下个月开始推出新的Unreal订阅模式&#x…

Vue.js中使用Web Workers来创建一个秒表

在Vue.js中使用Web Workers来创建一个秒表应用可以提高性能&#xff0c;因为Web Workers可以在后台线程中运行&#xff0c;不阻塞主线程。下面是一个简单的Vue.js秒表应用的示例&#xff0c;该应用使用Web Worker来执行计时功能。 首先&#xff0c;我们创建一个Web Worker文件…

python循环结构

循环结构 1.1遍历循环结构for 1.1.1遍历循环for (1)遍历循环for的语句结构: for 循环遍历 in 遍历对象&#xff1a; 语句块 程序执行&#xff1a; &#xff08;2&#xff09;示例&#xff1a; #遍历字符串 for i in hello:print(i) #range()函数&#xff0c;python中的内…

蓝桥杯-Sticks-DFS搜索

题目 样例输出是 6 5 题目中给错了&#xff0c;不知道什么时候会改。 思路 --剪枝&#xff0c;否则时间复杂度和空间复杂度过大&#xff0c;会超时。 --注意有多组测试样例时&#xff0c;需要将bool数组重新赋值为false。 --函数类型不是void&#xff0c;return语句不能省…

【FPGA】摄像头模块OV5640

本篇文章包含的内容 一、OV5640简介1.1 基本概述1.2 工作时序1.2.1 DVP Timing&#xff08;数据传输时序&#xff09;1.2.2 帧曝光工作模式 1.3 OV5640 闪光灯工作模式1.3.1 Xenon Flash&#xff08;氙灯闪烁&#xff09;模式1.3.2 LED 1&2 模式1.3.3 LED 3模式1.3.4 手动开…

Re62:读论文 GPT-2 Language Models are Unsupervised Multitask Learners

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文全名&#xff1a;Language Models are Unsupervised Multitask Learners 论文下载地址&#xff1a;https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learner…

接口测试开始前做什么?这10步缺一不可!

在进行接口测试之前&#xff0c;测试工程师需要进行一系列的准备工作&#xff0c;以确保测试的顺利进行。以下是接口测试开始之前的准备工作&#xff0c;并附有示例说明&#xff1a; 1. 了解项目和接口文档&#xff1a; 在开始测试之前&#xff0c;测试工程师需要仔细阅读项目…

Android 系统源码快速入门

Android源码快速入门 今天分享的内容是Android源码快速入门&#xff0c;主要分为以下几个步骤&#xff1a; * 硬件要求 * 虚拟机安装 * 开发环境搭建 * 下载编译源码 * 从一个简单的实际开发需求体验 Framework 开发硬件要求 用于 Android Framework 开发的电脑需要较强的 C…

sqlserver列出表的所有字段名

1、纵向列出所有字段 SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME tablename;2、横向列车所有字段&#xff0c;以‘&#xff0c;’分隔 SELECT STUFF((SELECT , column_nameFROM information_schema.columnsWHERE table_name tablenameFOR XM…

使用 Python 编写网络爬虫:从入门到实战

网络爬虫是一种自动化获取网页信息的程序&#xff0c;通常用于数据采集、信息监控等领域。Python 是一种广泛应用于网络爬虫开发的编程语言&#xff0c;具有丰富的库和框架来简化爬虫的编写和执行过程。本文将介绍如何使用 Python 编写网络爬虫&#xff0c;包括基本原理、常用库…

实地研究降本增效的杀伤力,LSTM算法实现全国失业率分析预测

前言 ​ 降本增效降本增笑&#xff1f;增不增效暂且不清楚&#xff0c;但是这段时间大厂的产品频繁出现服务器宕机和产品BUG确实是十分增笑。目前来看降本增效这一理念还会不断渗透到各行各业&#xff0c;不单单只是互联网这块了&#xff0c;那么对于目前就业最为严峻的一段时…

zynq7000 neon 裸机编译

最近想用zynq7000跑下neon&#xff0c;所以就开始折腾。 因为ne10不能用在裸机上&#xff0c;所以盯上了cmsis_dsp。因为这个库可以在cortex-a和cortex-m上面跑&#xff0c;而zynq7000用的是cortex-a9。应该是可以跑的。在这里特别感谢大佬的文章&#xff0c;少走不少弯路。 …

Cinema 4D 2024 for mac/Win:开启三维动画与建模新纪元

在数字化时代&#xff0c;三维动画与建模已成为影视、游戏、广告等多个领域不可或缺的创作工具。而Cinema 4D&#xff0c;作为这一领域的佼佼者&#xff0c;始终以其卓越的性能和创新的功能引领着行业的发展。如今&#xff0c;Cinema 4D 2024的发布&#xff0c;更是为我们带来了…

键盘映射工具KeyTweak的使用,把F9和F10改为 Home、End

如果你的笔记本没有Home、End键 对于写文字和写代码影响还是比较大的 下面使用键盘映射工具KeyTweak 把F9和F10分别改为 Home、End 然后点击ok 电脑重启后 就生效了 很好用 完美解决 小尺寸笔记本 的按键少的烦恼 可以自己再琢磨琢磨 去映射 符合自己需求的按键 软件下载链接&…

【早鸟优惠|高录用|EI稳定检索】2024年虚拟现实、图像和信号处理国际学术会议(ICVISP 2024)诚邀投稿/参会!

【早鸟优惠|高录用|EI稳定检索】 2024年虚拟现实、图像和信号处理国际学术会议&#xff08;ICVISP 2024&#xff09;诚邀投稿/参会&#xff01; # 早鸟优惠 # 先投稿先送审 # #投稿免费参会、口头汇报及海报展示# 2024年虚拟现实、图像和信号处理国际学术会议&#xff08;I…

Golang案例开发之gopacket抓包入门(1)

文章目录 前言一、gopacket是什么&#xff1f;二、gopacket前提二、实践 枚举主机上网络设备的接口1、代码2、结果文档 总结 前言 说起网络抓包&#xff0c;我们一定听过大名鼎鼎的Tcpdump和WireShark。他们分别是Linux平台和Windows平台的抓包工具。 Wireshark抓包工具&…

杉德支付配合调查 - 数字藏品服务

最近&#xff0c;数字收藏品平台淘派发布了一则公告&#xff0c;宣布支付通道杉德已暂停接口服务&#xff0c;以配合调查。 近期发现多个异常账户&#xff0c;涉嫌盗取他人信息和银行卡&#xff0c;利用平台从事非法交易。淘派已第一时间报警&#xff0c;协助警方追回资金(回执…

idea maven 项目融合

背景 &#xff1a;项目A 和项目B 是两个独立的多模块项目&#xff0c;项目A 和项目B &#xff0c;均为独立的数据源 。其中项目B 有两个数据原。 需要将项目B 以多模块的方式融合进项目A。 解决版本。建立项目C&#xff0c;只含有pom的&#xff0c;空项目&#xff0c;项目A和项…