打印
[MM32硬件]

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

[复制链接]
772|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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:


使用特权

评论回复
沙发
AdaMaYun| | 2025-7-31 17:56 | 只看该作者
外接WIFI模块实现MQTT云数据上传

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

147

帖子

3

粉丝