2.9" Tri-Color eInk FeatherWing IL0373

Adafruit product page for PN 4778

Adafruit EPD Library

Adafruit product tutorial

This eInk display expends a considerable amount of time flickering over the 20 seconds it takes to completely update the screen.   Costmetically, it is best not to plan this display for a project that requires a clean refresh.   Once the screen is updated, it has great contrast, and the red color is very useful for providing a highlight.  


/*
  2.9" Tri-Color eInk FeatherWing IL0373
  296x128 pixels
  E-Ink driver chipset IL0373
  
  https://www.adafruit.com/product/4778
  
  
 
 */

// In Arduino IDE, select 'Tools','Board','Adafruit Boards','Adafruit Feather ...'
// Find USB port in Windows by looking at ...

/////////////////////////////////////////////////////////////////////////////\/
// Show serial messages when DEBUG = true, otherwise minimize them.
#define DEBUG false
//////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////
// Built in LED(s) & LiPoly Battery

//  #0 ESP8266
// #13 ESP32, STM32F2, Teensy, 32u4, 382P, M0, M4
const uint8_t pinBuiltInLED = 13;  

// A6 328P,
// A7 M0
//const byte pinLiPoly = A6

/////////////////////////////////////////////////////////////////////////
// blinkLEDnoDelay()
unsigned long LEDblinkPeriod = 8;
unsigned long LEDblinkLast = 0;
uint8_t LEDblinkPWM = 0;
bool LEDblinkState = false;
uint8_t LEDlastMode = 0;

void blinkLEDnoDelay(byte pin, byte mode) {
  // Blink the LED on 'pin' without using delay() according to
  // the 'mode' argument defined below. 
  // pin must support PWM. 
  // 
  // mode:
  //  0 = breathing
  //  1 = blink slow constantly
  //  2 = blink fast constantly
  //  3 = slow burst every 1 second
  //  4 = fast burst every 1 second
  //
  // Required global variables: LEDblinkPeriod, LEDblinkLast, LEDblinkPWM, LEDblinkState, LEDlastMode
  if (mode == 0) {
    // breathing
    LEDblinkPeriod = 8;
    if (LEDlastMode != mode) {
      LEDblinkPWM = 0;
      LEDblinkState = true;
      digitalWrite(pin, LOW);
    }
    if (millis() - LEDblinkLast >= LEDblinkPeriod) {
        if (LEDblinkPWM > 254) LEDblinkState = false;
        if (LEDblinkPWM < 1) LEDblinkState = true;
        if (LEDblinkState) {
            LEDblinkPWM++;
        } else {
            LEDblinkPWM--;
        }
        analogWrite(pin, LEDblinkPWM);
        LEDlastMode = mode;
        LEDblinkLast = millis();
    }
  } else if (mode == 1) {
    // blink slow constantly
    LEDblinkPeriod = 1000;
    if (millis() - LEDblinkLast >= LEDblinkPeriod) {
        digitalWrite(pin, LEDblinkState);
        LEDblinkState = !LEDblinkState;
        LEDlastMode = mode;
        LEDblinkLast = millis();
    }
  } else if (mode == 2) {
    // blink fast constantly
    LEDblinkPeriod = 100;
    if (millis() - LEDblinkLast >= LEDblinkPeriod) {
        digitalWrite(pin, LEDblinkState);
        LEDblinkState = !LEDblinkState;
        LEDlastMode = mode;
        LEDblinkLast = millis();
    }
  } else if (mode == 3) {
    // slow burst every 1 second
    // Slow 4 blinks (lazy burst) followed by 1 sec pause
    if (LEDlastMode != mode) {
      LEDblinkPWM = 0;
      LEDblinkState = true;
      LEDblinkPeriod = 100;
    }
    if (millis() - LEDblinkLast >= LEDblinkPeriod) {
        if (LEDblinkPWM < 7) {
          if (LEDblinkPWM == 0) LEDblinkState = true;
          digitalWrite(pin, LEDblinkState);
          LEDblinkPeriod = 100;
          LEDblinkState = !LEDblinkState;
          LEDblinkPWM++;
        } else {
          digitalWrite(pin, LOW);
          LEDblinkPWM = 0;
          LEDblinkPeriod = 1000;
        }
        LEDlastMode = mode;
        LEDblinkLast = millis();
    }
  } else if (mode == 4) {
    // fast burst every 1 second
    // Fast 4 blinks (burst) followed by 1 sec pause
    if (LEDlastMode != mode) {
      LEDblinkPWM = 0;
      LEDblinkState = true;
      LEDblinkPeriod = 25;
    }
    if (millis() - LEDblinkLast >= LEDblinkPeriod) {
        if (LEDblinkPWM < 7) {
          if (LEDblinkPWM == 0) LEDblinkState = true;
          digitalWrite(pin, LEDblinkState);
          LEDblinkPeriod = 25;
          LEDblinkState = !LEDblinkState;
          LEDblinkPWM++;
        } else {
          digitalWrite(pin, LOW);
          LEDblinkPWM = 0;
          LEDblinkPeriod = 1000;
        }
        LEDlastMode = mode;
        LEDblinkLast = millis();
    }
  } // mode
}   // blinkLEDnoDelay()


