本帖最后由 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:
|
|