Jump to content
mirthe

Very slow refresh on 4.5" epaper shield

Recommended Posts

Hi there,

 

I have this product:

http://store.linksprite.com/4-5-e-paper-shield-for-arduino-pcduino/

 

It is taking an INCREDIBLY long time to load a single image onto the display, around 30-60 seconds. It goes through 10 or so stages of full-screen refreshes at different shades, then finally shows the image.

 

Here's my test code, which is meant to display 4 bars (white, light gray, dark gray, and black):

#define REQUIRED_IMAGE_PASSES 11

...

void sendImage() {
  bool DeviceStatus;
  unsigned char data;
    
  Serial.println("Start sendImage.");

  DeviceStatus = digitalRead(EINK_STATUS_PIN);
  digitalWrite(EINK_CS_PIN, LOW);
  SPI.transfer(4);
  while (digitalRead(EINK_STATUS_PIN) == DeviceStatus) { }
  DeviceStatus = !DeviceStatus;

  for (unsigned int pass = 0; pass < REQUIRED_IMAGE_PASSES; pass++) {
    for (unsigned long imageByteIdx = 0, x = 0, y = 0; imageByteIdx < 120000; imageByteIdx++) {
      if (x < 200) {
        data = 0xFF; // 4 black pixels
      } else if (x < 400) {
        data = 0xAA; // 4 dark gray pixels
      } else if (x < 600) {
        data = 0x55; // 4 light gray pixels
      } else {
        data = 0x00; // 4 white pixels
      }
      SPI.transfer(data);

      while (digitalRead(EINK_STATUS_PIN) == DeviceStatus) { }
      DeviceStatus = !DeviceStatus;

      if ((x += 4) >= 800) {
        x = 0;
        y++;
      }
    }    
  }
  
  digitalWrite(EINK_CS_PIN, HIGH);

  Serial.println("End sendImage.");
}

My code is based on the code from the tutorial. Notice that it sends the image data 11 times, because of the outer for-loop! What I named REQUIRED_IMAGE_PASSES the sample code calls:

#define FRAME_END_LEN	11

Through some testing, I see that each run through the outer-loop results in 1 full screen refresh (at a different shade of gray), and takes several seconds. So in total it takes 30-60 seconds. Note that image only appears in the final pass through the outer-loops, it's not like each pass is building up the image, they seem unnecessary.

 

The datasheet for the epaper display used in this shield (GDE043A2) says it has a refresh time of 300-1600ms.

 

What is making the refresh so slow? Why does the image data need to be sent 11 times?

 

Also, the light gray isn't displaying (shows up white), but I can live with that.

 

Thanks.

 

Share this post


Link to post
Share on other sites

Same here... so many passes seem unneccessary. Need to look at the code on the onboard chip to figure things out.

Also have a problem with 4 colors since using with Arduino, space is important and if it doesn't support 4 colors might as well send 2.

Share this post


Link to post
Share on other sites

Yes, but the sample code that comes with the display DOES NOT work, it has numerous bugs. Use the code I posted in my initial message.

 

If it's working, expect to watch an agonizingly slow progressive drawing.

 

I haven't found another eInk display of this form factor, so I'm super frustrated by how non-performant this one is. Completely unusable.

Share this post


Link to post
Share on other sites

Strangely, the screen faded and it wasn't even powered on or connected to anything.  It was sitting near a window on my desk which gets about 2 hours of sun.  Is that normal?

Share this post


Link to post
Share on other sites

Clear screen doesn't even work for me; your code only is an update to sending an image.

 

The sample code that comes with the board is full of errors. Here's my complete fixed code, but I ripped it out of a larger project just now so I might've left something in that's unnecessary. The part that surprises me most is REQUIRED_IMAGE_PASSES, a constant I added to reflect that you actually need to send the same data to the board 11 times (!!!) to get it to fully render the image.

#include <SPI.h>

#define EINK_STATUS_PIN 9
#define EINK_CS_PIN 10

#define IMAGE_WIDTH 800
#define IMAGE_HEIGHT 600
#define SPI_MODE SPI_MODE1
#define REQUIRED_IMAGE_PASSES 11

void clearScreen(void) {
  bool DeviceStatus;
  
  DeviceStatus = digitalRead(EINK_STATUS_PIN);
  digitalWrite(EINK_CS_PIN, LOW);
  SPI.transfer(3); 
  while (digitalRead(EINK_STATUS_PIN) == DeviceStatus) { }
  digitalWrite(EINK_CS_PIN, HIGH);
}

void setImageDimension(bool isWidth, unsigned int value) {
  bool DeviceStatus;
  
  DeviceStatus = digitalRead(EINK_STATUS_PIN);
  digitalWrite(EINK_CS_PIN, LOW);
  SPI.transfer(isWidth ? 2 : 1);
  while (digitalRead(EINK_STATUS_PIN) == DeviceStatus) { }
  DeviceStatus = !DeviceStatus;
  SPI.transfer(value >> 8);
  while (digitalRead(EINK_STATUS_PIN) == DeviceStatus) { }
  DeviceStatus = !DeviceStatus;  
  SPI.transfer(value & 0xFF);
  while (digitalRead(EINK_STATUS_PIN) == DeviceStatus) { }
  digitalWrite(EINK_CS_PIN, HIGH);
}

void setImageWidth(unsigned int width) {
  setImageDimension(true, width);
}

void setImageHeight(unsigned int height) {
  setImageDimension(false, height);
}

void sendImage() {
  bool DeviceStatus;
  unsigned char data;
    
  Serial.println("Start sendImage.");

  DeviceStatus = digitalRead(EINK_STATUS_PIN);
  digitalWrite(EINK_CS_PIN, LOW);
  SPI.transfer(4);
  while (digitalRead(EINK_STATUS_PIN) == DeviceStatus) { }
  DeviceStatus = !DeviceStatus;

  for (unsigned int pass = 0; pass < REQUIRED_IMAGE_PASSES; pass++) {
    for (unsigned long imageByteIdx = 0, x = 0, y = 0; imageByteIdx < 120000; imageByteIdx++) {
      if (x < 200) {
        data = 0xFF;
      } else if (x < 400) {
        data = 0xAA;
      } else if (x < 600) {
        data = 0x55;
      } else {
        data = 0x00;
      }
      SPI.transfer(data);

      while (digitalRead(EINK_STATUS_PIN) == DeviceStatus) { }
      DeviceStatus = !DeviceStatus;

      if ((x += 4) >= 800) {
        x = 0;
        y++;
      }
    }    
  }
  
  digitalWrite(EINK_CS_PIN, HIGH);

  Serial.println("End sendImage.");
}

void setup() {
  Serial.begin(9600);
  while (!Serial) {};
  
  pinMode(EINK_STATUS_PIN, INPUT); 
  digitalWrite(EINK_STATUS_PIN, HIGH);
  pinMode(EINK_CS_PIN, OUTPUT); 
  digitalWrite(EINK_CS_PIN, HIGH);

  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE);
  SPI.setClockDivider(SPI_CLOCK_DIV4);  

  Serial.println("Rendering image.");
  setImageWidth(IMAGE_WIDTH);
  setImageHeight(IMAGE_HEIGHT);
  clearScreen();
  sendImage();
}

void loop() {
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×