本帖最后由 sujingliang 于 2025-4-26 13:41 编辑
为了将检测到的液位数据发送出去,做了下面这个扩展板
主要的作用是分别连接套件中的开发板和扩展板,并通过搭载的WIFI模块用MQTT协议将数据发送的物联网平台
整体连接示意图:
实物图:
一、MQTT平台准备
采用巴法云,地址https://bemfa.com/
1、每一个用户平台都会分配个ClientID,后面会用到
2、新建MQTT设备云
按照巴法云规范标准,后3位为004,代表设备为传感器
平台准备完毕
二、软件准备
程序在液位检测例程上修改,液位检测的部分不再描述。
所用WIFI模块为WF24,和MCU UART(P2.2 P2.3)连接。
1、UART初始化
/* Configure and enable the UART peripheral */
Cy_SCB_UART_Init(scb_0_HW, &scb_0_config, &CYBSP_UART_context);
Cy_SCB_UART_Enable(scb_0_HW);
/* 配置 UART 中断 */
Cy_SysInt_Init(&UART_IRQ_cfg, UART_InterruptHandler);
NVIC_EnableIRQ(UART_IRQ_cfg.intrSrc); // 使能 NVIC 中断
// 当 RX FIFO 非空时启用 UART RX 中断
Cy_SCB_SetRxInterruptMask(scb_0_HW , CY_SCB_RX_INTR_NOT_EMPTY);
// 当 TX FIFO 未满时启用 UART TX 中断
Cy_SCB_SetTxInterruptMask (scb_0_HW ,CY_SCB_TX_INTR_LEVEL);
/* Enable global interrupts */
__enable_irq();
初始化UART,并启用RX中断,RX中断处理函数UART_InterruptHandler。
2、RX中断处理函数UART_InterruptHandler
static void UART_InterruptHandler(void)
{
/* 检查是否 RX FIFO 非空 */
if (Cy_SCB_GetRxInterruptStatusMasked(scb_0_HW) & CY_SCB_UART_RX_NOT_EMPTY)
{
/* 读取接收到的数据 */
uint8_t rxData = Cy_SCB_UART_Get(scb_0_HW);
/* 存入缓冲区(可改为环形缓冲区) */
if (rxCount < RX_BUFFER_SIZE)
{
rxBuffer[rxCount++] = rxData;
}
/* 可选:检查结束符(如 '\n') */
if (rxData == '\n'&&rxCount>2)
{
// 可以设置标志位通知主循环
atResponseReady=true;
}
}
/* 清除中断标志 */
Cy_SCB_ClearRxInterrupt(scb_0_HW, CY_SCB_UART_RX_NOT_EMPTY);
}
当接收数据最后一位为回车,设置接收完成标志为true,用于主循环处理。
3、主循环处理
if(atResponseReady)
{
uartRxProcessHandler();
rxCount=0;
atResponseReady=false;
}
void uartRxProcessHandler(void)
{
if(strstr(rxBuffer,"on")!= NULL){
Cy_GPIO_Write(CYBSP_LED3_PORT ,CYBSP_LED3_PIN,1);
enCapSense=true;
}
else if(strstr(rxBuffer,"off")!= NULL)
{
Cy_GPIO_Write(CYBSP_LED3_PORT ,CYBSP_LED3_PIN,0);
}
memset(rxBuffer,0,sizeof(rxBuffer));
}
接收到含有on的字符串,点灯并使能液位监测
4、main函数中水位监测处理
if(enCapSense)
{
uint32_t level_w_FR, level_wo_FR;
/* Scan the normal Liquid Level Widget */
Cy_CapSense_ScanWidget(CY_CAPSENSE_LIQUIDLEVEL0_WDGT_ID, &cy_capsense_context);
/* Wait until the scan is finished */
while(Cy_CapSense_IsBusy(&cy_capsense_context)) {}
/* Scan the Foam Rejection Widget */
Cy_CapSense_ScanWidget(CY_CAPSENSE_LIQUIDLEVEL0_FR_WDGT_ID, &cy_capsense_context);
/* Wait until the scan is finished */
while(Cy_CapSense_IsBusy(&cy_capsense_context)) {}
/* Process all th widgets */
Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);
/* Send capsense data to the Tuner */
//Cy_CapSense_RunTuner(&cy_capsense_context);
/* store the liquid level before and after foam rejection */
level_wo_FR = CY_CAPSENSE_LIQUIDLEVEL0_PTRPOSITION_VALUE->x;
level_w_FR = CY_CAPSENSE_LIQUIDLEVEL0_FR_PTRPOSITION_VALUE->x;
sprintf(cmd,"AT+MQTTPUBRAW=WATER004,%d,0,0",getDigits(level_wo_FR)+2);
Send_AT_Command(cmd, response, AT_TIMEOUT_MS);
sprintf(cmd,"%ld",level_wo_FR);
Send_AT_Command(cmd, response, AT_TIMEOUT_MS);
/* keep the compiler happy */
(void)level_wo_FR;
(void)level_w_FR;
enCapSense=false;
}
液位监测标志使能状态,获取level_wo_FR 。通过以下AT指令发送出去
sprintf(cmd,"AT+MQTTPUBRAW=WATER004,%d,0,0",getDigits(level_wo_FR)+2);
Send_AT_Command(cmd, response, AT_TIMEOUT_MS);
sprintf(cmd,"%ld",level_wo_FR);
Send_AT_Command(cmd, response, AT_TIMEOUT_MS);
5、发送AT指令
bool Send_AT_Command(const char* atCommand, char* response, uint16_t timeout_ms) {
/* 清空缓冲区 */
memset(rxBuffer, 0, RX_BUFFER_SIZE);
rxCount = 0;
atResponseReady = false;
/* 发送 AT 指令(带换行符) */
Cy_SCB_UART_PutString(scb_0_HW, atCommand);
Cy_SCB_UART_PutString(scb_0_HW, "\r\n"); // 添加结束符
/* 等待响应 */
Cy_SysLib_Delay(timeout_ms);
/* 返回响应内容 */
strcpy(response, rxBuffer);
return true;
}
6、MQTT初始化
//WIFI模块RESET
Send_AT_Command("AT+RST", response, AT_TIMEOUT_MS);
//WIFI连接
if (Send_AT_Command("AT+CWSTATE?", response, AT_TIMEOUT_MS)) {
if (strstr(rxBuffer, "+CWSTATE:2") == NULL)
{
Send_AT_Command("AT+CWJAP=ssid,password", response, AT_TIMEOUT_MS);
}
}
//发送clientid,其中的clientid要替换成自己的
Send_AT_Command("AT+MQTTLONGCLIENTID=1892ce3cc45c4xxxxxxxxxxxxxxxx7", response, AT_TIMEOUT_MS);
//连接巴法云
Send_AT_Command("AT+MQTTCONN=bemfa.com,9501,0", response, AT_TIMEOUT_MS);
//发布WATER004主题登录指令
Send_AT_Command("AT+MQTTPUBRAW=WATER004/up,7,0,0", response, AT_TIMEOUT_MS);
Send_AT_Command("**n", response, AT_TIMEOUT_MS);
//订阅WATER004
Send_AT_Command("AT+MQTTSUB=WATER004,0", response, AT_TIMEOUT_MS);
//发布一条数据用于测试
Send_AT_Command("AT+MQTTPUBRAW=WATER004,4,0,0", response, AT_TIMEOUT_MS);
Send_AT_Command("25", response, AT_TIMEOUT_MS);
三、运行
wifi模块初始化成功,并且mqtt连接成功,绿灯亮
通过巴法云APP,可以搜到WATER004,连接后可以设置为"液位监测"方便使用,可以看到测试数据25cm已经显示出来
点击进去,显示如下:
可以按这个按钮控制LED亮,使能液位监测标志,MCU会采集一次数据,并通过MQTT发送数据,这时手机APP显示的数据随之改变。
MCU发给WIFI模块日志:
WIFI模块发给MCU日志:
MQTT+CapSense的潜在使用场景:
1、远程鱼缸水位监测
2、远程降雨量测量
3、农田灌溉优化
4、洪灾灾害易发区监控
...
|
此文章已获得独家原创/原创奖标签,著作权归21ic所有,未经允许禁止转载。
|