简体   繁体   中英

Serial Read - Arduino - DELAY

I am a new programmer, so I am having a bit of problem with Serial communication of Arduino.

I am trying to read data from serial Input, sent by a simulation as characters and I need to store it as integer to write it with my servo.

I found this https://forum.arduino.cc/t/serial-input-basics-updated/382007 tutorial and example 4 does the job,

However, the simulation sends the data so fast that Arduino bottlenecks and the data pile up in the serial port and even if I stop the simulation the Arduino continues to perform the messages.

How can I slow down the data receiving like read data every 0.3 seconds instead. I tried to put some delays but it seems like it doesn't work.

Also, how can I change the code in a way that it stops performing new thing when there is no new serial messages and cancel the ones in the queue?

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;
    }
}

Thanks!

Welcome to the forum. I'll admit that I don't know about your arduino set-up, but I hope that I can help.

Serial ports are asynchronous sources of data. For base 3 wire RS-232, the receiver can't control the speed at which data is received other than baud rate hence received data is copied into a buffer (array) before it is processed.

This is to give your code time to process the received data before more messages arrive and cause what is known as a buffer overrun, corrupting data already received. Think of the serial link as being a hose pipe filling a bucket (the buffer) with water and you emptying it using a cup (your processing).

If your processing code is running too slowly and you are losing data then one option is to increase the size of the reception buffer, say from 32 to 255.

Adding delays to the reception code will only make matters worse.

An important point to make is that you must ensure that any processed data is removed from the buffer otherwise it will be processed again.

If your processing is fast enough then a nasty method is to just clear the buffer of all data by setting all array values to 0.

Another method is to use is keep a records (index value) of the next available location to write to and read from.

Data from the serial port is written into the buffer address using the write index value saved previously as a starting point. It is updated to take into account the size of the data written and incremented to indicate where to start the next write operation.

Your processing reads from the buffer using the last read index until it detects your end of message indicator and increments the read index to indicate the next location to read from.

It may be that your arduino serial port supports hardware flow control raising a Ready To Receive line when the hardware buffer (in the serial port itself) is full. This would be set before you open it.

Code:

  1. Remove Delay calls - they only slow down your code.
  2. Sending data out Serial.print , Serial.println commands take time, place those after myservo.write
  3. Remove Serial.print type commands that aren't strictly necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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