Quantcast
Channel: Arduino Forum - Latest topics
Viewing all articles
Browse latest Browse all 15454

GxEPD2 Partial update shows scrambled text

$
0
0

Hello!

I am new to the forum and this is my first arduino project. I want to use a epaper display with a Seeed Studio XIAO nRF52840 to display some temperatures.

I have the following display from GoodDisplay: https://aliexpress.com/item/1005002546926786.html (So the GDEY029T94 with the DESPI-C02 shield).

I first print the layout, and then periodically want to update the numbers (for simplicity in the attached code those are random values). The first update of both temperatures works fine, any subsequent update result in scrambled numbers for the upper number, for the lower number everything works fine - please see my attached photos.

I hope this describes my problem enough!

I also tries switching the RESE values form 0,47 to 3 but I am not sure which is the correct number as both seem to produce the same result

This is my code:

#include <GxEPD2_BW.h>
#include <Fonts/FreeSans18pt7b.h>
#include <U8g2_for_Adafruit_GFX.h>
#include <bluefruit.h>

/*
Connection information:
Waveshare -- Seeed
-------------------
VCC/3.3   -- 3V3
GND       -- GND
DIN/SDI   -- MOSI
CLK/SCK   -- RX/SCK
CS        -- D6
DC        -- D5
RST       -- D4
BUSY      -- D3
*/

GxEPD2_BW<GxEPD2_290_T94, GxEPD2_290_T94::HEIGHT> display(GxEPD2_290_T94(/*CS=D6*/ D6, /*DC=DC5*/ D5, /*RST=D4*/ D4, /*BUSY=D3*/ D3)); 

U8G2_FOR_ADAFRUIT_GFX u8g2_4_gfx;
SoftwareTimer displayUpdateTimer;

void setup() {
  // low power mode 
  Bluefruit.begin(); // Sleep functions need the softdevice to be active.
  sd_power_mode_set(NRF_POWER_MODE_LOWPWR); 

  initDisplay();

  displayUpdateTimer.begin(10000, updateTemperatureCallback);  // Configure the timer with 1000 ms interval, with our callback
  displayUpdateTimer.start();  // Start the timer

  suspendLoop();
}

void loop() {
  // no code here time is used for this function and loop is suspended
}

void initDisplay() {
  display.init(115200, true);
  u8g2_4_gfx.begin(display);
  display.setRotation(0);

  printLayout();
  display.end();
}

void updateTemperatureCallback(TimerHandle_t xTimerID) {
  (void) xTimerID;
  updateTemperatures(random(19,25), random(0,35));
  sd_app_evt_wait(); // puts the nrf52 to sleep when there is nothing to do
}

void printLayout() {
  // setup font 
  u8g2_4_gfx.setFontMode(1);                   // use u8g2 transparent mode (this is default)
  u8g2_4_gfx.setFontDirection(0);              // left to right (this is default)
  u8g2_4_gfx.setForegroundColor(GxEPD_BLACK);  // apply Adafruit GFX color
  u8g2_4_gfx.setBackgroundColor(GxEPD_WHITE);  // apply Adafruit GFX color

  int16_t padding = 40;
  uint16_t width = 0;
  uint16_t x = 0;
  uint16_t y = 0;

  display.setFullWindow();
  display.firstPage();
  do
  {
    u8g2_4_gfx.setFont(u8g2_font_helvB10_tf);
    u8g2_4_gfx.setCursor(8, padding);
    u8g2_4_gfx.print("Innen:");
    u8g2_4_gfx.setCursor(8, display.height() / 2 + padding);
    u8g2_4_gfx.print("Außen:");

    display.drawLine(0, display.height() / 2, display.width(), display.height() / 2 , GxEPD_BLACK);
  }  
  while (display.nextPage());
}

void updateTemperatures(double insideTemp, double outsideTemp) 
{
  Serial.println("Begin update");
  display.init(115200, false);
  // append °C to the temperature strings
  String insideTempAsStr = String(String(insideTemp, 1) + "°C");
  String outsideTempAsStr = String(String(outsideTemp, 1) + "°C");

  uint16_t yCoordinateUpperHalfCenter = display.height() / 4;
  partiallyUpdateSingleTemperature(insideTempAsStr, yCoordinateUpperHalfCenter);

  delay(500);

  uint16_t yCoordinateLowerHalfCenter = display.height() / 4 * 3;
  partiallyUpdateSingleTemperature(outsideTempAsStr, yCoordinateLowerHalfCenter);

  display.end();
}

void partiallyUpdateSingleTemperature(String temperatureStr, uint16_t yCoordinateCenter) {
  // Convert temperature string to char array to be able to determine length
  int strLen = temperatureStr.length() + 1; 
  char temperatureAsCharArray[strLen];
  temperatureStr.toCharArray(temperatureAsCharArray, strLen);

  u8g2_4_gfx.setFont(u8g2_font_helvR24_tf);
  uint16_t tempStrWidth = u8g2_4_gfx.getUTF8Width(temperatureAsCharArray);
  uint16_t x = ((display.width() - tempStrWidth) / 2);
  uint16_t y = yCoordinateCenter + (u8g2_4_gfx.getFontAscent() / 2); // here the height of the font is used to center it in a box, baseline is the lower left of a text box

  display.fillRect(0, yCoordinateCenter - (u8g2_4_gfx.getFontAscent() / 2), display.width(), u8g2_4_gfx.getFontAscent(), GxEPD_WHITE);
  u8g2_4_gfx.setCursor(x, y);
  u8g2_4_gfx.print(temperatureAsCharArray);
  display.displayWindow(0, yCoordinateCenter - (u8g2_4_gfx.getFontAscent() / 2), display.width(), u8g2_4_gfx.getFontAscent());
}

Please note that i want to use the display.end() call as I want to achieve a very low power project.

The serial monitor prints the following:

20:01:05.693 -> Begin update
20:01:05.855 -> _PowerOn : 95703
20:01:06.275 -> _Update_Part : 406250
20:01:07.208 -> _Update_Part : 406250
20:01:15.685 -> Begin update
20:01:15.846 -> _PowerOn : 95704
20:01:16.264 -> _Update_Part : 406250
20:01:17.199 -> _Update_Part : 406250
20:01:25.710 -> Begin update
20:01:25.871 -> _PowerOn : 95704
20:01:26.256 -> _Update_Part : 406250
20:01:27.191 -> _Update_Part : 406250
20:01:35.703 -> Begin update
20:01:35.863 -> _PowerOn : 95703
20:01:36.250 -> _Update_Part : 406250
20:01:37.185 -> _Update_Part : 406250
20:01:45.693 -> Begin update
20:01:45.855 -> _PowerOn : 95704
20:01:46.272 -> _Update_Part : 406250
20:01:47.176 -> _Update_Part : 406250

Could you please assist me on how to get my partial updates working?

1 post - 1 participant

Read full topic


Viewing all articles
Browse latest Browse all 15454

Trending Articles