[PSOC™] 【英飞凌PSOC 4000T DIY】3、液位监测之MQTT

[复制链接]
 楼主| sujingliang 发表于 2025-4-26 10:14 | 显示全部楼层 |阅读模式
<
本帖最后由 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初始化
  1. /* Configure and enable the UART peripheral */
  2.     Cy_SCB_UART_Init(scb_0_HW, &scb_0_config, &CYBSP_UART_context);
  3.     Cy_SCB_UART_Enable(scb_0_HW);

  4.     /* 配置 UART 中断 */
  5.      Cy_SysInt_Init(&UART_IRQ_cfg, UART_InterruptHandler);
  6.      NVIC_EnableIRQ(UART_IRQ_cfg.intrSrc);  // 使能 NVIC 中断

  7.      // 当 RX FIFO 非空时启用 UART RX 中断
  8.      Cy_SCB_SetRxInterruptMask(scb_0_HW , CY_SCB_RX_INTR_NOT_EMPTY);


  9.      // 当 TX FIFO 未满时启用 UART TX 中断
  10.      Cy_SCB_SetTxInterruptMask (scb_0_HW ,CY_SCB_TX_INTR_LEVEL);


  11.     /* Enable global interrupts */
  12.     __enable_irq();
初始化UART,并启用RX中断,RX中断处理函数UART_InterruptHandler。

2、RX中断处理函数UART_InterruptHandler
  1. static void UART_InterruptHandler(void)
  2. {
  3.     /* 检查是否 RX FIFO 非空 */
  4.     if (Cy_SCB_GetRxInterruptStatusMasked(scb_0_HW) & CY_SCB_UART_RX_NOT_EMPTY)
  5.     {
  6.         /* 读取接收到的数据 */
  7.         uint8_t rxData = Cy_SCB_UART_Get(scb_0_HW);

  8.         /* 存入缓冲区(可改为环形缓冲区) */
  9.         if (rxCount < RX_BUFFER_SIZE)
  10.         {
  11.             rxBuffer[rxCount++] = rxData;
  12.         }

  13.         /* 可选:检查结束符(如 '\n') */
  14.         if (rxData == '\n'&&rxCount>2)
  15.         {
  16.             // 可以设置标志位通知主循环

  17.                 atResponseReady=true;
  18.         }

  19.     }

  20.     /* 清除中断标志 */
  21.     Cy_SCB_ClearRxInterrupt(scb_0_HW, CY_SCB_UART_RX_NOT_EMPTY);
  22. }
当接收数据最后一位为回车,设置接收完成标志为true,用于主循环处理。

3、主循环处理
  1. if(atResponseReady)
  2. {
  3.               uartRxProcessHandler();
  4.                rxCount=0;
  5.                atResponseReady=false;
  6. }
  1. void uartRxProcessHandler(void)
  2. {
  3. if(strstr(rxBuffer,"on")!= NULL){
  4.                 Cy_GPIO_Write(CYBSP_LED3_PORT ,CYBSP_LED3_PIN,1);
  5.                 enCapSense=true;
  6.         }
  7.         else if(strstr(rxBuffer,"off")!= NULL)
  8.         {
  9.                 Cy_GPIO_Write(CYBSP_LED3_PORT ,CYBSP_LED3_PIN,0);
  10.         }
  11.         memset(rxBuffer,0,sizeof(rxBuffer));
  12. }
