Need to Clear Extra Digits from UNO Display

I've recently added an SSD1309_128X64 driven display to my UNO R4. I'm reading Analog A0 (10-bit) calculating the voltage and full scale percent and passing that data to the display.
This works well, except any digit not overwritten stays. For instance, the percentage starts at 0.00. It ramps up fine to 100.00, but when I ramp it back down, it leaves the two trailing zeros that it generated when it displayed 100.00, making it appear as 0.0000 instead of reverting back to 0.00.
I've tried several ways of clearing this data, including clear and clearLine, but this produces an annoying flash to the display before it redraws, even when I remove the delay time completely.
Is there a better way to clear these extra digits as the value moves up and down within the range?
Thanks.

/*

  Display_ADC.ino
  
  ADC Values for U8x8 API

  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)

*/

#include <Arduino.h>
#include <U8x8lib.h>

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

// Please UNCOMMENT one of the contructor lines below
// U8x8 Contructor List 
// The complete list is available here: https://github.com/olikraus/u8g2/wiki/u8x8setupcpp
// Please update the pin numbers according to your setup. Use U8X8_PIN_NONE if the reset pin is not connected
U8X8_SSD1309_128X64_NONAME0_4W_SW_SPI u8x8(/* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);

float floatMap(float x, float in_min, float in_max, float out_min, float out_max) {
  // Map a float value from one range to another.
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void setup(void)
{
  u8x8.begin();
  u8x8.setPowerSave(0);

  // Begin serial communication with a baud rate of 9600:
  Serial.begin(9600);
  analogReadResolution(10); //change adc to 14-bit resolution  
}

void loop(void)
{
  // Retrieve analog value from pin A0:
  int adc_value = analogRead(A0);
  // Convert the analog value to a voltage (0-5V range):
  float voltage = floatMap(adc_value, 0, 1023, 0, 5);

  // Add a percentage calculation based on the adc value
  float percentage;
  int total_marks = 1023;

  percentage = (float) adc_value / total_marks * 100.0;

  // Output the analog value, corresponding voltage and percentage to the serial monitor:
  Serial.print("Analog Count: ");
  Serial.print(adc_value);
  Serial.print(", Voltage: ");
  Serial.print(voltage);
  Serial.print("V");
  Serial.print(", Percentage: ");
  Serial.print(percentage);
  Serial.println("%");
  // Wait for a second before repeating the loop:
  delay(100);

  //Display Info
  u8x8.setFont(u8x8_font_amstrad_cpc_extended_f); // 8 x 8 Font
  //u8x8.setFont(u8x8_font_px437wyse700b_2x2_r); // 2 x 2 Font
  //u8x8.setFont(u8x8_font_inb33_3x6_n); // 3 x 6 Font
  //u8x8.setFont(u8x8_font_open_iconic_weather_4x4);
  //u8x8.setFont(u8x8_font_chroma48medium8_r); // 8 x 8 Font
  //u8x8.setFont(u8x8_font_px437wyse700a_2x2_r); //16 x 16 Font
  //u8x8.drawString(2,1,adc_value,"COUNT");
  //u8x8.drawString(2,2,voltage,"VOLTS");
  //u8x8.drawString(2,3,percentage,"PERCENT");
  u8x8.setCursor(0,0); u8x8.print("COUNT:"); u8x8.setCursor(8,0); u8x8.print(adc_value); 
  u8x8.setCursor(0,1); u8x8.print("VOLTS:"); u8x8.setCursor(8,1); u8x8.print(voltage);
  u8x8.setCursor(0,2); u8x8.print("PCT:"); u8x8.setCursor(8,2); u8x8.print(percentage);
  //u8x8.refreshDisplay();		// only required for SSD1606/7  
  //delay(50);

  //u8x8.clearLine(0);
  //u8x8.clear();
  }

I'm not familiar with the display but if the numeric field is a fixed size you could send a string of blanks of that size to wipe any previous data, then send a new value.

2 Likes

After printing the number, print as many blanks as required to erase any trailing digits from the previous number (the number of digits displayed by the largest number - the number of digits displayed by the smallest). That assumes no wrap around and that your library doesn't try to get clever with blank characters.

1 Like

In my code I am a bit of an old timer. I write my numbers as a fixed number of positions and space fill the unused positions. Works nicely and no extra flashing.

2 Likes

I just use the LiquidCrystal_I2C library, and I clear the screen before every write. I see no flashing.

2 Likes
  1. Store new data (numbers, characters, icons) and x,y position
  2. display.write(data) in WHITE
  3. Immediately before the data is to be changed on the OLED, position cursor at stored x,y and display.write(data) in BLACK
  4. GOTO 1
2 Likes

Thanks for all the advice. I'm good to go now.