写点什么

基于 STM32+ 华为云 IOT 设计的酒驾监控系统

作者:DS小龙哥
  • 2022 年 7 月 04 日
  • 本文字数:6093 字

    阅读完需:约 20 分钟

1. 前言

随着人们生活水平的提高,为了减少和杜绝车的现象越来越多,所引发的交通事故也引起了人们的重视,为了减少和杜绝酒后驾车导致事故发生,当前设计了一种安装在驾驶室内,能根据具体功能进行鉴别酒精浓度的系统,当识别到酒驾之后会发出警报,并发送短信给指定紧急联系人,通知家人通知酒驾,一起监督行车安全。并将 GPS 数据上传到华为云物联网平台,调用地图模块显示具体位置,主控芯片采用 STM32 单片机,GSM 模块采用 IM800C。系统还带了一块 LCD 显示屏,可以实时显示检测的酒精含量,酒精超标后,本地蜂鸣器也会发出警报,提醒驾驶员。


测量酒驾的标准是:

(1)饮酒驾车是指车辆驾驶人员血液中的酒精含量大于或者等于 20mg/100ml,小于 80mg/100ml 的驾驶行为。

(2)醉酒驾车是指车辆驾驶人员血液中的酒精含量大于或者等于 80mg/100ml 的驾驶行为。


需要使用的硬件如下:


(1)STM32 系统板


(2)酒精检测传感器


(3)LCD 显示屏


(4)供电模块


(5)SIM800C 模块


(6)蜂鸣器模块


(7)GPS 模块--采用 SIM800C 内部的 GPS 功能获取 GPS 数据。





为了测试,搞了几口二锅头。



上位机采用 QT 开发,调用华为云的应用侧接口获取设备上传的数据。再调用百度接口,获取 GPS 定位的位置。


2. 登录华为云创建云端设备

2.1 创建产品

华为运官网: https://www.huaweicloud.com/





在这里可以查看接入的协议的端口号和地址。




MQTT (1883)  a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com  
复制代码


我们设备接入的协议选择 MQTT,端口对应是 1883


接下来继续创建产品,点击产品页面,点击右上角创建产品:




2.2 创建设备




这是我的设备信息:


设备ID625cd29cecf9c41c38215ba5_1126626497
设备密钥1126626497 { "device_id": "625cd29cecf9c41c38215ba5_1126626497", "secret": "1126626497"}
复制代码

2.3 产品模型定义

这一步就是设置上报设备的属性,也就是设备的数据类型定义。





2.4 生成 MQTT 登录密匙

创建完产品、设备之后,接下来就需要知道如何通过 MQTT 协议登陆华为云服务器。


官方的详细介绍在这里: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112




MQTT 设备登陆密匙生成地址: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/



下面就得到了 MQTT 协议设备登录的参数。

2.5 使用 MQTT 客户端软件登录

所有的参数已经得到,接下来采用 MQTT 客户端登录华为云进行测试。


华为云物联网平台的域名是: a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com


华为云物联网平台的 IP 地址是: 121.36.42.100


在软件里参数填充正确之后,就看到设备已经连接成功了。


接下来打开设备页面,可以看到设备已经在线了。

2.6 上报数据

官方文档: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112


在这个文档里介绍了 MQTT 上报数据的格式。




总结的格式:


//订阅主题: 平台下发消息给设备$oc/devices/625cd29cecf9c41c38215ba5_1126626497/sys/messages/down
//设备上报数据$oc/devices/625cd29cecf9c41c38215ba5_1126626497/sys/properties/report
//上报的属性消息 (一次可以上报多个属性,在json里增加就行了){"services": [{"service_id": "MQ3","properties":{"MQ3":50}}]}
复制代码


到此,设备数据已经上报成功,如果需要增加更多的属性,按照流程继续增加即可。

3. STM32 代码实现

