Go Down

Topic: Slow data transmission between two Arduinos  (Read 80 times) previous topic - next topic

notgwb

Nov 20, 2019, 01:14 am Last Edit: Nov 20, 2019, 01:23 am by notgwb
I'm having issues with quickly sending integer values from one Arduino to the other via serial. Both Arduinos are pretty much running the same software and using the same hardware configuration.

Each Arduino has a rotary encoder connected and the goal is to transmit the encoder's value when changed to the other Arduino via serial. It is also reading it's own connected encoder and prints its counter to console.

When reading it's own local encoder, printing to console is very quick and instantaneous. The problem is printing the received value from the other Arduino's encoder ; there is about a ~1 second delay from when the TX Arduino's encoder is turned until the RX prints it to console. I would like this to be almost or near instantaneous.

I've tried different baud rates and SPI and still see this delay. I believe the problem lies in the RX portion of the code- maybe something is not efficient as it can be. I've come to this conclusion by running the same code on one Arduino, but instead of sending the encoder value to another Arduino, I send it as a MIDI message and am able to see the result in instantaneously via a MIDI interface.

I've also tried this using Due to Due, Mega to Mega, Due to Teensy 3.6, Teensy to Due, Mega to Teensy, Teensy to Mega, so I believe the problem is an inefficiency with the RX portion of the code rather than speed


Any tips or insight is greatly appreciated!


I realize in the code below I'm reading the local encoder and storing it as a long and in the RX portion, its parsing an integer. Disregard this as the Arduino sending its encoder data is sending an integer, not a long

Code: [Select]

#include <Arduino.h>
#include <Wire.h>
#include <Encoder.h>
using namespace std;

Encoder myEnc(9, 10);



int val = 0;          /// SERIAL RX/TX VARS
int incoming = 0;     /// SERIAL RX/TX VARS

void setup()
{
  Serial.begin(9600);
  Serial1.begin(345600);    //Begin Serial to talk to TX Arduino
  
}

long position  = -999;

void loop()
{

  long newPos = myEnc.read();
  if (newPos != position)  ///Read encoder
  {
    position = newPos;
    Serial.print(position);   ///Print to console

    Serial1.print(position);  ////Send to other Arduino
    
  }
  
incoming = Serial1.available();
while (incoming != 0)                 //While there is something to be read
  {
    val = Serial1.parseInt();             //Reads integers as integer rather than ASCI. Anything else returns 0

    Serial.println("RX'd val: ");
    Serial.print(val);   ///Print RX'd int to console
    incoming = Serial1.available();    
  }

  
}

Klaus_K

There is a timeout in the Serial.parseInt() function. Because the serial cannot be sure whether it received all digits of the integer or not. You can reduce the timeout with the Serial.setTimeout() function.

"Parsing stops when no characters have been read for a configurable time-out value, or a non-digit is read"

So you might be able to send a "stop" character a letter for instance.


You can find the description in the Arduino reference.

https://www.arduino.cc/reference/en/language/functions/communication/serial/settimeout/


https://www.arduino.cc/reference/en/language/functions/communication/serial/parseint/

Power_Broker

#2
Nov 20, 2019, 02:27 am Last Edit: Nov 20, 2019, 02:28 am by Power_Broker
You can use this serial transfer library to very quickly and reliably transfer up to 255 bytes of data per packet - plenty enough to send an int_16 or int_32.

I use the library myself for sending commands to my Arduino RC plane and to send telemetry data back to the hand controller with a refresh rate of about 50Hz (rate not limited by the serial transfer, its due to my on-board LiDAR sensor).

Give the library a shot
"The desire that guides me in all I do is the desire to harness the forces of nature to the service of mankind."
   - Nikola Tesla

notgwb

You can use this serial transfer library to very quickly and reliably transfer up to 255 bytes of data per packet - plenty enough to send an int_16 or int_32.

I use the library myself for sending commands to my Arduino RC plane and to send telemetry data back to the hand controller with a refresh rate of about 50Hz (rate not limited by the serial transfer, its due to my on-board LiDAR sensor).

Give the library a shot
Awesome that sounds exactly what I'm looking for thanks for the tip!

notgwb

There is a timeout in the Serial.parseInt() function. Because the serial cannot be sure whether it received all digits of the integer or not. You can reduce the timeout with the Serial.setTimeout() function.

"Parsing stops when no characters have been read for a configurable time-out value, or a non-digit is read"

So you might be able to send a "stop" character a letter for instance.


You can find the description in the Arduino reference.

https://www.arduino.cc/reference/en/language/functions/communication/serial/settimeout/


https://www.arduino.cc/reference/en/language/functions/communication/serial/parseint/
I noticed examples that used delimiters while I was researching earlier but didnt make that connection.. thanks for the tip

Go Up