Created
January 24, 2026 17:43
-
-
Save jborichevskiy/230f06b84e78b51b136eb9fdcb0e47b6 to your computer and use it in GitHub Desktop.
SE1330NG08-MNG-A0 ESP32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // prints "HI!" - inverts colors on every reset | |
| // for a 13.3 in 2 color e-ink SE1330NG08-MNG-A0 panel | |
| // for use with an SESTM32S01-A driver | |
| // thank you Claude for figuring this one out | |
| #include <SPI.h> | |
| #include <Preferences.h> | |
| #define PIN_BUSY 18 | |
| #define PIN_RES 17 | |
| #define PIN_DC 16 | |
| #define PIN_CS 15 | |
| #define PIN_SCL 7 | |
| #define PIN_SDA 6 | |
| #define WIDTH 960 | |
| #define HEIGHT 680 | |
| #define BYTES_PER_LINE 120 | |
| uint8_t frameBuffer[81600]; | |
| Preferences prefs; | |
| void setup() { | |
| Serial.begin(115200); | |
| delay(2000); | |
| Serial.println("\n=== HI TOGGLE TEST ===\n"); | |
| // Load toggle state from flash | |
| prefs.begin("epaper", false); | |
| bool inverted = prefs.getBool("inverted", false); | |
| Serial.print("Current state: "); | |
| Serial.println(inverted ? "INVERTED" : "NORMAL"); | |
| // Save opposite for next time | |
| prefs.putBool("inverted", !inverted); | |
| prefs.end(); | |
| pinMode(PIN_BUSY, INPUT); | |
| pinMode(PIN_RES, OUTPUT); | |
| pinMode(PIN_DC, OUTPUT); | |
| pinMode(PIN_CS, OUTPUT); | |
| digitalWrite(PIN_CS, HIGH); | |
| digitalWrite(PIN_RES, HIGH); | |
| SPI.begin(PIN_SCL, -1, PIN_SDA, PIN_CS); | |
| SPI.setFrequency(4000000); | |
| initDisplay(); | |
| // Set background and foreground based on inverted state | |
| uint8_t bg = inverted ? 0x00 : 0xFF; // Background | |
| uint8_t fg = inverted ? 0xFF : 0x00; // Foreground (letters) | |
| // Clear to background | |
| memset(frameBuffer, bg, sizeof(frameBuffer)); | |
| // Draw "HI!" | |
| Serial.println("Drawing HI..."); | |
| int startX = 100; | |
| int startY = 200; | |
| int letterW = 120; | |
| int letterH = 280; | |
| int thick = 40; | |
| int gap = 40; | |
| // H | |
| fillRect(startX, startY, thick, letterH, fg); | |
| fillRect(startX + letterW - thick, startY, thick, letterH, fg); | |
| fillRect(startX, startY + letterH/2 - thick/2, letterW, thick, fg); | |
| // I | |
| int iX = startX + letterW + gap; | |
| fillRect(iX, startY, letterW, thick, fg); | |
| fillRect(iX + letterW/2 - thick/2, startY, thick, letterH, fg); | |
| fillRect(iX, startY + letterH - thick, letterW, thick, fg); | |
| // ! | |
| int exX = iX + letterW + gap; | |
| fillRect(exX + letterW/2 - thick/2, startY, thick, letterH - 80, fg); | |
| fillRect(exX + letterW/2 - thick/2, startY + letterH - 50, thick, 50, fg); | |
| // Send to display | |
| Serial.println("Sending to display..."); | |
| sendFrameBuffer(); | |
| refresh(); | |
| Serial.println("\n=== DONE - Press reset to toggle ==="); | |
| } | |
| void loop() { | |
| delay(5000); | |
| } | |
| void fillRect(int x, int y, int w, int h, uint8_t color) { | |
| for (int py = y; py < y + h && py < HEIGHT; py++) { | |
| for (int px = x; px < x + w && px < WIDTH; px++) { | |
| if (px >= 0 && py >= 0) { | |
| int byteIndex = py * BYTES_PER_LINE + (px / 8); | |
| int bitIndex = 7 - (px % 8); | |
| if (color == 0x00) { | |
| frameBuffer[byteIndex] &= ~(1 << bitIndex); // Black | |
| } else { | |
| frameBuffer[byteIndex] |= (1 << bitIndex); // White | |
| } | |
| } | |
| } | |
| } | |
| } | |
| void sendFrameBuffer() { | |
| sendCmd(0x4E); | |
| sendData(0x00); | |
| sendData(0x00); | |
| sendCmd(0x4F); | |
| sendData(0x00); | |
| sendData(0x00); | |
| sendCmd(0x24); | |
| digitalWrite(PIN_DC, HIGH); | |
| digitalWrite(PIN_CS, LOW); | |
| for (uint32_t i = 0; i < 81600; i++) { | |
| SPI.transfer(frameBuffer[i]); | |
| } | |
| digitalWrite(PIN_CS, HIGH); | |
| sendCmd(0x4E); | |
| sendData(0x00); | |
| sendData(0x00); | |
| sendCmd(0x4F); | |
| sendData(0x00); | |
| sendData(0x00); | |
| sendCmd(0x26); | |
| digitalWrite(PIN_DC, HIGH); | |
| digitalWrite(PIN_CS, LOW); | |
| for (uint32_t i = 0; i < 81600; i++) { | |
| SPI.transfer(0x00); | |
| } | |
| digitalWrite(PIN_CS, HIGH); | |
| } | |
| void initDisplay() { | |
| digitalWrite(PIN_RES, LOW); | |
| delay(100); | |
| digitalWrite(PIN_RES, HIGH); | |
| delay(100); | |
| waitBusy(); | |
| sendCmd(0x12); | |
| delay(100); | |
| waitBusy(); | |
| sendCmd(0x74); | |
| sendData(0x54); | |
| sendCmd(0x7E); | |
| sendData(0x3B); | |
| sendCmd(0x01); | |
| sendData(0xA7); | |
| sendData(0x02); | |
| sendData(0x00); | |
| sendCmd(0x11); | |
| sendData(0x03); | |
| sendCmd(0x44); | |
| sendData(0x00); | |
| sendData(0x00); | |
| sendData(0xBF); | |
| sendData(0x03); | |
| sendCmd(0x45); | |
| sendData(0x00); | |
| sendData(0x00); | |
| sendData(0xA7); | |
| sendData(0x02); | |
| sendCmd(0x3C); | |
| sendData(0x01); | |
| sendCmd(0x18); | |
| sendData(0x80); | |
| sendCmd(0x22); | |
| sendData(0xB1); | |
| sendCmd(0x20); | |
| waitBusy(); | |
| } | |
| void refresh() { | |
| Serial.println("Refreshing..."); | |
| sendCmd(0x22); | |
| sendData(0xF7); | |
| sendCmd(0x20); | |
| unsigned long start = millis(); | |
| waitBusy(); | |
| Serial.print("Refresh: "); | |
| Serial.print(millis() - start); | |
| Serial.println("ms"); | |
| } | |
| void waitBusy() { | |
| while(digitalRead(PIN_BUSY) == HIGH) { | |
| delay(100); | |
| } | |
| } | |
| void sendCmd(uint8_t cmd) { | |
| digitalWrite(PIN_DC, LOW); | |
| digitalWrite(PIN_CS, LOW); | |
| SPI.transfer(cmd); | |
| digitalWrite(PIN_CS, HIGH); | |
| } | |
| void sendData(uint8_t data) { | |
| digitalWrite(PIN_DC, HIGH); | |
| digitalWrite(PIN_CS, LOW); | |
| SPI.transfer(data); | |
| digitalWrite(PIN_CS, HIGH); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment