Go Down

Topic: Poor serial performance when sending data from RaspberryPi to Arduino (Read 7 times) previous topic - next topic

Papa G

You didn't mention it so I want to make sure, did you modify /etc/inittab and /boot/cmdline.txt to prevent other processes using /dev/ttyAMA0?
edit: sorry, I see you're using a USB port. Never mind.

Papa G

robtillaart's suggestions are good, but may I make a few more?

The Serial class only takes strings and buffers as input. Strings, like tuples, are immutable, so building arbitrary data packets would be done by concatenation rather than insertion. A bytearray might make more sense as you can write to indices and slices of a bytearray and Serial treats it like a buffer.

I added the concept of bytearrays to your code:

Code: [Select]
import serial
from time import sleep



#setup serial port
port = "/dev/ttyACM0"
ser = serial.Serial(port, 230400, timeout=1)
sleep(1) #wait for serial

#fill screen with white then black

for l in range(100): #draw totally white frame (all bytes value 11111111)
    ser.write("\x01")   #send control byte: 1 = draw frame
   
                         #send screen data - 2 pixels sent in 3 bytes.
                        #1024 pixels in total = 512 loops of 3 bytes (1536 bytes total)
    white = bytearray([255, 255, 255])
    for c in range(512):
        ser.write(white)

                          #draw totally black frame (all bytes value 00000000)
    ser.write("\x01")    #send control byte: 1 = draw frame
   
                          #send screen data - 2 pixels sent over 3 bytes.
                         #1024 pixels in total = 512 loops of 3 bytes (1536 bytes total)
    black = bytearray([0, 0, 0])
    for c in range(512):
        ser.write(black)


Then, to create a custom packet like robtillaart suggested:
Code: [Select]
h = 1 #packet header
x = 0x13 #x coordinate
y = 0x2f #y coordinate
r = 0xc #red value
g = 0x4 #green value
b = 0xe #blue value
packet = bytearray([h, x, y, r, g, b]) #build packet

packet[3:6] = [12, 10, 3] #write new r, g, b values



Grumpy_Mike

The serial data rate is not maintained when going through a USB converter. The USB transfers data in batches or frames.
Also try upping the thread priority in the python code to give it more time before Linux steals some.

mrnick1234567

Thanks for all the suggestions Rob and PapaG... implementing a packet structure seems like a nice way to go.

Mike, I'll try upping the priority and see how it goes.

At the moment running functions that plot LED by LED in a packet of (x,y,r,g,b) seem to overwhelm the Arduino's serial buffer more often than not. Sending an ACK per frame slows things down too much. E.g. when plotting 100 LED's (less than 1/4 the screen) with an ACK per packet it drops the frame rate to 3 or 4 frames per second. Not sure the best way around this. I think I might try and set up something that sends a 'pause' command if the buffer get's near 128bytes full.





Grumpy_Mike

Quote
I think I might try and set up something that sends a 'pause' command if the buffer get's near 128bytes full.

That is known as Xon / Xoff handshaking.

Go Up