繁体   English   中英

串行读取 - Arduino - 延迟

[英]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] = '\0'; // 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 串行端口支持硬件流控制,当硬件缓冲区(在串行端口本身中)已满时提高准备接收线。 这将在您打开它之前设置。

代码:

  1. 删除Delay调用——它们只会减慢你的代码。
  2. 发送数据Serial.printSerial.println命令需要时间,放在myservo.write之后
  3. 删除并非绝对必要的Serial.print类型命令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM