如何在Node-RED中将串口拆分数据分别传入两个gauss组件?
Node-RED 拆分串口数据到两个Gauss组件的解决方案
问题现状
STM32通过串口发送ADC原始值与温度值(格式为两行文本),Node-RED中现有Function节点无法将两个数据分别传入对应Gauss组件,当前Function节点及STM32发送代码如下:
现有Function节点代码
var lines = msg.payload.split('\r\n'); var adcValue = parseFloat(lines[0].split(':')[1]); var temperature = parseFloat(lines[1].split(':')[1]); msg.payload = adcValue, temperature; return msg;
STM32端发送代码
if(converADC == 1){ rawValueconta = rawValue; converADC = 0; HAL_ADC_Stop_IT(&hadc3); while(counter < 10000){ if(flag == 1){ flag = 0; sprintf(msg, "ADC rawValue: %hu\r\n", rawValueconta); HAL_UART_Transmit(&huart3, (uint8_t*) msg, strlen(msg), 100); temp = ((float)(110-30)/ (float)(*(TS_CAL2)-*(TS_CAL1)))*(float)(rawValueconta-*(TS_CAL1))+(float)30; sprintf(msg, "Temperature: %.2f\r\n", temp); HAL_UART_Transmit(&huart3, (uint8_t*) msg, strlen(msg), 100); HAL_ADC_Start_IT(&hadc3); if(converADC == 1){ rawValueconta = rawValue; } } } } } converADC = 0;
问题分析
- Function节点中
msg.payload = adcValue, temperature;使用了逗号运算符,最终只会将temperature赋值给msg.payload,导致ADC值丢失,且无法同时传递两个独立数据到不同组件。 - STM32端的
while(counter < 10000)循环逻辑存在问题,会重复发送同一组数据直到计数器达标,且未添加组结束标记,易导致Node-RED串口节点出现粘包/截断问题。
解决方案
方案1:通过node.send()发送多消息分流
修改Function节点代码,将ADC值和温度值分别封装为独立消息发送,Node-RED会自动生成多个输出端口,对应连接到两个Gauss组件即可:
// 拆分文本并过滤空行,避免数据异常 var lines = msg.payload.split('\r\n').filter(line => line.trim() !== ''); if (lines.length >= 2) { // 提取并格式化ADC值(去除多余空格) var adcValue = parseFloat(lines[0].split(':')[1].trim()); // 提取并格式化温度值 var temperature = parseFloat(lines[1].split(':')[1].trim()); // 发送ADC值消息,可通过topic标记类型 node.send({ payload: adcValue, topic: 'adc' }); // 发送温度值消息 node.send({ payload: temperature, topic: 'temperature' }); } // 无需return msg,node.send已完成消息发送
方案2:单消息携带多属性,用Switch节点分流
如果希望保持单消息输出,可将两个值存入消息的不同属性,后续通过Switch节点拆分路由:
修改后的Function节点代码
var lines = msg.payload.split('\r\n').filter(line => line.trim() !== ''); if (lines.length >= 2) { msg.adc = parseFloat(lines[0].split(':')[1].trim()); msg.temperature = parseFloat(lines[1].split(':')[1].trim()); // 可选:删除原payload,避免干扰后续节点 delete msg.payload; } return msg;
后续路由配置
添加Switch节点,配置两个分支:
- 分支1:判断条件选择
msg.adc存在,输出连接到ADC对应的Gauss组件 - 分支2:判断条件选择
msg.temperature存在,输出连接到温度对应的Gauss组件
STM32端优化建议
修正循环逻辑并添加组结束标记,避免重复发送和串口粘包:
if(converADC == 1){ rawValueconta = rawValue; converADC = 0; HAL_ADC_Stop_IT(&hadc3); if(flag == 1){ flag = 0; // 发送ADC值 sprintf(msg, "ADC rawValue: %hu\r\n", rawValueconta); HAL_UART_Transmit(&huart3, (uint8_t*) msg, strlen(msg), 100); // 计算并发送温度值,添加\r\n\r\n作为组结束标记 temp = ((float)(110-30)/ (float)(*(TS_CAL2)-*(TS_CAL1)))*(float)(rawValueconta-*(TS_CAL1))+(float)30; sprintf(msg, "Temperature: %.2f\r\n\r\n", temp); HAL_UART_Transmit(&huart3, (uint8_t*) msg, strlen(msg), 100); HAL_ADC_Start_IT(&hadc3); } converADC = 0; }
同时在Node-RED的串口节点配置中,将“结束符”设置为\r\n\r\n,确保每次接收完整的一组数据。
内容的提问来源于stack exchange,提问作者Tiago Matos
相关产品推荐
相关产品推荐

