'restart' the LCD after a power down of the processor (u8g2)

Hi everyone,

I am doing a project in which I am using an LCD (DEM128064I_FGH-PW) using a ST7565 controller, and I program it with the u8g2 library. The display works perfectly fine with the following constructor:

U8G2_ST7565_64128N_F_4W_SW_SPI u8g2(U8G2_R2, /* clock= */ 4, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);

The problem comes when 'powering down' the system, to do this, I put the MCU (ATmega4809) in power down mode, and I turn off the voltage source to the LCD, to save as much power as possible. But, as the pins used for the display are outputs, they still supply power to the display, in a way of what I think is called 'phantom powering'.

The code I use for this is, it works nicely and the display will update again once the MCU is taken out of its sleepmode.

#include <avr/sleep.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

U8G2_ST7565_64128N_F_4W_SW_SPI u8g2(U8G2_R2, /* clock= */ 2, /* data=*/ 7, /* cs=*/ 10, /* dc=*/ 6, /* reset=*/ 8);

unsigned long previousMillis = 0;
bool ledF = 0;
volatile bool sleep = 0;
int counter = 0;

void setup(){
  u8g2.begin();
  pinMode(13,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(3,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(3),debounce,LOW);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
}

void loop(){
  if(sleep == 0){                             //check if device should sleep. if not, do your thing
    if(millis() - previousMillis > 500 ){
      if(ledF == 0){
        digitalWrite(13, LOW);
      }else{
        digitalWrite(13, HIGH);
      }
      ledF =  !ledF;
      //Write something to the screen
      u8g2.firstPage();
      do {
        u8g2.clearBuffer();
          u8g2.setFont(u8g2_font_ncenB10_tr);
          u8g2.drawStr(5,24,"This is a test");
          u8g2.setCursor(5,48);
          u8g2.print(counter);
        u8g2.sendBuffer();
      } while (u8g2.nextPage() );
      counter++;
      previousMillis = millis();
    }
    digitalWrite(9,LOW);
  }else{                                      //sleep
    digitalWrite(9,HIGH);                     //show that sleepmode is on
    delay(200);                               //needed to allow button debounce to fill out its timer.
    TurnOff();                                //actually sleep the cpu
  }
}

void TurnOff(){
    sleep_enable();
    sleep_cpu();                              //could add BOD for deeper sleep, should test.
}

void debounce(){                              // debounce function
  static unsigned long lastDebounceTime = 0;  //Timer for debounce
  if ((millis() - lastDebounceTime) > 100) {
    if(sleep == 0){
      sleep = 1;    
    }else{
      sleep = 0;
    }
  }
  lastDebounceTime = millis();
}

I suspect the phantom powering because of the following measurements, and the fact that the display does not 'turn off' (the last frame is still shown) when the voltage source to the display is removed.
image
So I am still losing current to the display.

A 'solution' to this suggested somewhere against phantom powering would be to set the pins connected to the display as inputs, before going to sleep. I tried this by altering the TurnOff() function to this:

void TurnOff(){
    pinMode(2,INPUT);
    pinMode(7,INPUT);
    pinMode(10,INPUT);
    pinMode(6,INPUT);
    pinMode(8,INPUT);
    sleep_enable();
    sleep_cpu();                              //could add BOD for deeper sleep, should test.
}

This helps and the power consumption is again 0.8mA. But now, when getting out of sleep mode, the display of course does not work anymore. Setting the respective pins to outputs again after waking up does not help either.
Is there a way of 'resetting' the connection to the display with the u8g2 library when coming out of sleep mode? Or is there another type of solution to this?

Solution found:
Keep the pinModes as INPUT while asleep, but simply restart the display again using

u8g2.begin();

after waking up.

(2/10/22) Edit for anyone stumbling across this:
you can use

u8g2.setPowerSave(true);

in order to prevent the little ugly bars from showing up when the display is powered off.

1 Like

This topic was automatically closed after 120 days. New replies are no longer allowed.