Text adding to rather than overwriting

Hi all, the sketch below reads some inputs from a sim game to display a numerical output (ILS Frequency if anyone is interested)

It will read the game output fine, but when the frequency is changed, instead of overwriting the text, it is adding to it, so any lit pixels stay lit. I tried a clearDisplay command in the loop part, but this then means that only parts of the text are displayed


#define DCSBIOS_IRQ_SERIAL

#include <DcsBios.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1305.h>
#include "Fonts/FreeSans18pt7b.h"

// Used for software SPI
#define OLED_CLK 13
#define OLED_MOSI 11

// Used for software or hardware SPI
#define OLED_CS 8
#define OLED_DC 9

// Used for I2C or SPI
#define OLED_RESET 10

// software SPI
//Adafruit_SSD1305 display(128, 32, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
// hardware SPI - use 7Mhz (7000000UL) or lower because the screen is rated for 4MHz, or it will remain blank!
Adafruit_SSD1305 display(128, 32, &SPI, OLED_DC, OLED_RESET, OLED_CS, 6000000UL);

// I2C
//Adafruit_SSD1305 display(128, 64, &Wire, OLED_RESET);


void setup()   {                
   {

  display.begin(0x3C); 
  
  delay(1000);
  display.clearDisplay();   // clears the screen and buffer
  display.setFont(&FreeSans18pt7b);
  
}
DcsBios::setup();
}



DcsBios::RotaryEncoder ilsVol("ILS_VOL", "-3200", "+3200", 16, 17);

DcsBios::RotaryEncoder ilsKhz("ILS_KHZ", "DEC", "INC", 18, 19);

DcsBios::RotaryEncoder ilsMhz("ILS_MHZ", "DEC", "INC", 15, 14);

 

void loop() {
  DcsBios::loop();


  display.setTextColor(WHITE, BLACK);
  display.setCursor(66, 27);
  display.print(".");
  display.display();
}

 void onIlsMhzChange(char* newValue) {
  display.setTextColor(WHITE, BLACK);
  display.setCursor(8, 27);
  display.print(newValue);
  display.display();
 
}
DcsBios::StringBuffer<3> ilsMhzStrBuffer(0x116e, onIlsMhzChange);

void onIlsKhzChange(char* newValue) {
  display.setTextColor(WHITE, BLACK);
  display.setCursor(75, 27);
  display.print(newValue);
  display.display();
  
}
DcsBios::StringBuffer<2> ilsKhzStrBuffer(0x1172, onIlsKhzChange);


Can anyone suggest how to get the sketch to refresh the text correctly?

Cheers

Les

You need to erase the previous text before writing the new. There are a number of ways to do this

  • clear the screen - not recommended as it causes screen flicker and can be slow
  • print the original text in the background colour
  • draw a rectangle in the background colour

However you do it, only write to the screen if the data has changed

Ok, thanks - would I have to move the text draw part to setup, or should it be kept in the loop section of the sketch?

Les

You need to erase the previous text by one means or another before you print the new value, so it belongs wherever you do that.

Thanks for the help, I used the fillRectangle function and that has the sketch behaving itself nicely, here's the code

#define DCSBIOS_IRQ_SERIAL

#include <DcsBios.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1305.h>
#include "Fonts/FreeSans18pt7b.h"

// Used for software SPI
#define OLED_CLK 13
#define OLED_MOSI 11

// Used for software or hardware SPI
#define OLED_CS 8
#define OLED_DC 9

// Used for I2C or SPI
#define OLED_RESET 10

// software SPI
//Adafruit_SSD1305 display(128, 32, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
// hardware SPI - use 7Mhz (7000000UL) or lower because the screen is rated for 4MHz, or it will remain blank!
Adafruit_SSD1305 display(128, 32, &SPI, OLED_DC, OLED_RESET, OLED_CS, 6000000UL);

// I2C
//Adafruit_SSD1305 display(128, 64, &Wire, OLED_RESET);


void setup()   {                
   {

  display.begin(0x3C); 
  

//display.display(); // show splashscreen
  delay(1000);
  display.clearDisplay();   // clears the screen and buffer
  display.setFont(&FreeSans18pt7b);
  
}
DcsBios::setup();
}

 

DcsBios::RotaryEncoder ilsVol("ILS_VOL", "-3200", "+3200", 16, 17);

DcsBios::RotaryEncoder ilsKhz("ILS_KHZ", "DEC", "INC", 18, 19);

DcsBios::RotaryEncoder ilsMhz("ILS_MHZ", "DEC", "INC", 15, 14);

 

void loop() {
  DcsBios::loop();

  display.display();
  display.setTextColor(WHITE, BLACK);
  display.setCursor(66, 27);
  display.print(".");
  display.display();
}

 void onIlsMhzChange(char* newValue) {
  display.fillRect(0, 0, 65, 32, BLACK);
  display.setTextColor(WHITE, BLACK);
  display.setCursor(8, 27);
  display.print(newValue);
  display.display();
 
}

void onIlsKhzChange(char* newValue) {
  display.fillRect(75, 0, 50, 32, BLACK);
  display.setTextColor(WHITE, BLACK);
  display.setCursor(75, 27);
  display.print(newValue);
  display.display();
  
}

DcsBios::StringBuffer<2> ilsKhzStrBuffer(0x1172, onIlsKhzChange);
DcsBios::StringBuffer<3> ilsMhzStrBuffer(0x116e, onIlsMhzChange);

Cheers

Hello @Lesthegringo -

This code chunk is how I solve TFT and OLED text overwrite. Rather than clearing the area, I overwrite the existing character/data in the background color before the next char/data is printed.

  // only redraw potentiometer value if value has changed
  if (potNEW != potOLD) {

    // redraw old pot value in BLACK to erase old value
    display.setCursor(70, 10);
    display.setTextColor(BLACK);
    spacepad(potOLD);
    display.print(potOLD);
    // display.display(); // do NOT update display, it will cause flicker

    // draw new pot value in WHITE
    display.setCursor(70, 10);
    display.setTextColor(WHITE);
    spacepad(potNEW);
    display.print(potNEW);
    display.display();

    potOLD = potNEW; // update old data
  }

Here is the code in a simulation:

Thanks, while I managed to make my sketch work, this is great for future reference

For learning purposes, what is the function of the 'spacepad' command?

Cheers

Les

Spacepad is something I wrote, and add to my programs to "right-justify" a changing number value. The algorithm is "if a value is less than 1000 (three numbers or less), then add a space (or leading zero), then if the value is less than 100 (two numbers or less) add another space (or leading zero), then if the value is less than 10 (one number), add a space (or zero). I also use an extended version of padding for when the value drops into the negative side of the numberline (-55, for example) .

void spacepad(int pot) {
  // spacepadding or zeropadding creates right-alignment
  if (pot < 1000) display.print(" ");
  if (pot < 100) display.print(" ");
  if (pot < 10) display.print(" ");
}
1 Like

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