Model parallel ED047TC1.h - martinberlin/cale-idf GitHub Wiki

  • Size: 960 * 540 4.7" 16 levels of gray
  • Epaper model: ED047C1 or ED047C2 / touch controller: L58 (PDF is in Chinese)
  • Dimensions: 11.4 * 6.3 CM (About 4 mm height including epaper)
  • Product page
  • Status: Implemented and merged in master (Check note below about partial update)
  • Refresh time: 600 milliseconds
  • Communication protocol: Parallel with 8 data lines
  • Touch interface is implemented with our component FT6X36 using the L58 class

Important: EPDiy that is the component to control this epaper may be not enabled by default. Check the components/CalEPD/CMakeLists file and uncomment it so it's included on the build

idf_component_register(SRCS ${srcs}      
                    REQUIRES "Adafruit-GFX"
                    REQUIRES "FT6X36-IDF"
                    # Only for parallel epapers:
                    #REQUIRES "epd_driver"

                    INCLUDE_DIRS "include"
)

The idea to support this displays is documented in the WiKi section "Parallel epapers driven by EPDiy"

NEWS: Touch class is called L58Touch and passed first round of tests. It's now merged also in branch: refactor/oop It implements a virtual "tapping detection" since we still could not read proper touch events but is at least usable to press buttons. Enable the demos/parallel/demo-touch-keyboard.cpp in CMakeLists to see it in action.

This super fast parallel epaper was sent to our studio by LILYGO. The implementation is done using as a base EPDiy component.

Product description and internal GPIOs

This 4.7-inch version continues the low-power design, the sleep mode current is about 170uA, and two optional battery modes are designed on the back. A 6 pin touch screen interface is reserved as an optional accessory to facilitate your application. The touch screen is coming so it will take some weeks to implement it in the class like we already did with 2.7" from Goodisplay.

There are 5 buttons reserved on the side, 3 of which are custom buttons, which can define functions flexibly. One is the reset button.

Product schematic

// Run idf.py menuconfig-> Component Config -> E-Paper driver and select:
// Display type: LILIGO 4.7 ED047TC1
// Board: LILIGO T5-4.7 Epaper
// In the same section Component Config -> ESP32 Specifics -> Enable PSRAM
#include "parallel/ED047TC1.h"
Ed047TC1 display;

void app_main(void) {
   display.init(true);
   display.setCursor(50,100);
   // Use all inherited GFX methods: setFont, setTextColor, fillRect, fillCircle, etc*
   display.println("Hello fast epaper");
   display.update();
   vTaskDelay(2000 / portTICK_PERIOD_MS);
   display.clearScreen();
}
  

Analysis of pixel buffer

The challenge that is still pending is to implement partial update. For that we need to crop and extract a small buffer area from the big buffer. The image below is the start of the analysis to implement this:

parallel_buffer

First approach to partial update


void Ed047TC1::updateWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h, enum DrawMode mode, bool using_rotation)
{
  Rect_t area = {
    .x = x,
    .y = y,
    .width = w,
    .height = h,
  };

  uint8_t *buffer = (uint8_t *)heap_caps_malloc(w*h/2,MALLOC_CAP_SPIRAM);
  memset(buffer, 0xFF, w*h/2);

  uint32_t i = 0;
  // Crop only this square from the big framebuffer
  for (int16_t y1 = y; y1 < y+h; y1++)
  {
    for (int16_t x1 = x; x1 < x+w; x1=x1+2)
    {
      buffer[i] = framebuffer[y1 *ED047TC1_WIDTH / 2 + x1/2];
      i++;
    }
    //printf("buffer y: %d line: %d\n",y1,i);
  }

  epd_draw_image(area, buffer, mode);
}

Check the demo over here to see a bouncing ball example:

https://github.com/martinberlin/cale-idf/tree/refactor/oop/main/demos/parallel - demo-epaper-parallel-partial.cpp

Note: Doing it this way is over engineered if you want to print just a small ball. In that case it will be better to draw the ball itself in a small buffer. But for bigger sections where speed in not crucial, this can work well, and you can use the full inherited Adafruit GFX geometric functions.

Touch research

There is no documentation available about the I2C touch controller. This makes it not a good candidate at this time to use it in an UX firmware. Only name we found in the Aliexpress product page is: Touch chip: L58 - Support multi-touch

We started the implementation based on Lilygo example but is still very raw due to the lack of documentation. To make a good touch implementation we need to know what events are send. It’s not about simply to read X and Y coordinates. Lewis from Lilygo posted a L58 PDF but is in chinese and does not seem to have an "Events table". We need to research more and sniff all what is coming per I2C, it would really surprise me that this is a mobile touch overlay, and has no events. Will update this when I get more useful information.

Warning: If you assemble the touch take great are when connecting the small flat cable. The connector in the Lilygo PCB is not meant to open and close many times. I got one broken just by trying to get it inside the 3D printed housing.

Touch V2 will come after one month

My Tap simulation works quite good and is enough to make buttons and alike. When it's fully working with last information that Lilygo sent me I will try to add Gestures, such as "Drag start", "Drag end", "Zoom in"/out etc. and of course real Tap detection, that is when pressDown and liftUp are less than aprox 200/300 millis.

Proof of concept video here in Twitter: https://twitter.com/martinfasani/status/1366074023176765442

To test the class for this epaper and insert touch capabilities, instantiate it like this:

// Run idf.py menuconfig-> Component Config -> E-Paper driver and select:
// Display type: LILIGO 4.7 ED047TC1 | Board: LILIGO T5-4.7 Epaper (enable PSRAM!)
// menuconfig-> Touch configuration -> 15 SDA, 14 SDL, 13 Touch interrupt (INT)
// This is the I2C component to read touch with I2C: 
#include "L58Touch.h"

// TOUCH_INT is touch interrupt, goes HI when it detects a touch, so coordinates can be read using I2C
L58Touch ts(CONFIG_TOUCH_INT);
#include "parallel/ED047TC1touch.h"
Ed047TC1t display(ts);
uint16_t t_counter = 0;

void touchEvent(TPoint p, TEvent e)
{
    ++t_counter; // Touch triggered, print the coordinates:
    printf("X: %d Y: %d count:%d\n", p.x, p.y, t_counter);
}

void app_main(void) {
   display.init(true);
   // Includes both epaper + touch rotation. Do not use rotation from Adafruit GFX when using touch!
   display.displayRotation(0);

   display.setCursor(50,100);
   display.println("Try to tap the screen!");
   display.update();

   // Register the callback function that will receive the touch events
   display.registerTouchHandler(touchEvent);

   // The ESP-IDF way to do what in arduino-esp32 is loop() function
   for (;;) {
     display.touchLoop();
   }

}

There is an sdkconfig ready with the correct settings to flash the epaper ESP32 in the config-examples directory:

cale-idf$ cp config-examples/ttgo-EPD47-touch sdkconfig

Touch demos

They are located on main/demos/parallel/ you can select between:

  1. demo-touch-parallel: Draw example with rotation aware touch
  2. demo-touch-keyboard: Keyboard example

Next step would be to adapt LittlevGL or μGFX and make it work on epaper just for basic button widgets using partial refresh.