2

I want to send a int value (0-640) from Raspberry to Arduino via RX/TX serial port (not USB).

For the moment I receive the value on the Raspberry over UDP, therefore the received type is "class 'bytes' ". I am converting the bytes to int, encode it to a string and sends it to Arduino.

My problem is that it is extremely slow to convert from ASCII to int on Arduino side. Best case scenario would be, of course, to have something simple like:

Raspberry (dream scenario):

serial.write(data)

Arduino (dream scenario):

RPiMsg = Serial1.read();

Any suggestions? Questions?

My code so far:

Raspberry code:

import struct
import serial

serial = serial.Serial('/dev/ttyAMA0', 115200)

while True:
    # (This is here to show you where it comes from):
    data, addr = sock.recvfrom(4)

    if len(data)!=4:
        continue
    else:
        # Convert data to int
        msg = struct.unpack('i',data)[0]
        # Send to Arduino
        serial.write(str(msg).encode() + str('\n').encode())

Arduino code:

void setup()
{
  // Opens serial ports, sets data rate
  Serial1.begin(115200); // Serial1 = reads from Pi
}

void loop()
{
  if (Serial1.available())
  {
    // Resets RPiMsg
    RPiMsg = 0;

    // Read serial one byte at a time and convert ASCII to int
    while(true)
    {
      incomingByte = Serial1.read();

      // Exit while-loop, end of message
      if (incomingByte == '\n') break;

      // If nothing is in the buffer, Serial1.read() = -1
      if (incomingByte == -1) continue;

      // Shift 1 decimal place left
      RPiMsg *= 10;

      // Convert ASCII to int
      RPiMsg = ((incomingByte - 48) + RPiMsg);
    }

    Serial.println(RPiMsg);
  }
}
bac
  • 93
  • 1
  • 13
  • I think your code Looks pretty good! What is the actual Problem? – Thomas Sparber Dec 15 '15 at 13:49
  • My problem is that it is extremely slow to convert from ASCII to int on Arduino side. It comes in "chunks", maybe 10-20 messages at a time. Then a bit of delay and then another chunk. @ThomasSparber – bac Dec 15 '15 at 13:53
  • Maybe you Need to `flush` on the raspberry side? ...after calling write – Thomas Sparber Dec 15 '15 at 13:55
  • Are you sure the slow part is the conversion ? It shouldn't be. Anyway, I would send the data as 2 bytes per number instead and use them as is, no conversion `RPiMsg = (data1<<8) | data2;` – tglaria Dec 15 '15 at 13:58
  • aaaa, ok, My guess: the serial port is slow, so just send one number per time. Your Pi receives a message, send one number, wait for the arduino to be able to receive more and THEN send another. – tglaria Dec 15 '15 at 13:59
  • `serial.flushInput()` made no difference, are there other ways to `flush`? @ThomasSparber – bac Dec 15 '15 at 14:07
  • @bac On the raspberry side you Need to call `flushOutput()` because you are writing to the socket – Thomas Sparber Dec 15 '15 at 14:10
  • If I use `RPiMsg = Serial1.read();` instead of the ASCII to int conversion above, the Arduino serial monitor prints the values at the same speed as the terminal prints them from the Raspberry.. @tglaria – bac Dec 15 '15 at 14:10
  • `flushOutput()`, of course..lol! But it made no difference either. Are there similar ways to do on the Arduino side? @ThomasSparber – bac Dec 15 '15 at 14:13
  • @bac https://www.arduino.cc/en/Serial/Flush :-) – Thomas Sparber Dec 15 '15 at 14:14
  • Tried both `Serial1.setTimeout(1)` and `Serial1.flush()` = no difference, but realized that it says in the link for Flush that _"Waits for the transmission of **outgoing** serial data to complete."_ @ThomasSparber – bac Dec 15 '15 at 14:24
  • @bac About what delay are we actually talking about? What does extremely slow mean for you? – Thomas Sparber Dec 15 '15 at 14:27
  • It is seconds (~3s) between the chunks presented on the Arduino's serial monitor. @ThomasSparber – bac Dec 15 '15 at 14:35
  • @bac One Thing you can try is to print something before and after some data is sent/retrieved. So you can find out where your bottleneck is. – Thomas Sparber Dec 15 '15 at 14:37
  • Already printing on both sides (removed it in Raspberry code above), it has to be the ASCII conversion that causes this because if I use `RPiMsg = Serial1.read()` instead of the ASCII to int conversion above, the Arduino serial monitor prints the values at the same speed as the terminal prints them from the Raspberry. @ThomasSparber – bac Dec 15 '15 at 14:41
  • Why you double-convert int-ASCII(in RPi) and ASCII-int(in arduino)? Why not just send `data`variable to arduino? You are encode and decode, you can send directly bytes to arduino. I think... – jabujavi Dec 16 '15 at 08:23
  • Realized that too, over-worked it a little bit.. But `Serial1.read()` does only read one byte, i.e. >255. I want values from 0 up to 640. Looked at [this](http://stackoverflow.com/a/3539366/5470638) today, but gets random values on the Arduino side. @jabujavi – bac Dec 16 '15 at 08:28
  • REad one, shift 8 positions and add next byte.... You could have problem with little/big endian. I can't add anything now. If it's possible, i will review your question later – jabujavi Dec 16 '15 at 10:06
  • Any help appreciated, tried tglarias suggestion above with bit shifting but got the same result as my last comment: random values on the Arduino side. @jabujavi – bac Dec 16 '15 at 22:12
  • Possible duplicate of [Serial data transmission input-output delay with Raspberry Pi](http://stackoverflow.com/questions/37349685/serial-data-transmission-input-output-delay-with-raspberry-pi) – Paul Sweatte Nov 27 '16 at 00:09

0 Answers0