酒精浓度传感器的预热时间要 20 秒~1 分钟左右,这段时间之后采集的数据才会稳定。预热模块会发热,烫手,这个是正常现象。

3.1 系统原理图


3.2 程序下载

通过 USB 进行程序下载: 下载软件在软件包目录下。


点击开始编程之后,点击板子上的复位键即可下载程序,如果失败,重试几次即可。正常的效果如下。



正常程序运行之后,打开串口调试助手看到的初始化信息如下:


3.3 字体取模

3.4 main.c 代码

keil 工程可以在这里 get: https://download.csdn.net/download/xiaolong1126626497/81993720


#include "stm32f10x.h"#include "led.h"#include "delay.h"#include "key.h"#include "usart.h"#include <string.h>#include "timer.h"#include "oled.h"#include "adc.h"#include <string.h>#include <stdlib.h>#include "font.h"#include "sim800c.h"#include "mqtt.h"
/*硬件连接方式:1. TFT 1.44 寸彩屏接线GND 电源地VCC 接5V或3.3v电源SCL 接PC8(SCL)SDA 接PC9(SDA)RST 接PC10DC 接PB7CS 接PB8BL 接PB11
2. 蜂鸣器VCC--->3.3VDAT--->PA6GND--->GND
3. 酒精检测传感器MQ3VCC--->3.3VGND--->GNDDAT--->PA1
4. 板载LED灯接线LED1---PA8LED2---PD2
5. 板载按键接线K0---PA0 K1---PC5 K2---PA15
6. SIM800C--GSM模块GND----GNDVCC--->3.3VPA2----SIM800C_RXDPA3----SIM800C_TXD*/
//华为物联网服务器的设备信息#define MQTT_ClientID "62381267575fb713ee164ad2_xl_1_0_0_2022032106"#define MQTT_UserName "62381267575fb713ee164ad2_xl_1"#define MQTT_PassWord "124344feff3e3d96ff6af13cf36af36766619ff1eeee40e99cbae9b7b9739fe4"
//订阅与发布的主题#define SET_TOPIC "$oc/devices/62381267575fb713ee164ad2_xl_1/sys/messages/down" //订阅#define POST_TOPIC "$oc/devices/62381267575fb713ee164ad2_xl_1/sys/properties/report" //发布//设置连接的路由器信息#define CONNECT_WIFI "Xiaomi_meizi6" //将要连接的路由器名称 --不要出现中文、空格等特殊字符#define CONNECT_PASS "12170307yu" //将要连接的路由器密码
#define CONNECT_SERVER_IP "a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com" //服务器IP地址#define CONNECT_SERVER_PORT 1883 //服务器端口
//JTAG模式设置,用于设置JTAG的模式//mode:jtag,swd模式设置;00,全使能;01,使能SWD;10,全关闭; #define JTAG_SWD_DISABLE 0X02#define SWD_ENABLE 0X01#define JTAG_SWD_ENABLE 0X00 void JTAG_Set(u8 mode){ u32 temp; temp=mode; temp<<=25; RCC->APB2ENR|=1<<0; //开启辅助时钟 AFIO->MAPR&=0XF8FFFFFF; //清除MAPR的[26:24] AFIO->MAPR|=temp; //设置jtag模式}

