Good day, Fellas.
I have a python application that sends 2068 bytes of image RGB data over serial to an ESP32, which is supposed to receive it and push the data to the LED strip. Think of a crude pixel art image display.
For the time being I'm just sending flat color values but the final intention is to open a 25x24px resolution video, rip the frames, break the pixels down into raw rgb values and send over serial to esp32 to display.
Python application:
import serial
import time
import cv2
ser = serial.Serial('COM3', 921600, timeout=1, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE)
time.sleep(0.2)
# create packet of data
packet = bytearray()
packet.append(0b00000001) # first byte to be read by controller, determines type operation
vfile = cv2.VideoCapture("test_video.mp4")
ret, frame = vfile.read()
for x in range(27):
for y in range(26):
if x % 2 == 1 and y == 0: continue # skip the firt pixel of every odd row
# packet.append(int(frame[y,x,2]))
# packet.append(int(frame[y,x,1]))
# packet.append(int(frame[y,x,0]))
packet.append(255) # test by sending white
packet.append(255)
packet.append(255)
# print(x,":",y, " rgb: ",frame[y,x,2],frame[y,x,1],frame[y,x,0])
ser.write(packet)
print(packet)
print(len(packet), " written")
input("press any to quit, this will reset controller")
#cv2.imwrite("frame_test.jpg", frame)
vfile.release()
ESP32 Arduino Application.
#include "ESP32_WS2812_Lib.h"
#define LEDS_COUNT 689
#define LEDS_PIN 17
#define CHANNEL 0
ESP32_WS2812 strip = ESP32_WS2812(LEDS_COUNT, LEDS_PIN, CHANNEL, TYPE_GRB);
uint16_t led_id = 0;
void setup() {
Serial.begin(921600);
pinMode(LED_BUILTIN, OUTPUT); // test led
digitalWrite(LED_BUILTIN, 0);
while (!Serial) {
Serial.println("waiting for serial");
}
Serial.println("serial running");
Serial.setRxBufferSize(2100); // set serial buffer size
strip.begin();
strip.setBrightness(30);
for (int i = 0; i < LEDS_COUNT; i++) { // clear all leds
strip.setLedColorData(i, 0, 0, 0);
}
strip.show();
}
void loop() {
if (Serial.available() > 0) {
uint8_t cmd_byte = Serial.read(); // read command byte to determine type of operation
if (cmd_byte == 0b00000001){ // if this is a 25x24 image data stream
//delay(10);
digitalWrite(LED_BUILTIN, 1); // show that commad of 0x01 was detected
led_id = 0; // reset led index to start applying from the beginning.
// enter loop and stay in this state until all data is transfered
while(true){
if (Serial.available() > 3){
delay(10);
uint8_t r = Serial.read();
uint8_t g = Serial.read();
uint8_t b = Serial.read();
strip.setLedColorData(led_id, r, g, b);
led_id += 1;
strip.show(); // for testing purposes each image is shown
if (led_id == 688){ // check if last led was set
// !!!!!!! never reaches this
break; // Consider all data received
}
} // end of if serial has 3 bytes
} // end of while loop
} // end of if cmd == 0x01
} // end of is serial available
}
I have noted a couple of peculiar behaviors:
- The esp stops reading serial data once it reaches around 720-ish bytes but it's not consistent. Could be more, could be less by a margin of anywhere between a 3 to 30 or more bytes.
When I send one color set to 255 while others are 0, it seems to be reading the data out of order because it just toggles primary colors?
I have included the mp4 file that the python app is requesting as the loops are based on it's dimensions.
test_video.zip (2.2 KB)