I'm working on a small project (or so I thought) involving an Arduino Mega (2560) and a Waveshare ePaper display.
I've got it working alright with the library (epd7in5) and I've added two images into PROGMEM
. But as soon as I add a third image (and thus a third entry into the PROGMEM
), somehow the ePaper screen doesn't initiate anymore. Adding some debugging in the library shows that the code gets stuck on a specific SPI.transfer()
.
EDIT: Theory Is it possible that SPI is not compatible when there's too much data in flash? I've read up on it that 64kb is the max. I'm slightly above that with two images, but significantly so with three. Could be that this breaks SPI? And if so: can I fix it?
I've added the code below and the specific part of the library where the SPI.transfer()
fails.
Main.cpp
Removing the code related to dummy3 ensures that the dummy3 array doesn't compile. Only using dummy1 and dummy2 everything works fine. Adding dummy3 and the program gets stuck on epd.Init()
.
#include <SPI.h>
#include <epd7in5.h>
#include "imagedata.h"
Epd epd;
void debug(String);
void setup() {
Serial.begin(9600);
debug("Serial begin");
if (epd.Init() != 0) {
debug("INIT FAILED!");
return;
}
debug("Changing image");
epd.DisplayFrame(dummy1); //DisplayFrame by default includes WaitUntilIdle.
debug("dummy1 on ePaper");
delay(1000);
debug("Changing image");
epd.DisplayFrame(dummy2);
debug("dummy2 on ePaper");
delay(1000);
debug("Changing image");
epd.DisplayFrame(dummy3);
debug("dummy2 on ePaper");
epd.SendCommand(POWER_OFF);
debug("POWER_OFF");
}
void loop() {
}
void debug(String message) {
Serial.print(millis());
Serial.print("\t");
Serial.println(message);
}
imagedata.cpp
I've removed the actual image data as it's A LOT. Two images result in a total flash of 67326 bytes (about 26% of total flash mem of 2560). Three images result in a total flash of 98052 bytes (about 38% of total flash mem of 2560). Headerfile contains simply the declarations.
#include "imagedata.h"
#include <avr/pgmspace.h>
const unsigned char dummy1[30726] PROGMEM = {...data...};
const unsigned char dummy2[30726] PROGMEM = {...data...};
const unsigned char dummy3[30726] PROGMEM = {...data...};
epd7in5.cpp
I've added the debug function. SendData is also included and uses the debug as well.
void Epd::debug(String message) {
Serial.print(millis());
Serial.print("\t");
Serial.print("EPD");
Serial.print("\t");
Serial.println(message);
}
int Epd::Init(void) {
if (IfInit() != 0) {
return -1;
}
debug("Resetting");
Reset();
debug("SendCommand(POWER_SETTING);");
SendCommand(POWER_SETTING);
debug("SendData(0x37);");
SendData(0x37);
debug("SendData(0x00);");
SendData(0x00);
debug("SendCommand(PANEL_SETTING);");
SendCommand(PANEL_SETTING);
SendData(0xCF);
SendData(0x08);
SendCommand(BOOSTER_SOFT_START);
SendData(0xc7);
SendData(0xcc);
SendData(0x28);
SendCommand(POWER_ON);
WaitUntilIdle();
SendCommand(PLL_CONTROL);
SendData(0x3c);
SendCommand(TEMPERATURE_CALIBRATION);
SendData(0x00);
SendCommand(VCOM_AND_DATA_INTERVAL_SETTING);
SendData(0x77);
SendCommand(TCON_SETTING);
SendData(0x22);
SendCommand(TCON_RESOLUTION);
SendData(0x02); //source 640
SendData(0x80);
SendData(0x01); //gate 384
SendData(0x80);
SendCommand(VCM_DC_SETTING);
SendData(0x1E); //decide by LUT file
SendCommand(0xe5); //FLASH MODE
SendData(0x03);
return 0;
}
void Epd::SendData(unsigned char data) {
debug("DigitalWrite(dc_pin, HIGH);");
DigitalWrite(dc_pin, HIGH);
debug("SpiTransfer(data);");
SpiTransfer(data);
}
epdif.cpp
This is the SPI transfer part that doesn't continue.
void EpdIf::SpiTransfer(unsigned char data) {
digitalWrite(CS_PIN, LOW);
SPI.transfer(data);
digitalWrite(CS_PIN, HIGH);
}
The serial print of the project is as follows...
0 Serial begin
0 EPD Resetting
400 EPD SendCommand(POWER_SETTING);
400 EPD SendData(0x37);
400 EPD DigitalWrite(dc_pin, HIGH);
435 EPD SpiTransfer(data);
So, as soon as it runs SpiTransfer
the code simply stops working. It seems it is in an infinite loop within SPI.transfer();
but I don't know exactly how that would happen. I don't see how PROGMEM
could interfere with the transfer and I have enough flash memory left...
What can be solution for this? Is it a problem in SPI that I need to change? Or do I need to store my data differently in PROGMEM
? I am a bit at a loss.
Thanks in advance for your help, greatly appreciated.