求一种基于RT-Thread的无接触式温湿度检测器设计方案

测量仪表

1490人已加入

描述

技术背景

在日常生活中,我们常见的电子测温器有较大的弊端,首先大部分电子测温计都无法自动保存储存数据,无法得知过去几天的温度与湿度。

同时常见的电子测温计会始终处于工作状态,LCD始终亮屏功耗较高。我们组设计的无接触式自动测温器可以很好的解决以上问题。同时在以低功耗消耗的同时,仍然以较高精度地对温度和湿度完成测量。

除此之外,我们设计的电子测温器仍然具有超过温度阈值自动报警引起注意、获取实时天气系统API等功能,实现了更多的功能完善。

技术目标

我们组设计的目标是自动化零接触式温湿度传感器,它会始终测量空气中的温度和湿度,同时将其数据上传至OneNET云平台并进行储存,同时会以折线图等形式数据化展现,便于处理。

同时他具有自动检测空气温度,若温度超过设定阈值便会报警的功能。同时他会自动检测和人们的距离,若没有人靠近,LCD会处于息屏状态减少消耗,只是在后台记录数据。若人们靠近,LCD会展示测量的温度和湿度,便于观察。

我们也获得了天气API,得到广州市的实时天气信息,可以将室外的温湿度与室内的温湿度进行比较。

AP3216接近传感器测接近值,AHT20温湿度线程将温度与湿度数据传给240x240并行LCD线程.

同时传给OneNET 云平台接入线程,然后将温度数据传给蜂鸣器线程。接近传感器线程返回值传递给240x240 并行LCD线程。

RT-Thread

LCD和配置显示:

如下图所示,星火1号开发板中装载有240*240的LCD显示屏。显示屏的驱动芯片是ST7789 v3,通信接口8080并口。通过 fsms 模拟出驱动时序和单片机进行通讯。

在main函数里,通过调用已经封装哈的LCD API函数,进行清屏操作。通过将背景刷为白色和黑色,进行屏幕的亮熄屏操作,同时在LCD上显示温湿度传感器所测量到的数值。

RT-Thread

配置ap3216c进行距离检测

RT-Thread

单片机通过I2C scl 、 I2C sda 对ap3216c 发送命令、读取数据等。

RT-Thread

我们先初始传感器ap3216c,传入参数i2c1为该传感器挂载的i2c总线的名称;然后将返回设备对象分别传入获取的ps函数,获得测量的ps值。通过最后串口返回的ps值大小代表是否有人靠近,如果靠近便会亮屏显示数据,未靠近便会息屏节省功耗。

收集数据并可视化

RT-Thread

连接网络

先通过rw007软件包使用 SPI 与主机通信,在终端输入wifi join的指令,将星火一号开发板接入网络。

获取温度湿度数据

将aht10采集到的温湿度数据信息同步。

将数据上传至云平台

OneNET平台将会收录数据并形成折线图,以便用户看到温度湿度的变化趋势。

RT-Thread

将数据直观展示

为了更方便的让用户查询温湿度信息,将数据可视化的展示在页面上,并且实时更新。这样用户就可以远程查询温湿度。

查询实时天气

从网页获取API密匙,并生成API接口地址。

连网后,通过软件代码用API获取实时天气数据。

RT-Thread

设计心得

我们通过这次实训学习到了很多知识:

首先是在前面5天,我们了解了嵌入式操作系统的应用与发展,学习了rt-thread的基本知识,初步明白了线程的运行原理和通过线程来控制系统的运行。

因为是第一次接触这些知识,我们遇到了很多的困难,但因为有乐于帮助的老师和同学,困难都被一一解决。

同时我们还明白了借助已有的软件包和代码资源来实现功能的重要性,毕竟在短时间内想自己写出强大而复杂的程序对于我们初学者而言是极其困难的。

除此之外,体会最深的就是不断练习才是掌握这门技术最有效的方法,即使课上听懂了的内容也要课后自己练习,只有当工程运行成功的那一刻,才算是真正的了解。

以下是我们设计的代码:

