Files
pictureFrame/firmware/src/main.cpp
T
football2801 01274f5cb7 chore: restructure firmware into subdirectory, add DDEV config
Move firmware files from repo root src/ into firmware/ to avoid
collision with Symfony's src/ PHP class directory. Add DDEV
config targeting PHP 8.4 / PostgreSQL 16 / nginx-fpm with
Imagick extension via docker-compose override.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 22:51:19 -04:00

120 lines
3.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <Arduino.h>
#include <SPI.h>
#include "image.h"
#define EPD_WIDTH 800
#define EPD_HEIGHT 480
#define IMG_W 480 // portrait image dimensions
#define IMG_H 800
#define PIN_SCK 18
#define PIN_MOSI 23
#define PIN_CS 5
#define PIN_DC 17
#define PIN_RST 16
#define PIN_BUSY 4
static uint8_t row_buf[EPD_WIDTH / 2];
void wait_busy() { while (digitalRead(PIN_BUSY) == LOW) delay(5); }
void send_command(uint8_t cmd) {
digitalWrite(PIN_DC, LOW);
digitalWrite(PIN_CS, LOW);
SPI.transfer(cmd);
digitalWrite(PIN_CS, HIGH);
}
void send_data(uint8_t data) {
digitalWrite(PIN_DC, HIGH);
digitalWrite(PIN_CS, LOW);
SPI.transfer(data);
digitalWrite(PIN_CS, HIGH);
}
void epd_reset() {
digitalWrite(PIN_RST, HIGH); delay(20);
digitalWrite(PIN_RST, LOW); delay(2);
digitalWrite(PIN_RST, HIGH); delay(20);
}
void epd_init() {
epd_reset();
wait_busy();
delay(30);
send_command(0xAA);
send_data(0x49); send_data(0x55); send_data(0x20);
send_data(0x08); send_data(0x09); send_data(0x18);
send_command(0x01); send_data(0x3F);
send_command(0x00); send_data(0x5F); send_data(0x69);
send_command(0x03);
send_data(0x00); send_data(0x54); send_data(0x00); send_data(0x44);
send_command(0x05);
send_data(0x40); send_data(0x1F); send_data(0x1F); send_data(0x2C);
send_command(0x06);
send_data(0x6F); send_data(0x1F); send_data(0x17); send_data(0x49);
send_command(0x08);
send_data(0x6F); send_data(0x1F); send_data(0x1F); send_data(0x22);
send_command(0x30); send_data(0x03);
send_command(0x50); send_data(0x3F);
send_command(0x60); send_data(0x02); send_data(0x00);
send_command(0x61);
send_data(0x03); send_data(0x20); send_data(0x01); send_data(0xE0);
send_command(0x84); send_data(0x01);
send_command(0xE3); send_data(0x2F);
send_command(0x04);
wait_busy();
}
void epd_sleep() {
send_command(0x02); send_data(0x00); wait_busy();
send_command(0x07); send_data(0xA5);
}
void show_image() {
send_command(0x10);
digitalWrite(PIN_DC, HIGH);
digitalWrite(PIN_CS, LOW);
// 90° CW rotation: display(x,y) → portrait(IMG_W-1-y, x)
// Portrait image is IMG_W×IMG_H, IMAGE_ROW = IMG_W/2 bytes per portrait row.
for (int y = 0; y < EPD_HEIGHT; y++) {
int pcol = (IMG_W - 1) - y;
for (int x = 0; x < EPD_WIDTH; x++) {
uint32_t bidx = (uint32_t)x * IMAGE_ROW + pcol / 2;
uint8_t b = pgm_read_byte(&IMAGE_DATA[bidx]);
uint8_t code = (pcol & 1) ? (b & 0x0F) : (b >> 4);
if (x & 1)
row_buf[x / 2] = (row_buf[x / 2] & 0xF0) | code;
else
row_buf[x / 2] = (code << 4) | (row_buf[x / 2] & 0x0F);
}
SPI.writeBytes(row_buf, sizeof(row_buf));
}
digitalWrite(PIN_CS, HIGH);
send_command(0x04); wait_busy();
send_command(0x12); send_data(0x00); wait_busy();
}
void setup() {
Serial.begin(115200);
Serial.println("pictureFrame");
pinMode(PIN_CS, OUTPUT);
pinMode(PIN_DC, OUTPUT);
pinMode(PIN_RST, OUTPUT);
pinMode(PIN_BUSY, INPUT);
SPI.begin(PIN_SCK, -1, PIN_MOSI, PIN_CS);
SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
epd_init();
show_image();
epd_sleep();
Serial.println("Done.");
}
void loop() {
delay(60000);
}