Serial Read - Arduino - DELAY



我是一名新程序员,所以我对Arduino的串行通信有一点问题。

我正试图从串行输入读取数据,由模拟作为字符发送,我需要将其存储为整数,以便与伺服一起写入。

我发现这个https://forum.arduino.cc/t/serial-input-basics-updated/382007教程和示例4可以完成这项工作,

然而,模拟发送数据的速度如此之快,以至于Arduino瓶颈和数据堆积在串行端口中,即使我停止模拟,Arduino也会继续执行消息。

如何降低数据接收速度,比如每0.3秒读取一次数据。我试着延迟一些时间,但似乎行不通。

另外,我如何改变代码的方式,它停止执行新的东西时,没有新的串行消息和取消队列中的那些?

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
boolean newData = false;
//SERVO//
#include <Servo.h>
Servo myservo;  // create servo object to control a servo
////////////////////////
int dataNumber = 0;             // new for this version
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
myservo.attach(9);  // attaches the servo on pin 9 to the servo object
Serial.println("<Arduino is ready>");
}
void loop() {
recvWithEndMarker();
showNewNumber();
}
void recvWithEndMarker() {
static byte ndx = 0;
char endMarker = 'n';
char rc;

if (Serial.available()> 0)  {
rc = Serial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = ''; // terminate the string
ndx = 0;
newData = true;
delay(1);
}
}
}
void showNewNumber() {
if (newData == true) {
dataNumber = 0;             // new for this version
dataNumber = atoi(receivedChars);   // new for this version
Serial.print("This just in ... ");
Serial.println(receivedChars);
Serial.print("Data as Number ... ");    // new for this version
Serial.println(dataNumber);     // new for this version
myservo.write(dataNumber);                  // sets the servo position according to the scaled value
delay(50);
newData = false;
}
}

谢谢!

欢迎来到论坛。我承认我不了解你的arduino设置,但我希望我能帮助你。

串口是异步数据源。对于基本3线RS-232,接收器不能控制除波特率以外的数据接收速度,因此接收到的数据在处理之前被复制到缓冲区(数组)中。

这是为了给你的代码时间来处理接收到的数据之前更多的消息到达,并导致所谓的缓冲区溢出,破坏已经接收到的数据。可以把串行链接想象成一个软管,向桶(缓冲区)注水,然后用杯子(处理)将其清空。

如果你的处理代码运行得太慢,你正在丢失数据,那么一个选择是增加接收缓冲区的大小,比如从32到255。

在接收代码中增加延迟只会让事情变得更糟。

需要说明的重要一点是,必须确保所有处理过的数据都从缓冲区中删除,否则将再次处理。

如果你的处理足够快,那么一个糟糕的方法就是通过将所有数组值设置为0来清除缓冲区中的所有数据。

另一种方法是保存下一个可用的写入和读取位置的记录(索引值)。

来自串行端口的数据使用先前保存的写索引值作为起始点写入缓冲区地址。它被更新以考虑写入数据的大小,并递增以指示从哪里开始下一个写入操作。

您的处理使用最后一个读索引从缓冲区读取,直到它检测到消息结束指示符并增加读索引以指示下一个要读取的位置。

可能是您的arduino串行端口支持硬件流控制,当硬件缓冲区(在串行端口本身)已满时引发Ready To Receive行。这将在您打开它之前设置。

代码:

  1. 删除Delay调用-它们只会减慢你的代码。
  2. 发送Serial.print,Serial.println命令需要时间,将放在之后myservo.write
  3. 删除不需要的Serial.print类型命令。

最新更新