关注+星标公众号,不错过精彩内容

作者 | MakingClub
微信公众号 | electronic造物实验室

阿里云物联网平台

新建设备

  1. 注册阿里云账号并搜索物联网服务。选择并进入物联网平台产品页。
    搜索物联网
  2. 点击管理控制台,进入物联网平台管理界面。进入物联网平台
  3. 选择公共实例(如果尚未开通,需要先进行开通,具体步骤不再赘述),然后点击进入。选择公共实例
  4. 创建一个新的产品。填写产品名称所属品类等必要信息,并完成产品创建步骤。创建产品
    在这里插入图片描述
  5. 在创建完成的产品页面上,添加设备。输入设备名称并确认。添加设备在这里插入图片描述
  6. 输入设备名称,输入完成后点击确认;
    在这里插入图片描述
    至此,阿里云物联网平台创建设备完成,接下来获取MQTT连接参数。

获取AT参数

创建设备成功后进入设备详情页,查看MQTT连接参数,并进行保存。MQTT连接参数
通过上述步骤,你可以获取到阿里云物联网平台上设备的MQTT连接参数,并进行保存。这些参数将用于在ESP-01S / ESP8266上配置AT指令,实现设备与物联网平台之间的通信。

AT指令介绍

AT命令,用来控制TE(TerminalEquipment)和MT(Mobile Terminal)之间交互的规则。AT指令可以参考乐鑫官方提供的AT 命令集

连接阿里云AT指令介绍

  1. AT+RST 复位ESP-01S / ESP8266模块;
  2. AT+CWMODE=3 设置ESP模块为Station+SoftAP模式;
  3. AT+CWJAP=“SSID”,“PWD” 设置ESP模块连接无线网络 *注意双引号为英文;
  4. AT+MQTTUSERCFG=0,1,“NULL”,“username”,“password”,0,0,“” 设置 MQTT 用户属性;
  5. AT+MQTTCLIENTID=0,“clientId” 设置MQTT 的clientId参数;
  6. AT+MQTTCONN=0,“host”,1883,1 连接 MQTT Broker;
  7. AT+MQTTCLEAN 断开MQTT连接。
    以上为连接阿里云MQTT服务器需要的配置命令,接下来在阿里云新建设备,获取AT指令需要填充的参数。

MQTT固件

ESP-01S 1M Flash固件下载1MB AT MQTT
ESP8266 4M Flash固件下载4MB AT MQTT

固件下载

硬件连接

USB转TTL推荐使用带有独立LDO的模块,因为ESP8266EX通讯时电流较大,如无独立LDO可能导致ESP8266EX掉电重启。
可以使用下图模块,带独立LDO,可以提供一定带负载能力;
请添加图片描述

下图模块不推荐使用,无独立LDO,3V3为CH340提供,带负载能力弱。
请添加图片描述
ESP-01烧录固件

VCC -----> TTL  3.3V 
GND -----> TTL GND
TXD -----> TTL RXD
RXD-----> TTL TXD
EN-------> TTL 3.3V 
RST ----> TTL RST
GPIO0 ---> GND
GPIO2 ---> 3.3V (不接也可以)

基本接法如下图所示:
ESP-01烧录固件接线
ESP-01S烧录固件

VCC -----> TTL  3.3V 
GND -----> TTL GND
TXD -----> TTL RXD
RXD-----> TTL TXD
RST ----> TTL RST
GPIO0 ---> GND

ESP-01S烧录固件

固件烧录

下载AT指令固件到本地后,需要使用乐鑫提供的flash_download_tool工具。下载后直接解压即用,运行烧录工具。乐鑫官网 - 支持 - 相关下载 - 工具-Flash 下载工具
Flash 下载工具
选择型号,选择ESP8266
在这里插入图片描述
打开烧录软件, 从"…“选择要烧录的bin文件: ESP8266-AT_MQTT-1M.bin;填写烧录地址"0x0000”SPI MODE选择 “DOUT”;FLASH SIZE选择 “8Mbit”;"DoNotChgBin"不变;“COM” 选择你USBtoTTL的COM口;波特率默认即可。
在这里插入图片描述上述配置完成后, 点击START开始烧录, 若一直停在等待上电同步可以就将RST连接GND再断开, 就可以开始下载了。

串口助手调试

在进行串口助手调试之前,需要进行正确的硬件连接。

硬件连接

对于ESP-01,需要使用两个上拉电阻将EN和RST引脚上拉到3.3V,如下图所示:
在这里插入图片描述
对于ESP-01S,只需要连接3.3V、RXD、TXD和GND即可。

测试指令