u16 MQ3_data=0; //酒精浓度float MQ3_data_float=0; //mg/l
char data_buff[100];//酒精超标提示u8 sim800c_buff[100]="Drunk driving reminder";
int main(){ u8 state=0; u8 key=0; u32 time_cnt=0; JTAG_Set(JTAG_SWD_DISABLE); //释放PA15 LED_Init(); //LED灯初始化 BEEP_Init(); //蜂鸣器初始化 KEY_Init(); //按键初始化 USART1_Init(115200); //串口1初始化-打印调试信息 Lcd_Init(); //LCD初始化 Lcd_Clear(0); //清屏为黑色 LCD_LED_SET; //通过IO控制背光亮 AdcInit(); //ADC初始化--检测酒精传感器的值 TIMER2_Init(72,20000);//辅助串口2接收,超时时间为20ms USART2_Init(115200); //可能的波特率(测试): 57600 、9600、115200 USART3_Init(115200);//串口-WIFI TIMER3_Init(72,20000); //超时时间20ms //预热视频 LCD_ShowChineseFont(0,16*3,16,HZ_FONT_16[20],RED,0); LCD_ShowChineseFont(16,16*3,16,HZ_FONT_16[21],RED,0); LCD_ShowChineseFont(16*2,16*3,16,HZ_FONT_16[22],RED,0); LCD_ShowChineseFont(16*3,16*3,16,HZ_FONT_16[23],RED,0); LCD_ShowChineseFont(16*4,16*3,16,HZ_FONT_16[24],RED,0); LCD_ShowChineseFont(16*5,16*3,16,HZ_FONT_16[25],RED,0); LCD_ShowChineseFont(16*6,16*3,16,HZ_FONT_16[26],RED,0); LCD_ShowChineseFont(16*7,16*3,16,HZ_FONT_16[27],RED,0); //delay_ms(30000); //初始化时间30秒 delay_ms(5000); //初始化时间5秒 Lcd_Clear(0); //清屏为黑色 //采集数据的真实数据 LCD_ShowChineseFont(0,16*2,16,HZ_FONT_16[0],RED,0); LCD_ShowChineseFont(16,16*2,16,HZ_FONT_16[1],RED,0); LCD_ShowChineseFont(16*2,16*2,16,HZ_FONT_16[2],RED,0); LCD_ShowChineseFont(16*3,16*2,16,HZ_FONT_16[3],RED,0); //酒精含量计算结果 LCD_ShowChineseFont(0,16*3,16,HZ_FONT_16[4],RED,0); LCD_ShowChineseFont(16,16*3,16,HZ_FONT_16[5],RED,0); LCD_ShowChineseFont(16*2,16*3,16,HZ_FONT_16[6],RED,0); LCD_ShowChineseFont(16*3,16*3,16,HZ_FONT_16[7],RED,0);
//酒精超标显示 Gui_DrawFont_GBK16(0,16*4,RED,0,(u8*)" "); LCD_ShowChineseFont(0,16*4,16,HZ_FONT_16[16],RED,0); LCD_ShowChineseFont(16,16*4,16,HZ_FONT_16[17],RED,0); LCD_ShowChineseFont(16*2,16*4,16,HZ_FONT_16[18],RED,0); LCD_ShowChineseFont(16*3,16*4,16,HZ_FONT_16[19],RED,0);
//初始化SIM800C state=SIM800C_InitCheck(); printf("SIM800C初始化状态:%d\r\n",state); DelayMs(1000); //设置文本模式 state=SIM800C_SetNoteTextMode(); printf("设置文本模式状态:%d\r\n",state); DelayMs(1000); // printf("正在初始化WIFI请稍等.\r\n"); for(i=0;i<5;i++) { if(ESP8266_Init()==0) { esp8266_state=1; break; } else { esp8266_state=0; printf("ESP8266硬件检测错误.\n"); } } if(esp8266_state) { printf("准备连接服务器....\r\n"); //非加密端口 printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode(CONNECT_WIFI,CONNECT_PASS,CONNECT_SERVER_IP,CONNECT_SERVER_PORT,1)); //2. MQTT协议初始化 MQTT_Init();
//3. 连接服务器 for(i=0;i<5;i++) { if(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord)==0) { esp8266_state=1; break; } esp8266_state=0; printf("服务器连接失败,正在重试...\n"); delay_ms(500); } printf("服务器连接成功.\n");
//3. 订阅主题 if(MQTT_SubscribeTopic(SET_TOPIC,0,1)) { printf("主题订阅失败.\n"); } else { printf("主题订阅成功.\n"); } } while(1) { key=KEY_Scan(); if(key) { printf("key=%d\r\n",key); } //控制LED灯 if(key==2) { LED2=!LED2; } //手动控制蜂鸣器测试 //手动发送短信测试 if(key==1) { BEEP=1; delay_ms(100); BEEP=0;
sprintf((char*)sim800c_buff,"Drunk driving reminder:%d",MQ3_data); //发送短信 if(SIM800C_SendNote((u8*)"13800138000",sim800c_buff,strlen((char*)sim800c_buff))==0) printf("短信发送成功\r\n"); else printf("短信发送失败\r\n"); } //轮询时间到达 if(time_cnt>300) { time_cnt=0; LED1=!LED1; //获取空气质量 MQ3_data=GetAdcCHxDATA(1); printf("采集MQ3数据:%d\r\n",MQ3_data); //上报数据 sprintf(data_buff,"{\"services\": [{\"service_id\":\"STM32\",\"properties\":{\"MQ3\":%d}]}", MQ3_data); MQTT_PublishData(POST_TOPIC,data_buff,0); //上报数据 sprintf(data_buff,"{\"services\": [{\"service_id\":\"STM32\",\"properties\":{\"MQ3\":%d}]}", MQ3_data); MQTT_PublishData(POST_TOPIC,data_buff,0); //LCD屏实时显示酒精浓度 //采集数据 sprintf(data_buff,"%d",MQ3_data); Gui_DrawFont_GBK16(72,16*2,RED,0,(u8*)" "); Gui_DrawFont_GBK16(72,16*2,RED,0,(u8*)data_buff); //酒精含量 //MQ3_data_float=((float)MQ3_data*(5.0/4096))*0.36-1.08; MQ3_data_float=((float)MQ3_data*(5.0/4096))*0.36; sprintf(data_buff,"%0.2f mg/L",MQ3_data_float); printf("计算酒精浓度:%s\r\n",data_buff); Gui_DrawFont_GBK16(72,16*3,RED,0,(u8*)" "); Gui_DrawFont_GBK16(72,16*3,RED,0,(u8*)data_buff); //判断酒精浓度是否超标,设置阀值 if(MQ3_data>2000) { sprintf((char*)sim800c_buff," :%d",MQ3_data); //发送短信 if(SIM800C_SendNote((u8*)"18171571217",sim800c_buff,strlen((char*)sim800c_buff))==0) printf("短信发送成功\r\n"); else printf("短信发送失败\r\n"); } //采集的值越小,表明酒精浓度越高。反之越大。 //根据阀值显示不同的文字提示 if(MQ3_data>2000) { //你已酒驾 Gui_DrawFont_GBK16(0,16*4,RED,0,(u8*)" "); LCD_ShowChineseFont(0,16*4,16,HZ_FONT_16[8],RED,0); LCD_ShowChineseFont(16,16*4,16,HZ_FONT_16[9],RED,0); LCD_ShowChineseFont(16*2,16*4,16,HZ_FONT_16[10],RED,0); LCD_ShowChineseFont(16*3,16*4,16,HZ_FONT_16[11],RED,0); } //正常稳定范围采集的值是500左右 else { //安全范围 Gui_DrawFont_GBK16(0,16*4,RED,0,(u8*)" "); LCD_ShowChineseFont(0,16*4,16,HZ_FONT_16[16],RED,0); LCD_ShowChineseFont(16,16*4,16,HZ_FONT_16[17],RED,0); LCD_ShowChineseFont(16*2,16*4,16,HZ_FONT_16[18],RED,0); LCD_ShowChineseFont(16*3,16*4,16,HZ_FONT_16[19],RED,0); } } DelayMs(10); time_cnt++; }}
复制代码


发布于: 刚刚阅读数: 2
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022.01.06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
基于STM32+华为云IOT设计的酒驾监控系统_7月月更_DS小龙哥_InfoQ写作社区