GC9A01 and Arduino Nano: Flashing Characters when displaying counter

Hello,
I recently purchased this LCD module from amazon to use in a metronome project:

In conjunction with an Arduino Nano 5V 16 Mhz, I was able to get the display to run the example given in the Arduino_GFX Library by moonournation:

I proceeded to set up a rotary encoder to increment/decrement an integer and display it on the LCD.
The problem I have is changing the value on the LCD. The best way I've found to get rid of the old text so far is by printing over the old value with the color set to be that of the Background. Then proceed to print the new value (in non-background color). This is the best solution found so far but parts of the LCD still "flash" when updating values. It's minute but still noticeable and undesirable.

I'm wondering if this is a limitation of the nano or if there's a better solution in the code. If anyone has had any experience with it, I would be grateful to hear. My code is posted below. Thank you.

#include <SPI.h>
#include <RotaryEncoder.h>
#include <Arduino_GFX_Library.h>
#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Fonts/FreeSans18pt7b.h>
#include <Fonts/FreeSans12pt7b.h>


// Example for Arduino UNO with input signals on pin 2 and 3
#define PIN_IN1 2
#define PIN_IN2 3

#define INC_ACC 4
#define DEC_ACC 5

#define BUZZER 10

//Metronome Parameters
int newBPM = 0;
int bpm = 100;
int minBPM = 40;
int maxBPM = 240;
int accent = 0;

char buf[20];

#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */

Arduino_DataBus *bus = create_default_Arduino_DataBus();

Arduino_GFX *gfx = new Arduino_GC9A01(bus, 7 /* RST */, 0 /* rotation */, true /* IPS */);
#endif /* !defined(DISPLAY_DEV_KIT) */

// Setup a RotaryEncoder with 2 steps per latch for the 2 signal input pins:
RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);

void SetBpm(){
encoder.tick();
  newBPM = encoder.getPosition()/2;
  if (bpm != newBPM) {
    if(newBPM > maxBPM){ newBPM = maxBPM;encoder.setPosition(maxBPM*2);}
    else if(newBPM < minBPM) { newBPM = minBPM; encoder.setPosition(minBPM*2);}

    //Erase Previous
    gfx->setFont(&FreeSans18pt7b);
    gfx->setCursor(75, 75);
    gfx->setTextColor(BLACK);
    gfx->setTextSize(2);
    gfx->print(bpm);
    

    //Draw New
    gfx->setFont(&FreeSans18pt7b);
    gfx->setCursor(75, 75);
    gfx->setTextColor(BLUE);
    gfx->setTextSize(2);
    gfx->print(newBPM);

    //Draw BPM
    gfx->setFont(&FreeSans18pt7b);
    gfx->setCursor(75, 150);
    gfx->setTextSize(1);
    gfx->print("  ");
    gfx->println("BPM");
    
    

    // Serial.print("pos:");
    // Serial.print(newBPM);
    // Serial.print(" dir:");
    // Serial.println((int)(encoder.getDirection()));
    bpm = newBPM;
  }
}

void setup() {
  Serial.begin(9600);
  Serial.println("Starting Encoder");
  encoder.setPosition(200);

  //Accent Buttons
  pinMode(INC_ACC, INPUT_PULLUP);
  pinMode(DEC_ACC, INPUT_PULLUP);
  //Buzzer
  pinMode(BUZZER, OUTPUT);

  //LCD
  gfx->begin();
  gfx->fillScreen(BLACK);
  #ifdef DF_GFX_BL
    pinMode(DF_GFX_BL, OUTPUT);
    digitalWrite(DF_GFX_BL, HIGH);
  #endif

      gfx->setCursor(50, 50);
    gfx->setTextColor(RED);
    gfx->setFont(&FreeSans18pt7b);
    gfx->println("Hello World!");
    Serial.println("Printed hollo");
    delay(2000); // 5 second
     gfx->setCursor(50, 50);
    gfx->fillScreen(BLACK);
}

void loop() {
  SetBpm();
}

Try

gfx->setTextColor(BLUE, BLACK);

This should print your new text and erase the background at the same time.

However, it does not work for "custom fonts", only "built-in fonts". I'm not sure which you are using.

Hi Paul, thanks for the reply. I just tried it out and it seems to still have the flashing effect and text in different places doesn't get cleared (i.e. going from a three-digit to two-digit number). Also, other text on the screen (such as the "BPM" Text) begins to flash as well. I'm assuming because this function changes the whole background. Thank you though.

Post your updated code. Maybe you didn't change it correctly.

That can be fixed in your code, like this:

    char buffer[4];
    sprint(buffer, "%3d", newBPM);
    gfx->print(buffer);

I don't think it does that.

Hi Paul, I realized I forgot to change the custom font I was using and that's why it wasn't working but it seems to be working now without the Flashing. I also tried the sprintf and it fixed that problem as well. I thought it changed the whole background because the "BPM" text was flashing too but I just had to do another setTextColor in order to get rid of the background.

Here's the updated function:

void SetBpm(){
encoder.tick();
  newBPM = encoder.getPosition()/2;
  if (bpm != newBPM) {
    if(newBPM > maxBPM){ newBPM = maxBPM;encoder.setPosition(maxBPM*2);}
    else if(newBPM < minBPM) { newBPM = minBPM; encoder.setPosition(minBPM*2);}

    //sprintf(buf, "%3d %3d %3d %3d ", bpm, fr, rl, rr);
    //Erase Previous
    // gfx->setFont(&FreeSans18pt7b);
    // gfx->setCursor(75, 75);
    // gfx->setTextColor(BLACK, BLACK);
    // gfx->setTextSize(2);
    // gfx->print(bpm);
    

    //Draw New
    gfx->setFont();
    gfx->setCursor(75, 75);
    gfx->setTextColor(BLUE, BLACK);
    gfx->setTextSize(5);
    char buffer[4];
    sprintf(buffer, "%3d", newBPM);
    gfx->print(buffer);
    //gfx->print(newBPM);

    //Draw BPM
    gfx->setFont(&FreeSans18pt7b);
    gfx->setCursor(75, 150);
    gfx->setTextSize(1);
    gfx->setTextColor(BLUE);
    gfx->println("BPM");
    
    

    // Serial.print("pos:");
    // Serial.print(newBPM);
    // Serial.print(" dir:");
    // Serial.println((int)(encoder.getDirection()));
    bpm = newBPM;
  }
}

I know beggars can't be choosers but I'm assuming there are no workarounds for using a custom font? Either way thanks for your help, this has been killing me the past few days.

Read this.

It does not explain why background colour does not work for custom fonts, only that it doesn't.

It mentions using a "canvas" but I don't know if your Nano will have enough RAM memory for that.

Also, I forgot that your code had char buf[20]; already defined. You can just re-use that instead of declaring a new char buffer[4];.

Awesome, I'll look into it. Thanks for all your help!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.