IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 5.20 综合案例2.0-甲醛浓度检测系统 -> 正文阅读

[嵌入式]5.20 综合案例2.0-甲醛浓度检测系统

简介

甲醛是一种有特殊刺激气味的气体,对人的眼睛有强烈的刺激作用。若空气中甲醛浓度过高,比如新装修的房子、新买的汽车等,可引起中毒反应,严重的可致癌。家去拿时空气中的杀手之一,需要时刻提防。本案例的核心在于准确测量家庭中的甲醛浓度。

电化学甲醛模组

在这里插入图片描述

产品型号CJSH20-CH2O
检测气体甲醛
干扰气体酒精,一氧化碳等气体
输出数据UART 输出(3.3V 电平)
工作电压3.7V~5.5V
预热时间≤3 分钟
响应时间≤60 秒
恢复时间≤60 秒
量程0~5ppm
分辨率≤0.010 mg/m3
工作温度-20℃~50℃
工作湿度15%RH-90%RH(无凝结)
存储温度0~25℃
使用寿命2 年(空气中 0℃~35℃)
模组尺寸长17.7mm×宽17.8mm

1、管脚定义
在这里插入图片描述
2、通讯协议

波特率9600
数据位8 位
停止位1 位
校验位

3、通讯命令
通信分为主动上传式和问答式,出厂默认主动上传,每间隔1S发送一次浓度值。 如果用户切换到问答模式下,需要重新切换为主动上传时,发送如下命令行格式即可:
在这里插入图片描述
数据显示格式如下:
在这里插入图片描述
气 体 浓 度 值 (PPB)=( 气 体 浓 度 高 位 *256+ 气 体 浓 度 低 位 ). 当转换为 PPM 时: PPM= PPB/1000,1PPM甲醛相当于1.34mg/m3. 1mg/m3甲醛相当于0.746PPM.

准备

本案例需要的硬件

器材数量
HaaS506开发板1
电化学甲醛模组1
SIM卡1
杜邦线若干

硬件连接图

  • 使用TTL口下载完成后,用TTL口连接甲醛传感器进行数据读取。

在这里插入图片描述

代码流程

1、连接阿里云平台。
2、上传云端报警状态,重复读取传感器数据,并上传云端。

1、物联网平台开发

第一次使用物联网平台的读者,需要开通实例后使用物联网平台功能。也可以使用免费的公共实例进行开发,在阿里云物联网平台中,左上角选择‘华东2-上海’,点击‘公共实例’,即可开通。

1、平台产品创建可参考haas506 2.0开发教程-aliyunIoT
2、创建产品属性(添加物模型)

  • 选择产品功能定义编辑草稿
    在这里插入图片描述

  • 添加自定义功能

  • 添加标识符数据类型(标识符要与代码一致)

  • 点击发布上线
    在这里插入图片描述
    在这里插入图片描述

  • 点击确定
    在这里插入图片描述

2、设备端开发

  • 第一次使用开发板的读者可以按照haas5062.0开发教程-导学篇搭建开发环境。
  • 搭建完后复制以下代码到Visual Studio Code,复制产品证书到代码相应位置。
    在这里插入图片描述
  • main.py
# coding=utf-8
import network
import ujson
import utime as time
import modem
from  aliyunIoT import Device
import kv
from driver import UART

#当iot设备连接到物联网平台的时候触发'connect' 事件
def on_connect(data):
    global module_name,default_ver,productKey,deviceName,deviceSecret,on_trigger,on_download,on_verify,on_upgrade
    print('***** connect lp succeed****')
    data_handle = {}
    data_handle['device_handle'] = device.getDeviceHandle()


#当连接断开时,触发'disconnect'事件
def on_disconnect():
    print('linkkit is disconnected')


#当iot云端下发属性设置时,触发'props'事件
def on_props(request):
    print('clound req data is {}'.format(request))


#当iot云端调用设备service时,触发'service'事件
def on_service(id,request):
    print('clound req id  is {} , req is {}'.format(id,request))
#当设备跟iot平台通信过程中遇到错误时,触发'error'事件
def on_error(err):
    print('err msg is {} '.format(err))

#网络连接的回调函数
def on_4g_cb(args):
     global g_connect_status
     pdp = args[0]
     netwk_sta = args[1]
     if netwk_sta == 1:
         g_connect_status = True
     else:
         g_connect_status = False

#网络连接
def connect_network():
     global net,on_4g_cb,g_connect_status
     #NetWorkClient该类是一个单例类,实现网络管理相关的功能,包括初始化,联网,状态信息等.
     net = network.NetWorkClient()
     g_register_network = False
     if net._stagecode is not None and net._stagecode == 3 and net._subcode == 1:
         g_register_network = True
     else:
         g_register_network = False
     if g_register_network:
    #注册网络连接的回调函数on(self,id,func);  1代表连接,func 回调函数  ;return 0 成功
         net.on(1,on_4g_cb)    
         net.connect(None)
     else:
         print('网络注册失败')
     while True:
         if g_connect_status:
             print('网络连接成功')
             break
         time.sleep_ms(20)

