本帖最后由 sujingliang 于 2025-6-18 21:29 编辑
WIFI模块采用大夏龙雀的DX- WF24模块,主控BK7238,支持MQTT协议。
MQTT服务选用巴法云:https://cloud.bemfa.com/。
主要的原因是试用免费,接入比较简单。缺点只支持 MQTT3.1.1 协议。
MM32F0121使用USART2与wifi模块通讯,printf重定向到USART1做为LogTx。
1、DX- WF24 主要的AT指令
设置 Station需连接的 AP
AT+CWJAP=<ssid>,<pwd>
设置 Station需连接的 AP
AT+CWJAP=<ssid>,<pwd>
设置 MQTT 客户端 ID
AT+MQTTLONGCLIENTID=<client_id>
连接 MQTT 服务器
AT+MQTTCONN=<host>,<port>,<reconnect>
发布 MQTT 主题消息
AT+MQTTPUBRAW=<topic>,<length>, <qos>,<retain>
订阅 MQTT 主题
AT+MQTTSUB=<topic>,<qos>
2、巴法云准备
新建一个MQTT设备或者像我这样利用以前用过的设备主题:WATER004,
这个设备负责ADC采样值的分发。比如MCU通过WIFI模块将采集到的ADC数据发布到巴法云上,用户可以通过手机上的巴法APP获得该数据。
3、软件部分
1)USART配置
- //RX:PA9;TX:PA10
- void USART2_Configure(uint32_t Baudrate)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- USART_InitTypeDef USART_InitStruct;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
- USART_StructInit(&USART_InitStruct);
- USART_InitStruct.USART_BaudRate = Baudrate;
- USART_InitStruct.USART_WordLength = USART_WordLength_8b;
- USART_InitStruct.USART_StopBits = USART_StopBits_1;
- USART_InitStruct.USART_Parity = USART_Parity_No;
- USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_Init(USART2, &USART_InitStruct);
-
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_3);
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_3);
- GPIO_StructInit(&GPIO_InitStruct);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStruct);
- GPIO_StructInit(&GPIO_InitStruct);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_FLOATING;
- GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- USART_Cmd(USART2, ENABLE);
- }
2)封装一个TX_Polling函数
- void USART_TxData_Polling(uint8_t *Buffer, uint8_t Length)
- {
- uint8_t i = 0;
- for (i = 0; i < Length; i++)
- {
- USART_SendData(USART2, Buffer[i]);
- while (RESET == USART_GetFlagStatus(USART2, USART_FLAG_TC))
- {
- }
- }
- printf("TX:%s,Length:%d\r\n",Buffer,Length);
- }
3)发送AT指令的函数
- void send_at_command(const char *cmd,uint16_t time_out_ms)
- {
- // 添加AT前缀和终止符
- char full_cmd[128];
- snprintf(full_cmd, sizeof(full_cmd), "%s\r\n", cmd);
-
- USART_TxData_Polling((uint8_t*)full_cmd,strlen(full_cmd));
- PLATFORM_DelayMS(time_out_ms); // 等待模块响应
- }
4)USART接收RX函数
- uint16_t receive_response(char *buffer, uint16_t size, uint32_t timeout_ms)
- {
- uint32_t start_time = GetTick(); // 使用 SysTick 或 TIMx 计时
- uint16_t received = 0;
- while (received < size)
- {
- if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET)
- {
- buffer[received++] = USART_ReceiveData(USART2);
- }
- else if (GetTick() - start_time >= timeout_ms)
- {
- break; // 超时,返回已接收的字节数
- }
- }
- return received; // 返回实际接收的字节数
- }
5)配网及MQTT配置
- void configure_wifi(void)
- {
- char response[256];
-
- //重启
- send_at_command("AT+RST",1500);
- receive_response(response, sizeof(response),500);
- printf("%s\r\n",response);
-
- //查询是否自动连接wifi
- send_at_command("AT+CWSTATE?",1500);
- receive_response(response, sizeof(response),500);
- printf("%s\r\n",response);
- if (strstr(response, "+CWSTATE:2") == NULL)
- {
- //连接wifi
- send_at_command("AT+CWJAP=ssid,password",1500);
- receive_response(response, sizeof(response),500);
- printf("%s\r\n",response);
- }
-
- //设置MQTT clientID
- send_at_command("AT+MQTTLONGCLIENTID=1892ce3cc45c43a39f66b9b8xxxxxxxx",1500);
- receive_response(response, sizeof(response),500);
- printf("%s\r\n",response);
-
- //连接巴法云
- send_at_command("AT+MQTTCONN=bemfa.com,9501,0",1500);
- receive_response(response, sizeof(response),500);
- printf("%s\r\n",response);
-
- //up 指令:向主题WATER004/推送数据。只更新云端数据,不进行任何推送
- //发布者**n
- send_at_command("AT+MQTTPUBRAW=WATER004/up,7,0,0",1500);
- receive_response(response, sizeof(response),500);
- printf("%s\r\n",response);
-
- send_at_command("**n",1500);
- //receive_response(response, sizeof(response),500);
-
- //订阅 MQTT 主题
- send_at_command("AT+MQTTSUB=WATER004,0",1500);
- receive_response(response, sizeof(response),500);
- printf("%s\r\n",response);
-
- //发布 MQTT 主题消息,先发1个数字25做为测试
- send_at_command("AT+MQTTPUBRAW=WATER004,4,0,0",1500);
- receive_response(response, sizeof(response),500);
- printf("%s\r\n",response);
-
- send_at_command("25",1500);
-
- }
6)发送ADC采样的测试程序
- void wifi_mqtt_Sample(void)
- {
- uint8_t i = 0;
- uint32_t Sum1 = 0;
- uint32_t Sum2 = 0;
- uint32_t Sum3 = 0;
- float Voltage1;//,Voltage2, Voltage3;
-
- char cmd[50];
- char response[256];
-
- ADC_Configure();
- ADC_SoftwareStartConvCmd(ADC1, ENABLE);
-
- USART2_Configure(115200);
- configure_wifi();
-
- while(1)
- {
- if (0 != ADC_DMA_InterruptFlag)
- {
- ADC_DMA_InterruptFlag = 0;
- Sum1 = 0;
- Sum2 = 0;
- Sum3 = 0;
- for (i = 0; i < 30; i++)
- {
- if(i%3==0){
- Sum1 += ADC_Buffer[i];
- }else if(i%3==1){
- Sum2 += ADC_Buffer[i];
- }else{
- Sum3 += ADC_Buffer[i];
- }
- }
- Voltage1 = (float)Sum1 / (float)10.0 * (float)3.3 / (float)4096.0;
-
- //AT+MQTTPUBRAW发布 MQTT 主题消息
- sprintf(cmd,"AT+MQTTPUBRAW=WATER004,%d,0,0",6);
- send_at_command(cmd,500);
- receive_response(response, sizeof(response),500);
- sprintf(cmd,"%.2f",Voltage1);
- send_at_command(cmd,500);
- receive_response(response, sizeof(response),500);
-
- PLATFORM_LED_Toggle(LED1);
- PLATFORM_LED_Toggle(LED2);
-
- PLATFORM_DelayMS(1000);
- }
- }
- }
4、效果
调整开发板上的电位器,ADC采集数据发生变化,通过MQTT发送给巴法云。
通过巴法app可以获得ADC数据。
MQTTX接收订阅:
手机APP:
|