Bluno Beetle V1.1 BLE数据实时串口输出实现方案咨询
问题原因
你的代码里使用了Serial.readStringUntil('\n'),这个函数会阻塞等待直到收到换行符才返回完整字符串,同时多余的Serial.read()还会丢掉第一个字符。这就导致只有整行命令(带换行)全部发送完成后,代码才会读取并输出数据,表现为批量输出。
解决方案
要实现数据一接收就立即输出,需要改成逐字符非阻塞读取:每收到一个字符就立刻输出到串口,同时逐步拼接命令字符串,直到遇到换行再执行对应命令逻辑。
修改后的完整代码
#include <Adafruit_NeoPixel.h> #include <Servo.h> int estPin = 5; int servoPin = 2; int pixelPin = 3; int pixelNum = 1; Servo servo; Servo esc; String command; int color[3] = {150, 0, 0}; Adafruit_NeoPixel pixels(pixelNum, pixelPin, NEO_GRB + NEO_KHZ800); void setup() { pixels.begin(); Serial.begin(115200); servo.attach(servoPin); esc.attach(estPin); delay(7000); } void loop() { // 循环读取所有可用字符 while (Serial.available()) { char receivedChar = Serial.read(); // 收到字符后立即输出到串口 Serial.print(receivedChar); if (receivedChar == '\n') { // 遇到换行符,处理完整命令 processCommand(command); command.clear(); // 清空缓冲区,准备接收下一条命令 } else { // 拼接字符到命令字符串 command += receivedChar; } } } // 封装命令处理逻辑 void processCommand(String cmd) { if (cmd.length() >= 3) { String code = cmd.substring(0,3); if(code == "rgb") { String rgb = cmd.substring(3); String c[3]; int index = 0; for (int i=0;i<3;i++){ index = rgb.indexOf(' '); c[i] = rgb.substring(0, index); rgb = rgb.substring(index+1); color[i] = c[i].toInt(); } pixels.clear(); for(int i=0; i<pixelNum; i++) { pixels.setPixelColor(i, pixels.Color(color[0], color[1], color[2])); pixels.show(); } } else if(code == "srv") { String value = cmd.substring(3,6); servo.write(value.toInt()); Serial.println(value); } else if(code == "mtr") { String Svalue = cmd.substring(3,6); int value = Svalue.toInt(); value = map(value, 0, 100, 1100, 1900); esc.writeMicroseconds(value); Serial.println(value); } } }
关键修改点
- 移除多余的
Serial.read():避免丢失第一个收到的字符。 - 逐字符实时输出:用
while(Serial.available())循环读取每个字符,读取后立刻调用Serial.print(receivedChar)输出。 - 拆分命令处理逻辑:把命令解析代码封装成
processCommand函数,仅当收到换行符时才处理完整命令,保证命令解析的正确性。 - 非阻塞逻辑:不再等待整行数据,实时处理每个字符,实现数据即时输出。
内容的提问来源于stack exchange,提问作者NewUser69420
相关产品推荐
相关产品推荐

