Hello,
I wondered if anyone could give me some help on why my serial performance is very slow. I have an Arduino driving an LED matrix, receiving data from a Raspberry Pi using Python and pyserial. The serial data is sent over a USB cable plugged between the Pi and Arduino.
A sketch on the Arduino listens for bytes, one control byte, then 1536 pixel data bytes. (The LED matrix is 1024 RGB pixels at 4 bit colour. I pack two 4 bit values into each byte, so each RGB pixel is 1.5 bytes. Therefore an entire frame is sent in 1024 pixels x 1.5 bytes per pixel = 1536 bytes.)
If my maths is right... Running at 115200 baud, I make that roughly 14400bytes/s - enough that I should see a maximum of 9 frames per second. However I'm only seeing roughly two frames per second. Even at 230400 baud things are 2 or 3 fps.
Any ideas appreciated!
Here is the Python send code:
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
loop=0
while (loop < 100):
#draw totally white frame (all bytes value 11111111)
#send control byte: 1 = draw frame
ser.write(chr(1))
#send screen data - 2 pixels sent in 3 bytes. 1024 pixels in total = 512 loops of 3 bytes (1536 bytes total)
c=0
while (c < 512):
ser.write(chr(255))
ser.write(chr(255))
ser.write(chr(255))
c=c+1
#draw totally black frame (all bytes value 00000000)
#send control byte: 1 = draw frame
ser.write(chr(1))
#send screen data - 2 pixels sent over 3 bytes. 1024 pixels in total = 512 loops of 3 bytes (1536 bytes total)
c=0
while (c < 512):
ser.write(chr(255))
ser.write(chr(255))
ser.write(chr(255))
c=c+1
loop=loop+1
And here is the Arduino receive code.
#include "RGBmatrixPanel.h" //3rd party matrix driver
//define pins
#define A 5
#define B 4
#define C 3
#define D 2
#define CLK 10
#define LAT 9
#define OE 7
RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, true);
void setup() {
Serial.begin(230400);
matrix.begin();
}
void loop() {
byte incomingByte = 0;
if (Serial.available() > 0) { //if > 1 get 1st byte which is control byte
incomingByte = Serial.read();
//if control byte is 1, draw frame
switch ( int(incomingByte) ) {
case 1:
drawScreen();
break;
default:
Serial.println("unknown cmd");
}
}
}
void drawScreen() {
//Total bytes to receive is 1536
byte x = 0;
byte y = 0;
byte r = 0;
byte g = 0;
byte b = 0;
byte data = 0;
while (y < 32 ) {
if (Serial.available() >= 3) { //read 3 bytes (2 pixels)
//read 1st byte and split into nibbles
data = byte (Serial.read());
r = data & B00001111;
g = data >> 4;
//read 2nd byte and split into nibbles
data = byte (Serial.read());
b = data & B00001111;
//draw pixel1
matrix.drawPixel(x, y, matrix.Color444(r,g,b));
//next pixel
x++;
r = data >> 4;
//read 3rd byte and split into nibbles
data = byte (Serial.read());
g = data & B00001111;
b = data >> 4;
//draw pixel2
matrix.drawPixel(x, y, matrix.Color444(r,g,b));
//next pixel
if (x == 31){
x=0;
y++;
}
else {
x++;
}
}
}
matrix.swapBuffers(false);
}