Hey Everybody! Less of a question here and more just wanted to share some findings playing with a Waveshare 2.9" 3 color panel/driver board, an esp8266 and the GxEPD2 library.
Code and hardware that was working great on an old-style "dumb" 2.13 hat didn't play nice when moved over to the new board.
The 8266 flavor I am running on is a D1 mini pro. Taking heed of the suggestion to add a 1k pullup to RST did make it work - but I tried higher resistance values as well -- you see, I'm trying to make an ultra-long-life battery device that heavily leverages ESP deepsleep, and yes even the 3.3mA of a 1k resistor -- (in addition to the un-hibernated display from declaring RST as -1) was pushing my deepsleep current up to 5mA.
That's not much, and thats probably fine for most people - but wasn't going to cut it for my implementation. So I got to wondering why that pullup had to be such a high value.
If you look at the schematic of the D1 mini pro, you can see that cathode of LED1 is connected to GPIO2/D4 and the anode is connected to 3v3 through a 1k resistor - thus, if the sleeping display is tugging on that reset line a little bit, it can sap current from the 3v rail though the resistor and the LED. This will also prevent the board from booting properly in many cases including mine, since GPIO2 must be high on boot, and that current may well drag it low.
The easiest way to fix this of course is a 1k resistor right on the back of the paper board between VCC and RST, and eliminating the reset pin in code - but that's a bit inelegant and wasteful.
Here's what I did.
-
Desolder the led.
Okay yeah, drastic and permanent, but in my application its only going to waste power, and that 1k path to 3v3 isn't gonna play nice with the board's wacky floating pins shutdown state. Chuck it in the trash. Note: Do not try and cut the trace. It's a multilevel board, and important traces are underneath. Just desolder the LED. Or the little resistor next to the led. Or both if you're frisky - you do you. -
Swap RST and BUSY.
You can change the pin definitions, in my case this was inGxEPD2_display_selection_new_style.h
I redefined as follows:
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 4, /*BUSY=D2*/ 2));
If you have a spare GPIO, it might be worth just moving away from using D4 entirely and not mucking about with the LED, but I'm also running i2c so all the pins are occupado.
- Obviate any other parasitic draw.
We can set all the pins toINPUT
before we zonk out just to try and get any leakage down to the absolute minimum. I defined a function as follows:
const uint64_t sleepTime = 3 * 60 * 1000000;
void shutItDown() {
pinMode(0, INPUT);
pinMode(2, INPUT);
pinMode(4, INPUT);
pinMode(13,INPUT);
pinMode(14,INPUT);
pinMode(15,INPUT);
Serial.println("Dying. Bye!");
ESP.deepSleep(sleepTime);
}
Note that the Mini Pro has 10k pullups on GPIO0 and GPIO2 as well as a 10k pulldown on GPIO15 so - we don't have to worry about setting their levels prior to sleep, as the board is handling this with hardware. If your board isn't so equipped, this function might not work for you.
Anyway, the ESP and the Display now reliably sleep and wake up, and DeepSleep current is >400 microamps. (It may well be lower, I don't think my little high side current sensor is really meant to hear that tiny of a whisper).
So -- working for me. Hopefully something in here is useful for you.