sujingliang 发表于 2025-6-18 19:21

【灵动微电子MM32F0121测评】11、外接WIFI模块实现MQTT云数据上传

本帖最后由 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_InitTypeDefGPIO_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);

      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;
    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 = USART_ReceiveData(USART2);
      }
      else if (GetTick() - start_time >= timeout_ms)
      {
            break;// 超时,返回已接收的字节数
      }
    }

    return received;// 返回实际接收的字节数
}5)配网及MQTT配置
void configure_wifi(void)
{
      char response;
      
      //重启
      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_ti   = 0;
      uint32_t Sum1 = 0;
      uint32_t Sum2 = 0;
      uint32_t Sum3 = 0;
      float    Voltage1;//,Voltage2, Voltage3;
      
      char cmd;
      char response;
      
      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;
                                                      }else if(i%3==1){
                                                                Sum2 += ADC_Buffer;
                                                      }else{
                                                                Sum3 += ADC_Buffer;
                                                      }
            }

            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:


AdaMaYun 发表于 2025-7-31 17:56

外接WIFI模块实现MQTT云数据上传
页: [1]
查看完整版本: 【灵动微电子MM32F0121测评】11、外接WIFI模块实现MQTT云数据上传