#include
#include
#include
#include "aht10.h"
#include "ap3216c.h"
#include
#include
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include
/* 配置 KEY 输入引脚 /
#define PIN_KEY1 GET_PIN(C, 1) // PC1: KEY1 --> KEY
#define PIN_WK_UP GET_PIN(C, 5) // PC5: WK_UP --> KEY
/
配置蜂鸣器引脚 /
#define PIN_BEEP GET_PIN(B, 0) // PA1: BEEP --> BEEP (PB1)
/
中断回调 */
void irq_callback(void args)
{
rt_uint32_t sign = (rt_uint32_t) args;
switch (sign)
{
case PIN_WK_UP :
rt_pin_write(PIN_BEEP,PIN_HIGH);
LOG_D("WK_UP interrupt. beep on.");
break;
case PIN_KEY1 :
rt_pin_write(PIN_BEEP,PIN_LOW);
LOG_D("KEY1 interrupt. beep off.");
break;
default:
LOG_E("error sign= %d !", sign);
break;
}
}
int main(void)
{
/
设置按键引脚为输入模式 /
rt_pin_mode(PIN_KEY1, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(PIN_WK_UP, PIN_MODE_INPUT_PULLUP);
/
设置蜂鸣器引脚为输出模式 /
rt_pin_mode(PIN_BEEP, PIN_MODE_OUTPUT);
/
设置按键中断模式与中断回调函数 */
rt_pin_attach_irq(PIN_KEY1, PIN_IRQ_MODE_FALLING, irq_callback, (void *) PIN_KEY1);
rt_pin_attach_irq(PIN_WK_UP, PIN_IRQ_MODE_FALLING, irq_callback, (void ) PIN_WK_UP);
/
使能中断 /
rt_pin_irq_enable(PIN_KEY1, PIN_IRQ_ENABLE);
rt_pin_irq_enable(PIN_WK_UP, PIN_IRQ_ENABLE);
float humidity, temperature;
aht10_device_t dev;
/
总线名称 */
const char *i2c_bus_name = "i2c3";
int count = 0;
ap3216c_device_t dev1;
const char i2c_bus_name1 = "i2c2";
/
等待传感器正常工作 /
rt_thread_mdelay(2000);
/
初始化 aht10 /
dev = aht10_init(i2c_bus_name);
if (dev == RT_NULL)
{
LOG_E(" The sensor initializes failure");
return 0;
}
/
初始化 ap3216c /
dev1 = ap3216c_init(i2c_bus_name1);
if (dev1 == RT_NULL)
{
LOG_E("The sensor initializes failure.");
return 0;
}
while (count++ < 100)
{
rt_uint16_t ps_data;
/
读接近感应值 /
ps_data = ap3216c_read_ps_data(dev1);
if (ps_data == 0)
{
LOG_D("object is not proximity of sensor.");
}
else
{
LOG_D("current ps data : %d.", ps_data);
}
/
读取湿度 /
humidity = aht10_read_humidity(dev);
/
读取温度 /
temperature = aht10_read_temperature(dev);
rt_thread_mdelay(1000);
if(temperature>35)
{
rt_pin_write(PIN_BEEP, PIN_HIGH);
}
if(ps_data>=10)
{
lcd_clear(WHITE);
lcd_show_image(0, 0, 240, 69, image_rttlogo);
/
set the background color and foreground color /
lcd_set_color(WHITE, BLACK);
/
show some string on lcd /
lcd_show_string(10, 69, 24, "Temperature:");
lcd_show_string(10, 69+24, 24, "Humidity:");
lcd_show_num(170,69,temperature,4,24);
lcd_show_num(170,69+24,humidity,7,24);
/
draw a line on lcd /
lcd_draw_line(0, 69 + 16 + 24 + 32, 240, 69 + 16 + 24 + 32);
/
draw a concentric circles */
lcd_draw_point(120, 194);
for (int i = 0; i < 46; i += 4)
{
lcd_draw_circle(120, 194, i);
}
}
else
lcd_clear(BLACK);
}
return 0;
}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分