串口数据处理函数float sendCommand(String command, const int timeout)

本文介绍了一种从串口发送指令并解析回复数据的方法,特别关注于从回复中提取心率数值的过程。通过发送特定指令,程序等待串口回应,一旦收到回复,将解析含有心率信息的字符串,并从中提取出具体的心率值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们需要从串口 发送指令,然后串口有回复
需要把回复的数据进行处理
例如:串口发在这里插入图片描述
回复:+HEART=当前心率
在这里插入图片描述
+HEART=66
我们需要把心率值66提出来
float sendCommand(String command, const int timeout)
{
String response = “”;
WIFISerial.print(command); // send the read character to the esp8266
long int time = millis();
while( (time+timeout) > millis())
{
while(WIFISerial.available())
{
// The esp has data so display its output to the serial window
char c = WIFISerial.read(); // read the next character.
response+=c;
}
}
if ( response.indexOf(“NULL”)==-1 )//过滤输出 NULL 的情况
{
// Serial.print(response);
int x=response.indexOf("="); //体温 1–6
return( (response.substring(x+1,x+5)).toFloat() );

}

}

你可以把C#代码改写为python语言吗?C#代码如下:using AToolExport; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ChamberControl.GWS { public class GWSAPI : ChamberBase { private SerialPort GWSSerial; private eSerialPort _serialPort; private const string DefProgramName = ""; #region GWS串口命令 private const string COMMAND_GET_TEMP = "1, TEMP?"; private const string COMMAND_GET_HUMI = "1, HUMI?"; private const string COMMAND_GET_PRGM = "1, PRGM SET?"; private const string COMMAND_STOP_DEV = "1, MODE, OFF"; private const string COMMAND_EXECUTE_PROGRAM = "1, PRGM, RUN, RAM:1, STEP1"; private const string COMMAND_SET_CONSTANT_TEMP = "1, TEMP"; private const string COMMAND_SET_MODE_CONSTANT = "1, MODE, CONSTANT"; #endregion public GWSAPI(PrintMessageDelegate PrintMsgHandler, eSerialPort serialPort) { this.PrintMsgHandler = PrintMsgHandler; _serialPort = serialPort; } #region 信息打印方法 private void DebugPrint(string msg) { if (PrintMsgHandler != null) { PrintMsgHandler(MessageLevel.Debug, msg); } else { Console.WriteLine("[DEBUG]" + msg); } } private void InfoPrint(string msg) { if (PrintMsgHandler != null) { PrintMsgHandler(MessageLevel.Info, msg); } else { Console.WriteLine("[INFO]" + msg); } } private void ErrorPrint(string msg) { if (PrintMsgHandler != null) { PrintMsgHandler(MessageLevel.Error, msg); } else { Console.WriteLine("[ERROR]" + msg); } } private void WarningPrint(string msg) { if (PrintMsgHandler != null) { PrintMsgHandler(MessageLevel.Warning, msg); } else { Console.WriteLine("[WARNING]" + msg); } } #endregion #region 发收指令的方法 private bool SerialInit() { int baudrate = 19200; string outValue = string.Empty; try { Thread.Sleep(200); GWSSerial = new SerialPort(Enum.GetName(typeof(eSerialPort), _serialPort), baudrate, Parity.None, 8, StopBits.One); GWSSerial.WriteTimeout = 1000; GWSSerial.ReadTimeout = 1000; GWSSerial.Open(); } catch (Exception ex) { InfoPrint("初始化串口失败"); InfoPrint(ex.ToString()); return false; } return true; } private bool SerialClose() { try { GWSSerial.Close(); } catch (Exception ex) { InfoPrint("关闭串口失败"); InfoPrint(ex.ToString()); return false; } return true; } private string GetActualTemperature() { GWSSerial.Write(COMMAND_GET_TEMP); SInterval(); string result = GWSSerial.ReadExisting(); InfoPrint($"读取温度返回:{result}"); if (!string.IsNullOrWhiteSpace(result)) { if (result.StartsWith("NA:")) { ErrorPrint(result); } else { string[] out_list = result.Split(','); if (out_list.Count() == 4) { return string.Format(out_list[0]); } } } return "null"; } private string GetActualHumidity() { GWSSerial.Write(COMMAND_GET_HUMI); SInterval(); string result = GWSSerial.ReadExisting(); if (null != result) { if (result.StartsWith("NA:")) { if (result == "NA:CONT NOT READY-1") { ErrorPrint("由于老化箱不支持或未开启湿度控制,无法查询湿度信息"); } else { ErrorPrint(result); } } else { string[] out_list = result.Split(','); if (out_list.Count() == 4) { return string.Format(out_list[0]); } } } return "null"; } private string WriteProgram(List<Program> programList) { GWSSerial.Write("PRGM DATA WRITE, PGM1, EDIT START"); SInterval(); int step = 1; foreach (var program in programList) { List<string> commands = ConvertProgramToCommands(program, step); foreach (var cmd in commands) { GWSSerial.Write(cmd); //InfoPrint($"Writed Program: {cmd}"); } step++; SInterval(); } GWSSerial.Write("PRGM DATA WRITE, PGM1, END, OFF"); SInterval(); GWSSerial.Write("PRGM DATA WRITE, PGM1, EDIT END"); SInterval(); return GWSSerial.ReadExisting(); } private List<string> ConvertProgramToCommands(Program program, int step) { List<string> commands = new List<string>(); if (program.Temperature != 0) { commands.Add($"PRGM DATA WRITE, PGM1, STEP{step}, TEMP{program.Temperature}, TIME{program.Hour}:{program.Minute}"); } if (program.Humidity != 0) { commands.Add($"PRGM DATA WRITE, PGM1, STEP{step}, HUMI{program.Humidity}, TIME{program.Hour}:{program.Minute}"); } return commands; } private string ExecuteProgram() { GWSSerial.Write(COMMAND_EXECUTE_PROGRAM); SInterval(); return GWSSerial.ReadExisting(); } private string StopDevice() { GWSSerial.Write(COMMAND_STOP_DEV); SInterval(); return GWSSerial.ReadExisting(); } #endregion #region 重写的方法 public override bool CheckConnection() { if (!SerialInit()) { return false; } if ("null" != GetActualTemperature()) { SerialClose(); return true; } else { ErrorPrint("串口初始化完成,但是无法与老化箱进行通信。请排查线路连接,COM号,老化箱设置等问题。"); SerialClose(); return false; } } public override bool SetProgram(List<Program> programList) { string result; if (!SerialInit()) { return false; } int tryout = 1; while (tryout <= 3) { result = WriteProgram(programList); if (result.StartsWith("NA:")) { InfoPrint($"第{tryout}次尝试WriteProgram, 失败,result={result}"); tryout++; } else { return SerialClose(); } } if (4 == tryout) { InfoPrint("WriteProgram失败"); } SerialClose(); return false; } public override bool RunProgram() { string info = string.Empty; string result; if (!SerialInit()) { return false; } int tryout = 1; while (tryout <= 3) { result = ExecuteProgram(); if (result.StartsWith("NA:")) { InfoPrint($"第{tryout}次尝试ExecuteProgram, 失败,result={result}"); tryout++; } else { return SerialClose(); } } if (4 == tryout) { InfoPrint("ExecuteProgram失败"); } SerialClose(); return false; } public override bool SetTemperatureOnConstantMode(int temperature) { string result; if (!SerialInit()) { return false; } int tryout = 1; while (tryout <= 3) { GWSSerial.Write($"{COMMAND_SET_CONSTANT_TEMP}, S{temperature}"); SInterval(); result = GWSSerial.ReadExisting(); if (result.StartsWith("NA:")) { InfoPrint($"第{tryout}次尝试SetTemperature, 失败,result={result}"); tryout++; } else { break; } } if (4 == tryout) { InfoPrint("SetTemperature失败"); SerialClose(); return false; } tryout = 1; while (tryout <= 3) { GWSSerial.Write(COMMAND_SET_MODE_CONSTANT); SInterval(); result = GWSSerial.ReadExisting(); if (result.StartsWith("NA:")) { InfoPrint($"第{tryout}次尝试SetContantMode, 失败,result={result}"); tryout++; } else { return SerialClose(); } } if (4 == tryout) { InfoPrint("SetContantMode失败"); } SerialClose(); return false; } public override bool StopProgram() { string info = string.Empty; string result; if (!SerialInit()) { return false; } int tryout = 1; while (tryout <= 3) { result = StopDevice(); if (result.StartsWith("NA:")) { InfoPrint($"第{tryout}次尝试StopDevice, 失败,result={result}"); tryout++; } else { return SerialClose(); } } if (4 == tryout) { InfoPrint("StopDevice失败"); } SerialClose(); return false; } public override bool GetTemperature(out double temperature) { string result = string.Empty; string info = string.Empty; temperature = -999; if (!SerialInit()) { return false; } result = GetActualTemperature(); if ("null" != result) { if (double.TryParse(result, out double temp)) { temperature = temp; return SerialClose(); } else { InfoPrint("获取温度值失败"); } } SerialClose(); return false; } public override bool GetHumidity(out double humidity) { string result = string.Empty; string info = string.Empty; humidity = -999; if (!SerialInit()) { return false; } result = GetActualHumidity(); if ("null" != result) { if (double.TryParse(result, out double temp)) { humidity = temp; return SerialClose(); } else { InfoPrint("获取湿度值失败"); } } SerialClose(); return false; } #endregion #region 普通方法 private void SInterval() { Thread.Sleep(500); } #endregion } #region 定义的参数 public enum Status { Stop = 0, Running = 1, Reservation = 2 } #endregion }
06-07
#include "esp8266.h" #include "main.h" // 添加此头文件以解决DebugPrint声明问题 #include <string.h> #include <stdio.h> // 全局变量定义 uint8_t wifiConnected = 0; uint8_t oneNetConnected = 0; uint8_t remote_led_command = 0; uint8_t remote_motor_command = 0; uint8_t new_remote_command = 0; uint32_t uploadSuccessCount = 0; uint32_t uploadFailCount = 0; // 使用串口3 (PB10, PB11) extern UART_HandleTypeDef huart3; // 私有函数声明 static void ESP8266_Transmit(const char *data); static void ESP8266_Flush(void); static uint8_t ESP8266_WaitResponse(const char *expected, uint32_t timeout); // 使用您提供的参数 const char* ONENET_HOST = "mqtts.heclouds.com"; const int ONENET_PORT = 1883; const char* ONENET_CLIENT_ID = "jiaju"; const char* ONENET_USERNAME = "3n8QY47l17"; const char* ONENET_PASSWORD = "version=2018-10-31&res=products%2F3n8QY47l17%2Fdevices%2Fjiaju&et=2052972807&method=md5&sign=s1lLnOPwHXQNilx%2FJrdi6g%3D%3D"; const char* ONENET_TOPIC_PUB = "$sys/3n8QY47l17/jiaju/thing/property/post"; const char* ONENET_TOPIC_CMD = "$sys/3n8QY47l17/jiaju/cmd/request/#"; // 修改后的命令主题 void ESP8266_Init(void) { // 确保串口已初始化 HAL_Delay(500); // 清空串口缓冲区 ESP8266_Flush(); // 发送复位命令 ESP8266_SendCommand("AT+RST\r\n", "ready", 3000); HAL_Delay(2000); // 设置WiFi模式为STA ESP8266_SendCommand("AT+CWMODE=1\r\n", "OK", 1000); // 关闭回显 ESP8266_SendCommand("ATE0\r\n", "OK", 500); // 启用MQTT透传模式 ESP8266_SendCommand("AT+MQTTCONNCFG=0,120,1,\"\"\r\n", "OK", 1000); // 设置MQTT协议版本为3.1.1 ESP8266_SendCommand("AT+MQTTUSERCFG=0,4,\"\",\"\",\"\",0,0,\"\"\r\n", "OK", 1000); } void ESP8266_ConnectWiFi(const char* ssid, const char* password) { char cmd[128]; sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, password); if(ESP8266_SendCommand(cmd, "OK", 15000)) { wifiConnected = 1; } else { wifiConnected = 0; } } void ESP8266_ConnectOneNet(void) { char cmd[256]; sprintf(cmd, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n", ONENET_CLIENT_ID, ONENET_USERNAME, ONENET_PASSWORD); if(!ESP8266_SendCommand(cmd, "OK", 2000)) { return; } sprintf(cmd, "AT+MQTTCONN=0,\"%s\",%d,1\r\n", ONENET_HOST, ONENET_PORT); if(ESP8266_SendCommand(cmd, "+MQTTCONNECTED", 10000)) { oneNetConnected = 1; // 订阅新的命令主题(带#通配符) sprintf(cmd, "AT+MQTTSUB=0,\"%s\",1\r\n", ONENET_TOPIC_CMD); ESP8266_SendCommand(cmd, "OK", 2000); } else { oneNetConnected = 0; } } void ESP8266_SendData(float temp, float humi, uint8_t led_status, uint8_t motor_status) { static uint32_t request_id = 1; char cmd[200]; char value_str[20]; // 1. 发送温度 snprintf(value_str, sizeof(value_str), "%.1f", temp); sprintf(cmd, "AT+MQTTPUB=0,\"%s\"," "\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":" "{\\\"temperature\\\":{\\\"value\\\":%s}}}\"," "1,0\r\n", ONENET_TOPIC_PUB, request_id++, value_str); ESP8266_SendCommand(cmd, "OK", 2000); // 2. 发送湿度 snprintf(value_str, sizeof(value_str), "%.1f", humi); sprintf(cmd, "AT+MQTTPUB=0,\"%s\"," "\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":" "{\\\"humidity\\\":{\\\"value\\\":%s}}}\"," "1,0\r\n", ONENET_TOPIC_PUB, request_id++, value_str); ESP8266_SendCommand(cmd, "OK", 2000); // 3. 发送LED状态 const char* led_value = led_status ? "true" : "false"; sprintf(cmd, "AT+MQTTPUB=0,\"%s\"," "\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":" "{\\\"led\\\":{\\\"value\\\":%s}}}\"," "1,0\r\n", ONENET_TOPIC_PUB, request_id++, led_value); ESP8266_SendCommand(cmd, "OK", 2000); // 4. 发送电机状态 sprintf(cmd, "AT+MQTTPUB=0,\"%s\"," "\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":" "{\\\"motor\\\":{\\\"value\\\":%d}}}\"," "1,0\r\n", ONENET_TOPIC_PUB, request_id++, motor_status); ESP8266_SendCommand(cmd, "OK", 2000); // 更新上传统计 uploadSuccessCount += 4; } uint8_t ESP8266_SendCommand(const char *cmd, const char *expected, uint32_t timeout) { ESP8266_Transmit(cmd); uint8_t result = ESP8266_WaitResponse(expected, timeout); // 增强错误处理 - 记录错误响应 if (!result) { // 使用串口直接输出错误信息(因为DebugPrint可能不可用) char errorMsg[128]; snprintf(errorMsg, sizeof(errorMsg), "CMD Error: %s\r\n", cmd); HAL_UART_Transmit(&huart3, (uint8_t *)errorMsg, strlen(errorMsg), HAL_MAX_DELAY); } return result; } static void ESP8266_Transmit(const char *data) { HAL_UART_Transmit(&huart3, (uint8_t *)data, strlen(data), HAL_MAX_DELAY); } static void ESP8266_Flush(void) { uint8_t dummy; while (HAL_UART_Receive(&huart3, &dummy, 1, 10) == HAL_OK) {} } static uint8_t ESP8266_WaitResponse(const char *expected, uint32_t timeout) { char response[256] = {0}; uint32_t start = HAL_GetTick(); uint8_t index = 0; uint8_t found = 0; while ((HAL_GetTick() - start) < timeout) { if (HAL_UART_Receive(&huart3, (uint8_t *)&response[index], 1, 10) == HAL_OK) { if (strstr(response, expected) != NULL) { found = 1; break; } if (strstr(response, "ERROR") != NULL || strstr(response, "FAIL") != NULL) { break; } if (index < sizeof(response) - 1) { index++; } else { memmove(response, response + 128, 128); index = 128; } } } return found; } void ESP8266_SendPing(void) { ESP8266_SendCommand("AT+MQTTPING=0\r\n", "OK", 1000); } void ESP8266_ProcessResponses(void) { static char response[512] = {0}; static uint8_t index = 0; uint8_t received; if (HAL_UART_Receive(&huart3, (uint8_t *)&received, 1, 0) == HAL_OK) { if (index < sizeof(response) - 1) { response[index++] = received; response[index] = '\0'; if (index >= 2 && response[index-2] == '\r' && response[index-1] == '\n') { response[index-2] = '\0'; // 检查连接状态消息 if (strstr(response, "WIFI GOT IP")) { wifiConnected = 1; } if (strstr(response, "+MQTTCONNECTED")) { oneNetConnected = 1; } if (strstr(response, "+MQTTDISCONNECTED")) { oneNetConnected = 0; } // 处理订阅的消息(使用新的命令主题) if (strstr(response, "+MQTTSUBRECV:") && strstr(response, "cmd/request")) { // 解析远程命令 ParseRemoteCommand(response); } index = 0; response[0] = '\0'; } } else { index = 0; response[0] = '\0'; } } } void ParseRemoteCommand(const char *message) { // 重置命令状态 remote_led_command = 0; remote_motor_command = 0; // 定义本地变量用于解析(修复未定义错误) char* led_ptr = NULL; char* motor_ptr = NULL; char received_command = 0; // 查找JSON消息体 char* msg_body = strstr(message, "\"body\":"); if (!msg_body) { // 尝试旧格式处理 led_ptr = strstr(message, "\"led\":"); if (led_ptr) { remote_led_command = (strstr(led_ptr, "true") || strstr(led_ptr, "1")) ? 1 : 0; } motor_ptr = strstr(message, "\"motor\":"); if (motor_ptr) { if (strstr(motor_ptr, "1")) { remote_motor_command = 1; } else if (strstr(motor_ptr, "2")) { remote_motor_command = 2; } } } else { // 新版JSON格式处理(带"body"结构) led_ptr = strstr(msg_body, "\"led\":"); if (led_ptr) { // 向前移动到值位置 char* value_start = strchr(led_ptr, ':') + 1; // 跳过空格 while (*value_start == ' ') value_start++; if (strncmp(value_start, "true", 4) == 0 || *value_start == '1') { remote_led_command = 1; } else if (strncmp(value_start, "false", 5) == 0 || *value_start == '0') { remote_led_command = 0; } } motor_ptr = strstr(msg_body, "\"motor\":"); if (motor_ptr) { // 向前移动到值位置 char* value_start = strchr(motor_ptr, ':') + 1; // 跳过空格 while (*value_start == ' ') value_start++; if (*value_start == '1') { remote_motor_command = 1; } else if (*value_start == '2') { remote_motor_command = 2; } else if (*value_start == '0') { remote_motor_command = 0; } } } // 检查是否接收到有效命令 if (led_ptr || motor_ptr) { new_remote_command = 1; received_command = 1; // 通过串口输出命令内容(因为DebugPrint可能不可用) char cmd_info[80]; snprintf(cmd_info, sizeof(cmd_info), "Received CMD: led=%d, motor=%d\r\n", remote_led_command, remote_motor_command); HAL_UART_Transmit(&huart3, (uint8_t *)cmd_info, strlen(cmd_info), HAL_MAX_DELAY); } // 检查平台属性设置响应 if (strstr(message, "SetProperty")) { // 通过串口输出属性设置响应 char response_msg[60]; snprintf(response_msg, sizeof(response_msg), "Property set: %s\r\n", strstr(message, "success") ? "Success" : "Failure"); HAL_UART_Transmit(&huart3, (uint8_t *)response_msg, strlen(response_msg), HAL_MAX_DELAY); } } 这是我现在的代码,还是报错1022,请检查哪里有错误
最新发布
06-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值