在串口软件中打开COM口,选择波特率115200,加回车换行;发送AT指令,并等待接收到回复的"OK"。
在这里插入图片描述
接下来将MQTT信息填充进AT命令中进行连接测试。

  1. AT+RST 复位ESP-01S / ESP8266模块;
  2. AT+CWMODE=3 设置ESP模块为Station+SoftAP模式;
  3. AT+CWJAP=“SSID”,“PWD” 设置ESP模块连接无线网络 *注意双引号为英文;
  4. AT+MQTTUSERCFG=0,1,“NULL”,“username”,“passwd”,0,0,“” 设置 MQTT 用户属性;
  5. AT+MQTTCLIENTID=0,“clientId” 设置MQTT 的clientId参数;
  6. AT+MQTTCONN=0,“host”,1883,1 连接 MQTT Broker;
  7. AT+MQTTCLEAN 断开MQTT连接。
    AT+MQTTUSERCFG中的username和passwd与下图对应填写,AT+MQTTCLIENTID中的clientId也与下图对应,AT+MQTTCONN的host与下图mqttHostUrl对应。
    需要注意AT+MQTTCLIENTID指令中的clientId中的逗号前需要加’ \ '符号进行转义,假设clientId为“a1Tt5hwk2af.Device1|securemode=2,signmethod=hmacsha256,timestamp=1685260171273|”,那么发送的AT指令应为AT+MQTTCLIENTID=0,“723712|securemode=2,signmethod=hmacsha256,timestamp=1685260171273|”
    在这里插入图片描述
    发送完以上指令后,在阿里云物联网平台中刷新设备网页,你将会看到设备已成功上线的信息。

[18:24:44.609]发→◇AT
□
[18:24:44.613]收←◆AT

OK

[18:30:14.787]发→◇ATE0
□
[18:30:14.791]收←◆ATE0

OK

[18:30:31.339]发→◇AT+CWMODE=3
□
[18:30:31.344]收←◆
OK

[18:31:21.198]发→◇AT+CWJAP="Xiaxxxx81","dsssxx1"
□
[18:31:22.397]收←◆WIFI CONNECTED

[18:31:23.908]收←◆WIFI GOT IP

OK

[19:24:10.517]发→◇AT+CIPSNTPCFG=1,8,"ntp1.aliyun.com"
□
[19:24:10.530]收←◆
OK

[19:24:53.745]发→◇AT+MQTTUSERCFG=0,1,"NULL","Devixx1&a1Ttxxxaf","05314xxxxxxxxxxxxxxxxxxxxxxc5de74",0,0,""
□
[19:24:53.755]收←◆
OK

[19:25:09.562]发→◇AT+MQTTCLIENTID=0,"a1xxxxf.Device1|securemode=2\,signmethod=hmacsha256\,timestamp=1685260171273|"
□
[19:25:09.571]收←◆
OK

[19:25:21.162]发→◇AT+MQTTCONN=0,"a1xxxxxaf.iot-as-mqtt.cn-shanghai.aliyuncs.com",1883,1
□
[19:25:21.347]收←◆+MQTTCONNECTED:0,1,"a1Tt5wtm2af.iot-as-mqtt.cn-shanghai.aliyuncs.com","1883","",1

OK

可以看到设备已成功上线。
在这里插入图片描述

AT_Command移植

