利用RT-Thread与MQTT实现智慧班车管理系统的设计

项目硬件开发总结
下面从开发者的角度对本项目进行总结:(因为不是写paper所以比较随意哈~)
项目采用的iot架构,底层是stm32l475vet6潘多拉开发板+rt-thread,对于rt-thread的资源使用情况在论文中也有提到,这里直接截个图:
rt-thread使用情况详情
内核层的信号量、邮箱、消息队列等机制是用于线程同步以及线程通信的,中断一开始是用于检测pin设备的irq,但是后来去掉了,原因是不好用,确实是用中断的时候自己懒得调试了,程序运行会出现很多问题,所以直接开了个线程,这个后面会讲到。
设备与驱动层中i/o设备模型是最基本的设备model,所以不再赘述。uart设备是值得一提的哈。因为这个项目需要用到三个串口,即串口1用于finsh组件调试,串口2用于nb-iot通信,串口3用于gps数据的urc解析,但是官方给的bsp中没有添加串口3设备,所以需要自己添加uart设备。
添加uart设备
在rt-thread文档中心已经给出了详细的添加步骤,所在路径如下:
首先,需要本地安装cubemx,然后打开裁剪过的bsp目录中的board文件夹
【关于bsp的裁剪工作可以通过env工具,使用scons—dist完成】
然后找到该文件夹
打开完成后如果cube版本与官方制作bsp使用的cube版本不同时会弹出如下提示框:
找到uart3选项,设置为异步模式
同时,需要注意的是usart3默认使用的端口,潘多拉开发板并没有引出,所以需要到引出的pb10和pb11单独设置端口的模式:
最后,需要打开board文件夹中的kconfig文件,添加uart3选项:【建议使用notepad打开,这样打开的文件格式对称,便于复制】
添加完成后,打开env工具输入menuconfig命令,依次进入hardware drivers config—->on-chip peripheral drivers—->enable uart就可以看到新添加的uart3选项:
选中后重新生成工程,打开后记得重新编译。这样,uart3设备驱动已经添加成功。
适配软件包
回顾一下本项目需要完成的功能,这里直接贴出了论文截图:(懒了~)
aht10软件包的使用
将aht10软件包添加后,只需要关心应用层的逻辑即可。
我的应用层线程初始化都是在main线程中完成的,有关于aht10数据采集线程的初始化如下:
线程入口函数如下:
static void aht10_thread_entry()
{
rt_device_t dev_temp = rt_null;
rt_device_t dev_humi = rt_null;
struct tmp_msg msg;
struct rt_sensor_data sensor_data;
rt_size_t res_temp,res_humi;
rt_err_t res;
res = rt_sem_take(send_aht_sem, rt_waiting_forever);
if(res != rt_eok)
{
rt_kprintf(getgps_thread take a nb semaphore, failed.n);
return;
}
dev_temp = rt_device_find(temp_aht);
dev_humi = rt_device_find(humi_aht);
if (dev_temp == rt_null)
{
rt_kprintf(can't find device:dev_tempn);
return;
}
if (rt_device_open(dev_temp, rt_device_flag_rdwr) != rt_eok)
{
rt_kprintf(open device dev_temp failed!n);
return;
}
if (dev_humi == rt_null)
{
rt_kprintf(can't find dev_humi devicen);
return;
}
if (rt_device_open(dev_humi, rt_device_flag_rdwr) != rt_eok)
{
rt_kprintf(open device dev_humi failed!n);
return;
}
while(1)
{
res_temp = rt_device_read(dev_temp, 0, &sensor_data, 1);
if (res_temp != 1)
{
rt_kprintf(read temp data failed!);
rt_device_close(dev_temp);
return;
}
else
{
// rt_kprintf(temp:%3dcn,abs(sensor_data.data.temp)/10);
msg.temp_value=(abs(sensor_data.data.temp)/10);
}
rt_thread_mdelay(10);
res_humi = rt_device_read(dev_humi, 0, &sensor_data, 1);
if (res_humi != 1)
{
rt_kprintf(read humi data failed!n);
rt_device_close(dev_humi);
return;
}
else
{
// rt_kprintf(hum:%2d%, timestamp:%5dn,abs(sensor_data.data.humi)/10);
msg.humi_value=abs(sensor_data.data.humi)/10;
}
rt_mq_send(tmp_msg_mq, &msg,sizeof(msg));
// rt_kprintf(======aht10-thread send a mq,msg.tem:%d,msg.hum:%d======rn,msg.temp_value,msg.humi_value);
rt_thread_mdelay(300);
}
}
在上述代码中首先是获取nb初始化完成后release的信号量;获取成功后,再获取注册到sensor框架中的温湿度传感器(注意:这里的温湿度传感器是分开的,可以通过list_device在finshi终端查看);然后是打开设备并读取温湿度信息;最后将采集到的数据以邮箱机制发送到nb发送线程。这是整个aht10软件包的添加和数据的读取工作(需要注意:aht10是通过i2c进行通信的,所以需要开启i2c设备框架)
lwgps软件包的使用
lwgps软件包是一个轻量级的gps的urc解析包,支持nema格式。在使用软件包的时候也遇到过不少的坑哈,但是庆幸的是都已经解决了
可以直接使用该作者提供的驱动框架。特别需要注意的是:这里有一个小坑,可能很多人会忽略,软件包已经使用了init_app_export(lwgps2rtt_init);添加了lwgps的初始化,因此不需要在应用层调用,如果调用会出现我之前出现的报错信息:
线程入口函数如下:
static void getgps_thread_entry()
{
lwgps_t gps_info;
struct gps_msg gpsmsg;
float lati , longi;
rt_err_t res;
// res = rt_sem_take(send_gps_sem, rt_waiting_forever);
// if(res != rt_eok)
// {
// rt_kprintf(getgps_thread take a nb semaphore, failed.n);
// return;
// }
while(1)
{
lwgps2rtt_get_gps_info(&gps_info);
gpsmsg.lati_value=(gps_info.latitude);
gpsmsg.longi_value=(gps_info.longitude);
gpsmsg.hour=(gps_info.hours);
// rt_kprintf(gps-data:hour-->%drn,gpsmsg.hour);
rt_mq_send(gps_msg_mq,&gpsmsg,sizeof(gpsmsg));
rt_thread_delay(500);
}
}
使用pin设备——mq2数据采集
关于mq2的数据读取,并没有使用到adc设备,因为我想缩短开发周期赶论文┭┮﹏┭┮。我选用的是mq2的do输出模式,通过调整电位器设置阈值,实现原理比较简单哈,不再赘述。同时,它的软件读取工作也比较简单。但是由于项目实时性要求,上行数据流是采用json封装的,方便小程序端解析,所以需要持续发送采集数据,因此无论是检测到可燃气体还是没有检测到都要发送消息队列。
详细代码如下:
static void test_thread_entry()
{
char tr_array[]=true;
char fa_array[]=false;
struct mq_msg mq2_msg;
while(1)
{
// rt_kprintf(testrn);
if(rt_pin_read(mq2_pin_num)==pin_low)
{
memcpy(mq2_msg.msg,tr_array,sizeof(tr_array));
rt_mq_send(mq2_msg_mq,&mq2_msg,sizeof(mq2_msg));
rt_pin_write(beep_pin_num, pin_high);
rt_thread_mdelay(500);
rt_pin_write(beep_pin_num, pin_low);
}
else{
memcpy(mq2_msg.msg,fa_array,sizeof(fa_array));
rt_mq_send(mq2_msg_mq,&mq2_msg,sizeof(mq2_msg));
}
rt_thread_mdelay(200);
}
}
使用pin设备——红外对射数据采集
红外模块采用的“消抖”操作,因为有可能车门位置经过的人会一直停留,所以按照按键消抖处理的,详细的流程不再说明,直接上代码了:
/* 红外检测线程入口函数*/
static void hw_thread_entry(void parameter)
{
static rt_uint8_t hw_up = 1; / 无人标志 /
/ 初始化红外对射模块 /
rt_pin_mode(pin_num_add, pin_mode_input);
rt_pin_mode(pin_num_sub, pin_mode_input);
rt_pin_mode(led0_pin, pin_mode_output);
tmp_msg_mb = rt_mb_create(temp_mb0, mb_len, rt_ipc_flag_fifo);
while (1)
{
/ 检测无人标志 /
if (hw_up && ((rt_pin_read(pin_num_add) == pin_low) ||
(rt_pin_read(pin_num_sub) == pin_low)))
{
rt_thread_mdelay(50); / 延时消抖*/
hw_up = 0;
if (rt_pin_read(pin_num_sub) == pin_low)
{
rt_kprintf(having person-sub!n);
rt_pin_write(led0_pin, pin_high);
if(people_num=30)
{
rt_kprintf(the number of people is full!n);
continue;
}
else{
people_num++;
rt_kprintf(the num of people is %drn,people_num);
// rt_mb_send(tmp_msg_mb,people_num);
}
}
}
else if((rt_pin_read(pin_num_add) == pin_high) &&
(rt_pin_read(pin_num_sub) == pin_high))
{
hw_up = 1; /*无人标志 */
// rt_mb_send(tmp_msg_mb,people_num);
}
rt_mb_send(tmp_msg_mb,people_num);
rt_thread_mdelay(100);
}
}
使用at设备——nb模块初始化与nb模块数据发送
首先需要在项目中添加at组件,同时添加m5311软件包,添加完成后,在应用层main线程中开启nb初始化以及nb订阅和发送线程(采用mqtt协议)
初始化线程入口函数如下:
//nb初始化线程:新建mqtt机制+连接mqtt服务器
static void nb_mqtt_thread_entery()
{
nb_client = at_client_get(uart2);
nb_resp = at_create_resp(1024, 0, rt_tick_from_millisecond(300));
if(at_obj_exec_cmd(nb_client,nb_resp,arv)!=rt_eok)
{
log_e(the mqtt haven't inited successrn);
}
else{
log_e(mqtt have inited successrn);
if(at_obj_exec_cmd(nb_client,nb_resp,at+mqttopen=1,1,0,0,0,'','')!=rt_eok)
{
log_e(the mqtt haven't inited successrn);
}
else{//真正完成了新建mqtt机制和连接服务器
log_e(the mqtt haven inited successrn);
rt_pin_write(beep_pin_num, pin_high);
rt_thread_mdelay(500);
rt_pin_write(beep_pin_num, pin_low);
rt_sem_release(nb_sem);//释放信号量
rt_sem_release(send_gps_sem);
rt_sem_release(send_aht_sem);
}
}
rt_thread_mdelay(1000);
}
订阅和发送线程入口函数如下:
static void nb_mqtt_send_thread_entery()
{
struct tmp_msg msg;
struct gps_msg gps;
struct mq_msg mq2msg;
static rt_err_t result;
int pep_num=0;
result = rt_sem_take(nb_sem, rt_waiting_forever);
if(result != rt_eok)
{
rt_kprintf(nb_mqtt_send_thread take a nb semaphore, failed.n);
return;
}else{
for(;;)
{
if(at_obj_exec_cmd(nb_client,nb_resp,at+mqttsub=pyr,1)==rt_eok)//订阅主题
{
rt_kprintf(the nb-iot have subscribed the pyr topicrn);
break;
}
}
while(1)
{
if((rt_mq_recv(gps_msg_mq,&gps,sizeof(gps),rt_waiting_forever)==rt_eok)&&
(rt_mq_recv(tmp_msg_mq, &msg, sizeof(msg), rt_waiting_forever)==rt_eok)&&
(rt_mq_recv(mq2_msg_mq, &mq2msg, sizeof(mq2msg), rt_waiting_forever)==rt_eok)&&
(rt_mb_recv(tmp_msg_mb,(int*)&pep_num,rt_waiting_forever)==rt_eok))
{
rt_kprintf(---------->nb send thread receive the data-hour:%d,tmp:%d,mq2:%s,pep_num:%drn,gps.hour,msg.temp_value,mq2msg.msg,pep_num);
if(at_obj_exec_cmd(nb_client,nb_resp,at+mqttpub=pyr,1,1,0,0,{temp:%d,hum:%d,lati:%f,longi:%f,mq2:%s,pep_num:%d},msg.temp_value,msg.humi_value,gps.lati_value,gps.longi_value,mq2msg.msg,pep_num)!=rt_eok)
{
log_e(send the message of the mqtt failedrn);
}
// if(at_obj_exec_cmd(nb_client,nb_resp,at+mqttpub=pyr,1,1,0,0,{latitude:37.3862770000,longitude:117.9898270000,temp:23,humi:60,person:15,smoke:false})!=rt_eok)
// {
// log_e(send the message of the mqtt failedrn);
// }
}
rt_thread_mdelay(500);
// rt_thread_mdelay(1000); 有延时,所以采用0.5s-debug测出来的
}
}
}
项目软件开发总结
项目的应用软件使用的是微信小程序,涉及到的内容包括:小程序适配mqtt客户端连接服务器以及订阅和发布消息、小程序云开发模式serverless、小程序使用map组件、小程序使用腾讯云sms服务(个人版)、小程序实现左滑删除样式等内容… …另外,mqtt服务器使用的是emq搭建的免费版mqtt服务器。
这是使用的mqtt地址,目前仍然可以使用:emq服务器ip地址 ,支持端口号18083、8083、8084、18084访问,同时提供匿名访问.

华为MateBook E明天正式开售
中医药信息化“十四五”规划发布,唐古以数字化赋能行业发展
AIMB-278第12/13代Intel Core处理器Mini-ITX主板高性能解决方案,助力提升计算性能
ROHM新推出了一款电池充电IC:BD99954GW/MWV
企业迁移到云计算的动机是什么?
利用RT-Thread与MQTT实现智慧班车管理系统的设计
ATP发布了一款适用于工业环境的M.2固态硬盘
智能技术不断进步,自动驾驶全面落地还需多久
什么是EMC?EMI产生三要素是哪些?
AVS,下一个WAPI?
加密货币相对传统法定货币具有哪些优势
全功能智能手表首选,览邦WACH MAX - A90智能手表体验
电机保护器的分类和功能
到2030年工作被AI机器人替代后 我们会变成什么样?
人脸识别考勤机安装注意事项
云计算体系结构概述!
freertos中文手册(概念_功能和特点_原理实现)
网友直呼美呆,三星S8视频曝光,占屏比直逼小米Mix
大功率白光LED的应用分析
好产品靠打磨,这些细节告诉你华为Mate9的工匠精神