Skip to content

Instantly share code, notes, and snippets.

@jborichevskiy
Created January 24, 2026 17:43
Show Gist options
  • Select an option

  • Save jborichevskiy/230f06b84e78b51b136eb9fdcb0e47b6 to your computer and use it in GitHub Desktop.

Select an option

Save jborichevskiy/230f06b84e78b51b136eb9fdcb0e47b6 to your computer and use it in GitHub Desktop.
SE1330NG08-MNG-A0 ESP32
// 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