AT_Command由魔罗大佬开发,是一款管理AT命令通信交互组件, 适用于Modem、WIFI模块、蓝牙等使用AT命令或者ASCII命令行通信的场景。本次AT连接使用AT_Command移植到STM32F103C8T6进行运行。AT_Command Gitee链接
本次的项目环境为HAL库+CubeMx进行配置开发。

  1. 首先需要定义适配器,完成驱动接口及缓冲区设置
    在wifi_uart.c文件中,进行了串口发送和接收回调的实现。

    /*
     * @brief	    向串口发送缓冲区内写入数据并启动发送
     * @param[in]   buf       -  数据缓存
     * @param[in]   len       -  数据长度
     * @return 	    实际写入长度(如果此时缓冲区满,则返回len)
     */
    unsigned int wifi_uart_write(const void *buf, unsigned int len)
    {   
        unsigned int ret;
        ret = ring_buf_put(&rbsend, (unsigned char *)buf, len);  
        HAL_UART_Transmit(&wifi_uart,(unsigned char *)buf,len,0xffff);  // wifi串口数据发送
        return ret; 
    }
    /*
     * @brief	    WIFI串口接收
     * @param[in]   none
     * @return 	    none
     */
    void WIFI_UART_RxCpltCallback(unsigned char *data, uint8_t len)
    {
    	ring_buf_put(&rbrecv, data, len);           /*将数据放入接收缓冲区*/  
    }
    

    串口数据接收使用串口2(TX为PA2, RX为PA3)的是DMA+空闲中断的方式进行接收,在stm32f1xx_it.c文件中:

    /**
      * @brief This function handles USART2 global interrupt.
      */
    void USART2_IRQHandler(void)
    {
      /* USER CODE BEGIN USART2_IRQn 0 */
    
      /* USER CODE END USART2_IRQn 0 */
      HAL_UART_IRQHandler(&huart2);
      /* USER CODE BEGIN USART2_IRQn 1 */
    	if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) != RESET)  // 空闲中断
    	{
    		__HAL_UART_CLEAR_IDLEFLAG(&huart2);  // 清除空闲中断标志位
    		HAL_UART_DMAStop(&huart2);  // 停止DMA接收
    		
    		if( wifiConnectFlag == 0)  // 未完成配置
    			WIFI_UART_RxCpltCallback(uart2_rx_buf, strlen(uart2_rx_buf));  // 数据处理函数
    		else  // 配置完成 等待设备连接
    			wifi_connnect_calback(uart2_rx_buf, strlen(uart2_rx_buf));
    		memset(uart2_rx_buf, 0, strlen(uart2_rx_buf));  // 清除数据
    		
    		HAL_UART_Receive_DMA(&huart2, uart2_rx_buf, buf_size);  // 重新打开DMA接收
    	}
      /* USER CODE END USART2_IRQn 1 */
    }
    
  2. 使用AT适配器创建AT通信对象,在wifi.c文件中:

    static at_obj_t at;static at_obj_t at;
    /* 
     * @brief    wifi初始化  配置8266
     */
    void wifi_init(void)
    {
    	static char wifi_msg[128] = {0};
    	// WIFI 串口初始化
        wifi_uart_init(115200);
        at_obj_init(&at, &at_adapter);
    	// 关闭回显
        at_send_singlline(&at, NULL, "ATE0");  	// OK
        // AT测试
        at_send_singlline(&at, NULL, "AT");  // OK  ERROR *
    	// 配置工作模式 AP模式
    	at_send_singlline(&at, NULL, "AT+CWMODE=3");  
    	// 创建路由器
    	sprintf(wifi_msg, "AT+CWJAP=\"%s\",\"%s\"", SSID, PWD);
    	at_send_singlline(&at, NULL, wifi_msg);  
    	// 设定域名
    	at_send_singlline(&at, NULL, "AT+CIPSNTPCFG=1,8,\"ntp1.aliyun.com\"");  
    	// 设定MQTT账号
    	at_send_singlline(&at, NULL, "AT+MQTTUSERCFG=0,1,\"NULL\",\"username\",\"passwd",0,0,\"\"");  
    	// 设定Clinent ID
    	at_send_singlline(&at, NULL, "AT+MQTTCLIENTID=0,\"clientid注意逗号需反义\"");  
    	// 链接MQTT
    	at_send_singlline(&at, connnect_calback, "AT+MQTTCONN=0,\"host\",1883,1");
    }; 
    
  3. 加入轮询任务,wifi.c中实现了wifi_task函数,并在初始化中进行循环调用,如下:

    wifi_init();
    do
    {
    	wifi_task();
    	HAL_Delay(10);
    }while(wifiConnectFlag == 0);
    

    wifiConnectFlag 标志位会在at_send_singlline(&at, connnect_calback, "AT+MQTTCONN=0,\"host\",1883,1");中的connnect_calback回调函数中进行判断。
    如上进行配置后可基本完成AT_Command的配置,可以进行串口测试。

  4. 数据上报,数据上报通常使用标准格式如下:
    首先需要在产品中找到属性上报的Topic类,注意要将${deviceName}替换为设备名。
    在这里插入图片描述
    STM32中可使用如下的代码进行motorstatus属性上报

    char sendmsg[256];
    sprintf(sendmsg,"AT+MQTTPUB=0,\"/sys/a1Tt5wtm2af/${deviceName}/thing/event/property/post\",\"{\\\"id\\\":1685082419785\\\,\\\"params\\\":{\\\"motorstatus\\\":%d}\\\,\\\"version\\\":\\\"1.0\\\"\\\,\\\"method\\\":\\\"thing.event.property.post\\\"}\",1,0\r\n", motorstatus);
    HAL_UART_Transmit(&huart2, (unsigned char *)sendmsg, strlen(sendmsg), 0xffff);  // wifi串口数据发送
    HAL_Delay(1000);
    
  5. 云端属性获取,当云上产生设备属性操作时会通过MQTT发送到对应的设备中,此时需要进行相应的解析操作,首先通过判断wifiConnectFlag 标志位判断是否链接阿里云成功,若成功后之后的云端下发的属性命令将在wifi.c中的wifi_connnect_calback(uart2_rx_buf, strlen(uart2_rx_buf));函数进行解析:
    本部分代码的逻辑为判断字符串数组中是否有特定的三位字符与motorstatus属性吻合,从而解析出对应的属性值。

    /* 
     * @brief    wifi 连接成功后数据解析
     */
    // +MQTTSUBRECV:0,"/sys/a1U3gCVc2Lh/Device1/thing/service/property/set",104,{"method":"thing.service.property.set","id":"1199288712",
    // "params":{"windowControl":3},"version":"1.0.0"}
    void wifi_connnect_calback(unsigned char *data, uint8_t len)
    {
    	int i = 0;
        unsigned char *p ;
        	
    	p = data;  // 指针p指向接受数组的第一个元素
    	for(i=50;i<strlen(data);i++)
    	{
    		if(*(p+i)=='t' && *(p+i+1)=='u' && *(p+i+2) == 's')  // 寻找"motorstatus"
    		{
    			motorstatus = *(p+i+5)-0x30;
    		}
    	}
    	
    }
    