void blinkLED(byte ledPIN){
  //  consumes 300 ms.
  for(uint8_t i = 5; i>0; i--){
    digitalWrite(ledPIN, HIGH);
    delay(30);
    digitalWrite(ledPIN, LOW);
    delay(30);
  }    
} //blinkLED()


void blinkERR(byte ledPIN){
  // S-O-S
  const uint8_t S = 150, O = 300;
  for(uint8_t i = 3; i>0; i--){
    digitalWrite(ledPIN, HIGH);
    delay(S);
    digitalWrite(ledPIN, LOW);
    delay(S);
  }    
  delay(200);
  for(uint8_t i = 3; i>0; i--){
    digitalWrite(ledPIN, HIGH);
    delay(O);
    digitalWrite(ledPIN, LOW);
    delay(O);
  }    
  delay(200);
  for(uint8_t i = 3; i>0; i--){
    digitalWrite(ledPIN, HIGH);
    delay(S);
    digitalWrite(ledPIN, LOW);
    delay(S);
  }    
  delay(200);
} // blinkERR()

/////////////////////////////////////////////////////////////////////////
//  2.9" Tri-Color eInk FeatherWing IL0373

// Install library "Adafruit_EPT"
#include "Adafruit_ThinkInk.h"

#define EPD_DC 10
#define EPD_CS 9
#define EPD_BUSY -1 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6
#define EPD_RESET -1  // can set to -1 and share with microcontroller Reset!
#define EPD_SPI &SPI // primary SPI

// 2.9" Tricolor Featherwing or Breakout with IL0373 chipset
ThinkInk_290_Tricolor_Z10 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);

uint8_t display_layout = 0;

void splashScreen(uint32_t delay_ms) {
  // Mechatronic Solutions LLC splash screen...
  display.clearBuffer();
  display.setTextSize(3);
  display.setTextColor(EPD_BLACK);  // EPD_BLACK, EPD_RED
  
  display.setCursor(6,30); 
  //     .print("0123456789001234");  // .setTextSize(3);
  display.print("  Mechatronic");  // .setTextSize(3);

  display.setCursor(6,78); 
  //     .print("0123456789001234");  // .setTextSize(3);
  display.print(" Solutions LLC");  // .setTextSize(3);

  display.display();
  
  yield();
  delay(delay_ms);  
} // splashScreen()


/////////////////////////////////////////////////////////////////////////