#动态注册回调函数
def on_dynreg_cb(data):
     global deviceSecret,device_dyn_resigter_succed
     deviceSecret = data
     device_dyn_resigter_succed = True


 # 连接物联网平台
def dyn_register_device(productKey,productSecret,deviceName):
    global on_dynreg_cb,device,deviceSecret,device_dyn_resigter_succed
    key = '_amp_customer_devicesecret'
    deviceSecretdict = kv.get(key)
    print("deviceSecretdict:",deviceSecretdict)
    if isinstance(deviceSecretdict,str):    
        deviceSecret = deviceSecretdict 

    if deviceSecretdict is None or deviceSecret is None:
        key_info = {
            'productKey': productKey  ,
            'productSecret': productSecret ,
            'deviceName': deviceName
            }
        # 动态注册一个设备,获取设备的deviceSecret
        #下面的if防止多次注册,当前若是注册过一次了,重启设备再次注册就会卡住,
        if not device_dyn_resigter_succed:
            device.register(key_info,on_dynreg_cb)   

PPM_data = {}
def upload_PPM():
    global PPM_data,PPM
    PPM_data["hcho"]= PPM
    PPM_data_str=ujson.dumps(PPM_data)
    data={
        'params':PPM_data_str
        }      
    device.postProps(data)



if __name__ == '__main__':
    ICCID=None
    g_connect_status = False
    net = None
    device = None
    deviceSecret = None
    deviceName = None
    productKey = "a1A9j0EmrQr"
    productSecret = "21ATZN5PR2iuv08w"
    device_dyn_resigter_succed = False

    # 连接网络
    connect_network()
     # 获取设备的IMEI 作为deviceName 进行动态注册
    deviceName = modem.getDevImei()
    #获取设备的ICCID
    ICCID=modem.sim.getIccid()
    #初始化物联网平台Device类,获取device实例
    device = Device()
    if deviceName is not None and len(deviceName) > 0 :
     #动态注册一个设备
        dyn_register_device(productKey,productSecret,deviceName)
    else:
        print("获取设备IMEI失败,无法进行动态注册")
    while deviceSecret is None:
        time.sleep(0.2)
    print('动态注册成功:' + deviceSecret)

    key_info = {
        'region' : 'cn-shanghai' ,
        'productKey': productKey ,
        'deviceName': deviceName ,
        'deviceSecret': deviceSecret ,
        'keepaliveSec': 60,
        }
    #打印设备信息
    print(key_info)

    #device.ON_CONNECT 是事件,on_connect是事件处理函数/回调函数
    device.on(device.ON_CONNECT,on_connect)
    device.on(device.ON_DISCONNECT,on_disconnect)
    device.on(device.ON_PROPS,on_props)
    device.on(device.ON_SERVICE,on_service)
    device.on(device.ON_ERROR,on_error)
    device.connect(key_info)

    #主程序
    time.sleep(2)
    #UART初始化
    uart1=UART()
    uart1.open("serial1")
    readBuf=bytearray(9)
    writeBuf=bytearray(9)
    writeBuf = bytearray([0xFF,0x01,0x78,0x40,0x00,0x00,0x00,0x00,0x47])
    uart1.write(writeBuf)
    while True:
        #读取传感器数据并上传
        readSize=uart1.read(readBuf)
        print(readBuf)
        PPM = (int(readBuf[4])*256+int(readBuf[5]))/1000
        print(PPM) 
        upload_PPM()
        time.sleep(1)



  • 使用485串口读取log,配置 “replPort”: 2,串口TTL读取改为0 。
  • board.json
{
  "name": "haas506",
  "version": "2.0.0",
  "io": {
    "serial1": {
      "type": "UART",
      "port": 0,
      "dataWidth": 8,
      "baudRate": 9600,
      "stopBits": 1,
      "flowControl": "disable",
      "parity": "none"
    },
    "serial2": {
      "type": "UART",
      "port": 1,
      "dataWidth": 8,
      "baudRate": 9600,
      "stopBits": 1,
      "flowControl": "disable",
      "parity": "none",
      "timeout": 1000
    },
    "serial3": {
      "type": "UART",
      "port": 2,
      "dataWidth": 8,
      "baudRate": 115200,
      "stopBits": 1,
      "flowControl": "disable",
      "parity": "none",
      "timeout": 1000
    }
  },
  "debugLevel": "ERROR",
  "repl": "enable",
  "replPort": 2
}


调试

  • 调试串口使用485端口,打开设备管理器可以查看调试端口号。
    在这里插入图片描述
  • 串口调试工具使用putty
    在这里插入图片描述

调试结果

1、串口调试工具log,网络连接成功动态注册成功每秒打印读取的数字及PPM数值
在这里插入图片描述
2、云端有数据传入,打开实时刷新,显示数据会自动更新。
在这里插入图片描述
点击查看数据,可以看到每次上传的具体数值。
在这里插入图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:23:19  更:2022-06-01 15:24:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 16:02:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码