Lazy loaded image
毕设级项目:使用MQTT实现智能家居(三合一)b
Words 2996Read Time 8 min
2024-12-4
Created
May 15, 2022 05:55 AM
URL
Tags
notion image

参见资料

系统简介

MQTT 协议介绍
MQTT 数据包结构
MQTT 环境搭建
<iframe src="//player.bilibili.com/player.html?aid=755396508&bvid=BV1Pr4y1c788&cid=343527265&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

STM32+ESP8266 MQTT Client 开发

分层结构
notion image
UART Hardware layer (usart_write and ring_read_buffer)
 
AT command Function + Drive Abstruction layer(call usart_write and ring_read_buffer)

1. ESP8266 的 AT命令函数 STM32 MCU → USART3 →Send cmd to the ESP8266

2. USART驱动抽象层 ESP8266→ USART3 →

Use RT-thread for reference and Reconstruct AT command funciton

架构设计参考

注意点
  1. 通过中断读取和处理数据分开,通知方式。避免轮询读写的CPU负担
    1. 【STM32 定时器中断与串口接受中断相互影响?该怎么样解决】中提到中断时存入缓存,使用置标志位或发信号量方式通知主程序或任务进行数据接卸。防止中断处理函数占用时间过长,造成多硬件中断冲突。中断中更改标志位供主程序调用,标志位需要添加 volatile,防止编译器优化。
    2. 【借鉴 DMA 加回调函数高效接收串口数据】中使用 DMA 直接操作缓存,在串口空闲时唤起转存数据,回调函数方法实现数据的处理。
  1. 发送命令和接收命令返回,使用挂起和恢复方式实现传递机制
  1. 环形缓冲区的大小如何确认,以及缓冲区是否存在覆盖问题。缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量溢出的数据覆盖在合法数据上,理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间相匹配,这就为缓冲区溢出埋下隐患。
  1. 中断和通知线程能否使用消息队列方式
  1. 高效使用 CPU资源,不要死等(OLED、用户输入)

线程和函数设计

  1. Thread1 发送 AT Command 并悬挂等待
    1. send AT Command
    2. wait response semaphore ◀️
    3. 参考代码

      封装接口

      封装接口,独立于硬件平台和系统操作系统,便于移植。

      写ATSendCmd

      1. 多个任务 (不同客户端) 同时调用发送命令,需要做好防护,用锁
        1. TaskA → UART_AT_Send()
          TaskB → UART_AT_Send()
      1. 发送命令返回结果和解析线程共享全局变量 g_at_status。针对全局变量,封装简单的操作函数,提高操作易理解性。
      1. 添加发送示例,有助于理解和编程
      1. 关于程序效率,发送命令后等待返回信息,若死等,白白占用CPU资源,等待唤醒机制,等待解析好通知。返回的信息通过中断和解析程序等待和唤醒。通过这样的机制,实现资源的合理分配,避免无效的占用。
      1. 要有合理的超时退出机制,防止功能异常时,程序选入卡滞
  1. Thread2 轮询解析响应数据
    1. Read_UART
      1. wait task notice from USART3_IRQHandle (sleep-arousal mechanism) 🔙
      2. read ringbuffer data received from USART3_IRQHandle and save them up
    2. sparse
      1. regular sparse rc until “\r\n” and deal with three kinds of status
      2. sparse network data formatted with “+IPD,n:XXXX”
        1. put into DataBuf
        2. send network data received semaphore ➡️
      3. send rc semaphore ▶️
      参考代码

      ATRecvParser()

      1. 返回内容解析分类
        1. 回车换行 “\r\n”,判断结果,并保存数据
        2. 保留回车换行前的 内容
        3. 判断 +IPD 关键词前缀
      1. 将串口接收数据封装进入硬件抽象层
        1. notion image
      1. 如何获得多行数据,防止数据溢出
        1.  
       
  1. Thread3 等待网络数据
    1. wait network data received semaphore ⬅️
    2. post-process extracted topic messages
    3. 参考代码
  1. USART3_IRQHandle usart RXNE interrupt Response Handle
    1. save USART3.DR to ringbuffer
    2. send task notify 🔜c
    3. 参考代码
      中断中使用释放信号量需要使用带 ISR 后缀
       
  1. main
    1. 参考代码
 
 

publish to Ali

mqtt_aliyun
  1. 创建产品并填写产品信息
    1. 产品就是设备的集合,通常是一组具有相同功能定义的设备集合。
      1. 产品指同一个型号的产品,设备就是该型号下的某个设备。
      2. 产品指同一个多部件集合体,设备就是该集合体下的某个部件
  1. 添加设备并保存设备证书
    1. 设备|操作|查看 也可以查看设备信息
    2. notion image
  1. 自定义主题(Topic)
    1. 让设备能对这个主题进行订阅或者发布操作,回到“产品”选项,选择“Topic类列表”,定义“Topic类列表”,再填写“Topic类列表”的信息即可,注意选择设备的操作权限“发布和订阅”,这点很重要,如果没有权限,设备是无法对这个主题进行操作的,具体过程如图所示,至此,一个产品与设备就创建完成了。
  1. 测试连接(使用MQTTX软件)
    1. 查看设备信息,通过阿里云的在线签名工具https://jiejietop.gitee.io/aliyun/index.html ,生成密钥
    2. MQTTX中填写信息连接,各个参数组成可参考这里说明。
    3. 连接成功后,可以添加订阅的主题名字,向指定的主题发送内容。
    4. notion image
mqtt_baidu(未测试,链接介绍详细,百度智云每个月的前1000000条消息是免费的)
mqtt_onenet(未测试,链接介绍详细)
 
 
 
上一篇
Data Structure and Algorithm
下一篇
用面试拷问嵌入式技术栈

Comments
Loading...