接收到含有on的字符串,点灯并使能液位监测
4、main函数中水位监测处理
  1. if(enCapSense)
  2.             {
  3.             uint32_t level_w_FR, level_wo_FR;

  4.         /* Scan the normal Liquid Level Widget */
  5.             Cy_CapSense_ScanWidget(CY_CAPSENSE_LIQUIDLEVEL0_WDGT_ID, &cy_capsense_context);
  6.         /* Wait until the scan is finished */
  7.         while(Cy_CapSense_IsBusy(&cy_capsense_context)) {}

  8.         /* Scan the Foam Rejection Widget */
  9.         Cy_CapSense_ScanWidget(CY_CAPSENSE_LIQUIDLEVEL0_FR_WDGT_ID, &cy_capsense_context);
  10.         /* Wait until the scan is finished */
  11.         while(Cy_CapSense_IsBusy(&cy_capsense_context)) {}

  12.         /* Process all th widgets */
  13.         Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);

  14.         /* Send capsense data to the Tuner */
  15.         //Cy_CapSense_RunTuner(&cy_capsense_context);

  16.         /* store the liquid level before and after foam rejection */
  17.         level_wo_FR = CY_CAPSENSE_LIQUIDLEVEL0_PTRPOSITION_VALUE->x;
  18.         level_w_FR = CY_CAPSENSE_LIQUIDLEVEL0_FR_PTRPOSITION_VALUE->x;

  19.         sprintf(cmd,"AT+MQTTPUBRAW=WATER004,%d,0,0",getDigits(level_wo_FR)+2);
  20.         Send_AT_Command(cmd, response, AT_TIMEOUT_MS);
  21.         sprintf(cmd,"%ld",level_wo_FR);
  22.         Send_AT_Command(cmd, response, AT_TIMEOUT_MS);

  23.         /* keep the compiler happy */
  24.         (void)level_wo_FR;
  25.         (void)level_w_FR;
  26.                 enCapSense=false;
  27.             }
液位监测标志使能状态,获取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指令
  1. bool Send_AT_Command(const char* atCommand, char* response, uint16_t timeout_ms) {
  2.     /* 清空缓冲区 */
  3.     memset(rxBuffer, 0, RX_BUFFER_SIZE);
  4.     rxCount = 0;
  5.     atResponseReady = false;

  6.     /* 发送 AT 指令(带换行符) */
  7.     Cy_SCB_UART_PutString(scb_0_HW, atCommand);
  8.     Cy_SCB_UART_PutString(scb_0_HW, "\r\n"); // 添加结束符

  9.     /* 等待响应 */
  10.     Cy_SysLib_Delay(timeout_ms);

  11.     /* 返回响应内容 */
  12.     strcpy(response, rxBuffer);
  13.     return true;
  14. }
6、MQTT初始化
  1. //WIFI模块RESET
  2.   Send_AT_Command("AT+RST", response, AT_TIMEOUT_MS);

  3.   //WIFI连接
  4.     if (Send_AT_Command("AT+CWSTATE?", response, AT_TIMEOUT_MS)) {
  5.                 if (strstr(rxBuffer, "+CWSTATE:2") == NULL)
  6.                 {
  7.                     Send_AT_Command("AT+CWJAP=ssid,password", response, AT_TIMEOUT_MS);
  8.                 }
  9.     }

  10.    //发送clientid,其中的clientid要替换成自己的
  11.     Send_AT_Command("AT+MQTTLONGCLIENTID=1892ce3cc45c4xxxxxxxxxxxxxxxx7", response, AT_TIMEOUT_MS);

  12.    //连接巴法云
  13.     Send_AT_Command("AT+MQTTCONN=bemfa.com,9501,0", response, AT_TIMEOUT_MS);

  14.   //发布WATER004主题登录指令
  15.     Send_AT_Command("AT+MQTTPUBRAW=WATER004/up,7,0,0", response, AT_TIMEOUT_MS);
  16.     Send_AT_Command("**n", response, AT_TIMEOUT_MS);

  17.   //订阅WATER004
  18.     Send_AT_Command("AT+MQTTSUB=WATER004,0", response, AT_TIMEOUT_MS);

  19.   //发布一条数据用于测试
  20.     Send_AT_Command("AT+MQTTPUBRAW=WATER004,4,0,0", response, AT_TIMEOUT_MS);
  21.     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、洪灾灾害易发区监控

...




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
和下土 发表于 2025-4-30 22:20 | 显示全部楼层
在 Arduino IDE 中,可以使用 PubSubClient 库来实现 MQTT 功能。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

146

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部