void setup() {

  #if DEBUG
  Serial.begin(115200);
  while (!Serial) {
    delay(1);
  }
  Serial.println("\nSerial ready");
  #endif

  pinMode(pinBuiltInLED, OUTPUT);
  digitalWrite(pinBuiltInLED, LOW);

  //  2.9" Tri-Color eInk FeatherWing IL0373
  display.begin(THINKINK_TRICOLOR);
  //display.clearBuffer();
  //display.display();

  // From Adafruit.EPD.h
  //  .begin()
  //  .drawPixel()
  //  .clearBuffer()
  //  .clearDisplay()
  //  .setBlackBuffer()
  //  .setColorBuffer
  //  .display()

  // From Adafruit_GFX
  //  .setTextSize()  1 is default 6x8, 2 is 12x16, 3 is 18x24, etc
  //  .setCursor(x, y)    coordinates in pixels

  splashScreen(5000);

  // With .setTextSize(1), you get 18 rows of 48 characters/line
  // Characters are 6 px wide x 6 px tall  (VERY SMALL)
  // With spacing between rows and frame, start text at:
  //  (1,6), (1,8), (1,15), (1,22), (1,29), (1,36), (1,43), (1,50), (1,57), (1,57), (1,64), (1,71), (1,78), (1,85), (1,92), (1,99), (1,106), (1,113), (1,120)
  display.clearBuffer();
  display.setTextSize(1);
  display.setTextColor(EPD_BLACK);  // EPD_BLACK, EPD_DARK, EPD_LIGHT

  display.setCursor(1,8); 
  display.print("0123456789012345678901234567890123456789012345678");  // .setTextSize(1);
  
  display.setCursor(1,22); 
  display.print("0123456789012345678901234567890123456789012345678");  // .setTextSize(1);

  display.setCursor(1,36); 
  display.print("0123456789012345678901234567890123456789012345678");  // .setTextSize(1);

  display.setTextColor(EPD_RED);  // EPD_BLACK, EPD_RED
  display.setCursor(1,50); 
  //     .print("0123456789012345678901234567890123456789012345678");  // .setTextSize(1);
  display.print("          18 rows x 48 characters/row");  // .setTextSize(1);
  
  display.setTextColor(EPD_BLACK);  // EPD_BLACK, EPD_RED
  display.setCursor(1,64); 
  display.print("0123456789012345678901234567890123456789012345678");  // .setTextSize(1);
  
  display.setCursor(1,78); 
  //     .print("0123456789012345678901234567890123456789012345678");  // .setTextSize(1);
  display.print("Write on every other line to improve readability");  // .setTextSize(1);
  
  display.setCursor(1,92); 
  display.print("0123456789012345678901234567890123456789012345678");  // .setTextSize(1);
  
  display.setCursor(1,106); 
  display.print("0123456789012345678901234567890123456789012345678");  // .setTextSize(1);
    
  display.setCursor(1,120); 
  display.print("0123456789012345678901234567890123456789012345678");  // .setTextSize(1);
    
  display.display();
  delay(15000);


  // With .setTextSize(2), you get 7 rows of 23 characters/line
  // Characters are 12 px wide x 14 px tall
  // With spacing between rows and frame, start text at:
  //  (4,6), (4,23), (4,40), (4,56), (4,74), (4,91), (4,108)
  display.clearBuffer();
  display.setTextSize(2);
  display.setTextColor(EPD_BLACK);  // EPD_BLACK, EPD_RED
  // (6,0),(6,14),(6,28),(6,42),(6,56),(6,70),(6,84),(6,96)
  display.setCursor(4,6);  // top left
  //     .print("012345678901234567890123");  // .setTextSize(2);
  display.print("012345678901234567890123");  // .setTextSize(2);

  display.setCursor(4,23); 
  //     .print("012345678901234567890123");  // .setTextSize(2);
  display.print("  23 characters wide");  // .setTextSize(2);

  display.setCursor(4,40); 
  //     .print("012345678901234567890123");  // .setTextSize(2);
  display.print("  7 rows with spacing");  // .setTextSize(2);

  display.setCursor(4,57);  
  //     .print("012345678901234567890123");  // .setTextSize(2);
  display.print("       EPD_BLACK");  // .setTextSize(2);

  display.setCursor(4,74);  
  display.setTextColor(EPD_RED);  // EPD_BLACK, EPD_RED
  //     .print("012345678901234567890123");  // .setTextSize(2);
  display.print("       EPD_RED");  // .setTextSize(2);

  display.setCursor(4,91);  
  display.setTextColor(EPD_LIGHT);  // EPD_BLACK, EPD_RED
  //     .print("012345678901234567890123");  // .setTextSize(2);
  display.print("       EPD_LIGHT");  // .setTextSize(2);

  display.setCursor(4,108);  
  display.setTextColor(EPD_BLACK);  // EPD_BLACK, EPD_DARK, EPD_LIGHT
  //     .print("012345678901234567890123");  // .setTextSize(2);
  display.print("012345678901234567890123");  // .setTextSize(2);
  
  display.display();
  delay(15000);

  // With .setTextSize(3), you get five rows of 15 characters/line
  // Characters are 20 px tall
  // With spacing between rows and frame, start text at:
  //    (5,6), (6,30), (6,54), (6,78), 6,102)
  display.clearBuffer();
  display.setTextSize(3);
  display.setTextColor(EPD_BLACK);  // EPD_BLACK, EPD_RED
  
  display.setCursor(6,6);  // top left
  //     .print("0123456789012345");  // .setTextSize(3);
  display.print("0123456789012345");  // .setTextSize(3);

  display.setTextColor(EPD_RED);  // EPD_BLACK, EPD_RED
  display.setCursor(6,30); 
  //     .print("0123456789012345");  // .setTextSize(3);
  display.print(" 14 chars wide");  // .setTextSize(3);

  display.setTextColor(EPD_BLACK);  // EPD_BLACK, EPD_RED
  display.setCursor(6,54); 
  //     .print("0123456789012345");  // .setTextSize(3);
  display.print("chars 20 px tall");  // .setTextSize(3);

  display.setTextColor(EPD_RED);  // EPD_BLACK, EPD_RED
  display.setCursor(6,78); 
  //     .print("0123456789012345");  // .setTextSize(3);
  display.print("  5 rows tall ");  // .setTextSize(3);

  display.setTextColor(EPD_BLACK);  // EPD_BLACK, EPD_RED
  display.setCursor(6,102); 
  display.print("0123456789012345");  // .setTextSize(3);

  display.display();

  delay(15000);
  
  randomSeed(millis());
  
  #if DEBUG
  Serial.println("Setup finished");
  #endif
} // setup()


void loop() {

  blinkLEDnoDelay(pinBuiltInLED, 0);
  

} // loop()

 


Do you need help developing or customizing a IoT product for your needs?   Send me an email requesting a free one hour phone / web share consultation.  

 

The information presented on this website is for the author's use only.   Use of this information by anyone other than the author is offered as guidelines and non-professional advice only.   No liability is assumed by the author or this web site.