1
0
Fork 0

firmware: decode png frames

main
radex 2024-03-23 23:08:14 +01:00
parent 0c4d2510d2
commit 35b77b7446
Signed by: radex
SSH Key Fingerprint: SHA256:hvqRXAGG1h89yqnS+cyFTLKQbzjWD4uXIqw7Y+0ws30
4 changed files with 58 additions and 68 deletions

1
firmware/.gitignore vendored
View File

@ -4,3 +4,4 @@
.vscode/launch.json
.vscode/ipch
src/gfx_png.h
gfx/

13
firmware/README.md Normal file
View File

@ -0,0 +1,13 @@
**add graphics**
convert video
```
ffmpeg -i badapple.webm -ss 00:01:00 -t 30 -vf "fps=30,scale=20:20:force_original_aspect_ratio=increase,crop=20:20,format=gray" badapple-frames/badapple_%04d.png
```
move to `gfx` folder, then:
```
python3 scripts/gfx_convert.py
```

View File

@ -7,7 +7,7 @@ from PIL import Image
def get_all_gfx():
gfx = []
for root, dirs, files in os.walk("gfx-badapple"):
for root, dirs, files in os.walk("gfx"):
for file in files:
if file.startswith("."):
continue
@ -59,10 +59,12 @@ def png_to_code(name, path):
data = file.read()
size = len(data)
code = f"uint8_t png_{name}[{size}] = {'{'}"
code = f"static const uint8_t png_{name}[{size}] = {'{'}"
for i in range(size):
code += f"0x{data[i]:02x},"
code += "};\n\n"
code += "};\n"
code += f"#define PNG_SIZE_{name} {size}\n\n"
return code
def generate_png_gfx():
@ -71,20 +73,26 @@ def generate_png_gfx():
header = f"#pragma once\n#include <Arduino.h>\n\n/* DO NOT MODIFY - AUTOGENERATED! */\n\n"
index = f"uint8_t* png_frames[{len(gfx)}] = {'{'}\n"
index = f"static const uint8_t* png_frames[{len(gfx)}] = {'{'}"
for name, _ in gfx:
index += f" png_{name},\n"
index += "};\n"
index += f"png_{name},"
index += "};\n\n"
size_index = f"size_t png_frame_sizes[{len(gfx)}] = {'{'}"
for name, _ in gfx:
size_index += f"PNG_SIZE_{name},"
size_index += "};\n"
with open("src/gfx_png.h", "w") as f:
f.write(header)
f.write("#define PNG_COUNT " + str(len(gfx)) + "\n\n")
f.write(gfx_code)
f.write(index)
f.write(size_index)
print("gfx_png.h generated!")
if __name__ == "__main__":
generate_gfx()
# generate_gfx()
generate_png_gfx()

View File

@ -1,5 +1,4 @@
#include <Arduino.h>
#include "gfx.h"
#include "gfx_png.h"
#include "lodepng.h"
@ -18,49 +17,11 @@
#define ROW_COUNT 20 //24
#define COL_COUNT 20 //21
uint8_t frameIndex = 0;
#define MS_PER_FRAME 33
uint16_t frameIndex = 0;
unsigned long frameLastChangedAt;
#define MS_PER_FRAME 200
void printOut() {
Serial.println("------");
Serial.println("Row:");
Serial.print("SER: ");
Serial.println(digitalRead(ROW_SER));
Serial.print("OE_N: ");
Serial.println(digitalRead(ROW_OE));
Serial.print("RCLK: ");
Serial.println(digitalRead(ROW_RCLK));
Serial.print("SRCLK: ");
Serial.println(digitalRead(ROW_SRCLK));
Serial.print("SRCLR_N: ");
Serial.println(digitalRead(ROW_SRCLR));
Serial.println("------");
Serial.println("Col:");
Serial.print("SER: ");
Serial.println(digitalRead(COL_SER));
Serial.print("OE_N: ");
Serial.println(digitalRead(COL_OE));
Serial.print("RCLK: ");
Serial.println(digitalRead(COL_RCLK));
Serial.print("SRCLK: ");
Serial.println(digitalRead(COL_SRCLK));
Serial.print("SRCLR_N: ");
Serial.println(digitalRead(COL_SRCLR));
}
void setup() {
Serial.begin(9600);
Serial.println("Hello");
@ -104,32 +65,34 @@ void setup() {
// clear frames
frameIndex = 0;
frameLastChangedAt = millis();
}
delay(1500);
Serial.println("Decoding PNG...");
void loop() {
auto b4 = millis();
unsigned error;
unsigned char *buffer = 0;
unsigned width, height;
lodepng_decode_memory(&buffer, &width, &height, png_badapple_001, sizeof(png_badapple_001), LCT_GREY, 8);
const uint8_t *png = png_frames[frameIndex];
size_t pngSize = png_frame_sizes[frameIndex];
error = lodepng_decode_memory(&buffer, &width, &height, png, pngSize, LCT_GREY, 8);
if (error) {
Serial.print("PNG decode error ");
Serial.print(error);
Serial.print(": ");
Serial.println(lodepng_error_text(error));
return;
} else if (width != COL_COUNT || height != ROW_COUNT) {
Serial.println("Invalid frame size");
return;
}
Serial.print("Decoded in ");
Serial.print(millis() - b4);
Serial.println("ms");
Serial.println(width);
Serial.println(height);
}
void loop() {
char c = Serial.read();
if (c == 'o') {
printOut();
}
uint32_t *frame = frames[frameIndex];
// clear columns
digitalWrite(COL_SRCLR, LOW);
digitalWrite(COL_SRCLK, HIGH);
@ -160,7 +123,7 @@ void loop() {
// set column with rows' data
for (int y = 0; y < ROW_COUNT; y++) {
// get value
bool pxValue = frame[ROW_COUNT - 1 - y] & (1 << ((COL_COUNT - 1) - x));
uint8_t pxValue = buffer[y * COL_COUNT + x] > 128 ? 1 : 0;
digitalWrite(ROW_SER, pxValue);
// push value
digitalWrite(ROW_SRCLK, HIGH);
@ -178,12 +141,17 @@ void loop() {
digitalWrite(ROW_OE, LOW);
}
free(buffer);
// next frame
if (millis() - frameLastChangedAt > MS_PER_FRAME) {
frameLastChangedAt = millis();
frameIndex++;
if (frameIndex == GFX_COUNT) {
Serial.print("Going to frame ");
Serial.println(frameIndex);
if (frameIndex == PNG_COUNT) {
frameIndex = 0;
Serial.println("Loop over!");
}
}
}