- /* 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、洪灾灾害易发区监控
...