基于stm32 华为云iot设计的酒驾监控系统【玩转华为云】-4008云顶国际网站

ds小龙哥 发表于 2022/04/18 11:25:31 2022/04/18
【摘要】 随着人们生活水平的提高,为了减少和杜绝车的现象越来越多,所引发的交通事故也引起了人们的重视,为了减少和杜绝酒后驾车导致事故发生,当前设计了一种安装在驾驶室内,能根据具体功能进行鉴别酒精浓度的系统,当识别到酒驾之后会发出警报,并发送短信给指定紧急联系人,通知家人通知酒驾,一起监督行车安全。并将gps数据上传到华为云物联网平台,调用地图模块显示具体位置,主控芯片采用stm32单片机。

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 创建产品

华为运4008云顶国际网站官网:

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

mqtt (1883)	a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com	

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

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

2.2 创建设备

这是我的设备信息:

设备id
625cd29cecf9c41c38215ba5_1126626497
设备密钥
1126626497
    
{
    "device_id": "625cd29cecf9c41c38215ba5_1126626497",
    "secret": "1126626497"
}

2.3 产品模型定义

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

2.4 生成mqtt登录密匙

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

官方的详细介绍在这里:

mqtt设备登陆密匙生成地址:

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

2.5 使用mqtt客户端软件登录

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

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

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

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

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

2.6 上报数据

官方文档:

在这个文档里介绍了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:

#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   接pc10
dc    接pb7
cs    接pb8
bl	  接pb11
2. 蜂鸣器
vcc--->3.3v
dat--->pa6
gnd--->gnd
3. 酒精检测传感器mq3
vcc--->3.3v
gnd--->gnd
dat--->pa1
4. 板载led灯接线
led1---pa8
led2---pd2
5. 板载按键接线
k0---pa0 
k1---pc5 
k2---pa15
6. sim800c--gsm模块
gnd----gnd
vcc--->3.3v
pa2----sim800c_rxd
pa3----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;
	 }
}
【4008云顶国际集团的版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。