#include #include #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); }