总结

首先,在wifi_uart.c文件中实现了串口发送和接收回调函数。wifi_uart_write函数用于向串口发送缓冲区写入数据并启动发送,同时使用HAL_UART_Transmit函数进行串口数据发送。WIFI_UART_RxCpltCallback函数用于处理串口接收到的数据,将数据放入接收缓冲区。

stm32f1xx_it.c文件中,使用DMA和空闲中断的方式进行串口2的接收。当空闲中断触发时,会调用WIFI_UART_RxCpltCallback函数处理接收到的数据。

wifi.c文件中,创建AT适配器对象,并在wifi_init函数中进行AT指令的配置和发送。通过调用at_send_singlline函数发送AT命令。在wifi_task函数中循环调用,通过判断wifiConnectFlag标志位判断是否连接成功。

对于数据上报,你可以根据标准格式构造要发送的数据,使用sprintf函数将数据格式化为AT命令的形式,然后通过HAL_UART_Transmit函数发送到串口。例如,使用sprintf函数将motorstatus属性格式化为要发送的字符串,然后通过HAL_UART_Transmit函数发送到串口。

对于云端属性获取,当云端发送设备属性操作时,通过判断wifiConnectFlag标志位和解析接收到的数据进行相应的操作。在wifi_connnect_calback函数中,你可以解析接收到的数据,判断是否含有特定的属性命令,并提取属性值。

需要注意的是,以上只是一个简单的示例,具体的实现可能需要根据你的项目需求进行适当的修改和调整。同时,确保在使用AT命令进行通信时,正确配置串口和波特率,并根据具体的硬件连接情况进行适配。

问题排查

除了上述提到的移植和配置外,以下是一些可能需要的步骤和流程:

  1. 确定硬件连接:根据AT_Command库的要求,确认将STM32F103C8T6与Modem、WIFI模块、蓝牙等设备正确连接。确保使用的串口、引脚和电源连接正确。

  2. 配置CubeMX:使用CubeMX配置STM32F103C8T6的引脚和时钟设置,确保与硬件连接一致。在CubeMX中选择正确的串口配置,包括波特率、数据位、停止位等参数。

添加库文件和代码:将AT_Command库的源代码和相应的头文件添加到你的项目中。确保在编译过程中包含这些文件,并链接到正确的位置。

  1. 初始化串口和DMA:在代码中初始化串口和DMA相关的设置,确保正确配置串口的接收和发送功能。确保正确启动DMA进行接收,并在空闲中断中处理接收到的数据。

  2. 实现适配器函数:根据AT_Command库的要求,实现适配器函数,包括串口发送和接收的函数。这些函数将作为AT_Command库的回调函数,在相应的事件发生时被调用。

  3. 初始化AT_Command对象:在代码中创建AT_Command对象,并使用之前实现的适配器函数进行初始化。这将使AT_Command库能够使用正确的串口进行通信,并通过回调函数处理接收到的数据。

  4. 配置AT指令和发送数据:根据你的项目需求,使用AT_Command库提供的函数配置AT指令,例如发送AT测试命令、配置工作模式、创建路由器等。使用AT_Command库提供的函数发送数据到串口,实现数据上报等功能。

  5. 解析接收数据:根据AT_Command库的回调函数,解析接收到的数据。根据具体的协议和数据格式,提取需要的信息并进行相应的处理。例如,在wifi_connnect_calback函数中解析云端下发的属性命令,并根据属性命令进行相应的操作。

  6. 循环调用AT_Command库:在主循环中循环调用AT_Command库的相关函数,确保AT指令的正常运行。可以通过wifi_task函数进行循环调用,并在循环中添加适当的延时。

  7. 调试和测试:进行逐步调试和测试,确保AT_Command库在STM32F103C8T6上正常工作。验证AT指令的发送和接收功能,检查数据上报和云端属性获取的正确性。

以上是一个大致的流程,具体的实现可能需要根据你的项目需求和AT_Command库的要求进行调整。确保按照库的文档和示例进行

源码获取

关注公众号electronic造物实验室并发送AT指令即可获取测试源码。

在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