SOLVED can I just clear one symbol on a SSD1306

Maybe they are not called symbols but if I want to, for instance, put a clock on the screen and update it every second I can do
display.write(number);
display.display();
where number is a number derived from using millis and subtracting previous millis from millis in the usual fashion.
is it possible to clear the last number to replace it with a new one?
If I just enter the new number and just do
display.write(); (new number);
display.display();
it overwrites the last one, if I do
display.cleardisplay();
display.write(); (new number);
display.display();
it flashes the whole screen every second which is very distracting.
Is it possible to clear the buffer at just the one symbol ?
I have tried writing a symbol that is just a clear space in the font list but it only adds to the buffer area and doesn't clear it.
thanks

It depends which SSD1306 library you are using.

A regular Adafruit_GFX style library can use display.setTextColor(WHITE, BLACK) and the regular System 7x5 font draws background with each letter. i.e. the fresh value rubs out the previous.

If you want to use a Transparent font, you must call display.fillRect() to draw a fresh background.

Many SSD1306 libraries write into a buffer. You only see the result with display.display()
So it does not matter how convoluted you are. The result is instant when you call display.display()

David.

1 Like

I think I am using the adafruit_GFX you mention. I have tried to get what I think is your suggestion to work.
It looks as if the buffer still has the 'other' letter in it (I am trying to switch between A and B just to test the system.

#include <SPI.h>  //SDA to A4    SCL to A5
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
void setup()   
{                
  Serial.begin(9600);
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  display.clearDisplay();
}
void loop() {
  testfont();
}
void testfont(void)
{
display.setCursor(0,0);
  display.setTextSize(4);
  display.setTextColor(WHITE);
  display.write(65);
  display.display();
  delay(1000);
  display.setCursor(0,0);
  display.setTextColor(WHITE,BLACK);
  display.write(65);
  display.display();
  display.setCursor(0,0);
  display.setTextColor(WHITE);
  display.write(66);
  display.display();
  delay(1000);
  display.setCursor(0,0);
  display.setTextColor(WHITE,BLACK);
  display.write(66);
  display.display();
}

It still overwrites the block and I get a combination of both letters.?

AH! I altered the two lines with (BLACK,WHITE)in them to just (BLACK) and it looks as if it is working .I will do a bit more experimenting and report back here when I get what I want or not.

Try this:

#include <SPI.h>  //SDA to A4    SCL to A5
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
void setup()
{
    Serial.begin(9600);
    // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
    display.clearDisplay();
}
void loop() {
    testfont();
}
void testfont(void)
{
    display.setCursor(0, 0);
    display.setTextSize(4);
    display.setTextColor(WHITE);
    display.write('A');
    display.display();
    delay(1000);
    display.setCursor(0, 0);
    display.setTextColor(WHITE, BLACK);
    display.write('B');
    display.display();
    delay(1000);
    display.setCursor(0, 0);
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.print("transparent");
    display.display();
    delay(1000);
    display.setCursor(0, 0);
    display.setTextColor(WHITE, BLACK);
    display.print("overwrite");
    display.display();
    delay(1000);
    display.setCursor(0, 0);
    display.print("           ");
}

Thank you David,
I didn't try your program, I continued developing it myself.

Thanks to your hints I have made what I think is a good start to a counter/timer.
I have included as far as I have to date in case anyone else could use it as a start.

I would like to thank Limor Fried / Ladyada at Adafruit Industries for her initial sketch.
Her contributions often save me hours of searching.

/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/category/63_98

This example is for a 128x32 size display using I2C to communicate
3 pins are required to interface (2 I2C and one reset)

Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!

Written by Limor Fried/Ladyada  for Adafruit Industries.  
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
#include <SPI.h>  //SDA to A4    SCL to A5
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
int b=0;
int t=0;
int mt=0;
const long interval = 1000;
unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
void setup()   {                
  Serial.begin(9600);
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  // init done
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);
  //clear the adafruiy splashscreen
  display.clearDisplay();
  display.setCursor(12,8);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.print("00:00:00");
  display.display();  
}
void loop() 
{
  seconds();
}
void seconds(void) //draw the alphabet
{
  display.setCursor(0,0);
  display.setTextSize(1);
  display.setTextColor(WHITE);
  for (uint8_t i=0; i < 22; i++) //168
  {
    if (i == '\n') continue;
    display.write(i+65);
  }
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) 
    {
    previousMillis = currentMillis;// save the last time you changed the number
    display.setCursor(96,8);
    display.setTextSize(2);
    display.setTextColor(BLACK);
    //display.write(b+(28,DEC));
    delay(5);
    display.write(b+(48));
    delay(5);
    display.display();
    b++;
    if (b==10)
      {
      tenseconds();
      b=0;
      }
    delay(5);
    display.setCursor(96,8);
    display.setTextColor(WHITE);
    delay(5);
    display.write(b+48);
    delay(5);
    display.display();
    }
  display.setCursor(0,24);
  display.setTextSize(1);
  for (uint8_t i=0; i < 22; i++) //168
    {
    if (i == '\n') continue;
      display.write(i+65);
    }
  display.display();
}
void tenseconds()
{
  display.setCursor(84,8);
  display.setTextSize(2);
  display.setTextColor(BLACK);
  display.write(t+(48));
  display.display();
  t++;
  if (t==6)
    {
    t=0;
    minutes();
    }
  display.setCursor(84,8);
  display.setTextColor(WHITE);
  display.write(t+48);
  display.display();
}
void minutes()
{
  display.setCursor(60,8);
  display.setTextSize(2);
  display.setTextColor(BLACK);
  display.write(mt+(48));
  display.display();
  mt++;
  if (mt==10)
    {
    mt=0;
    //tminutes();
    }
  display.setCursor(60,8);
  display.setTextColor(WHITE);
  display.write(mt+48);
  display.display();
}

It is always worth keeping "up to date" with Adafruit libraries. They have changed substantially over the years.

This is my build report for the sketch you pasted in #5

Using library SPI at version 1.0 in folder: C:\Program Files (x86)\Arduino-1.8.9\hardware\arduino\avr\libraries\SPI 
Using library Wire at version 1.0 in folder: C:\Program Files (x86)\Arduino-1.8.9\hardware\arduino\avr\libraries\Wire 
Using library Adafruit_GFX_Library at version 1.6.1 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_GFX_Library 
Using library Adafruit_SSD1306 at version 2.0.1 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_SSD1306 
"C:\\Program Files (x86)\\Arduino-1.8.9\\hardware\\tools\\avr/bin/avr-size" -A "C:\\Users\\DAVIDP~1\\AppData\\Local\\Temp\\arduino_build_936373/matelot_print.ino.elf"
Sketch uses 14498 bytes (44%) of program storage space. Maximum is 32256 bytes.
Global variables use 532 bytes (25%) of dynamic memory, leaving 1516 bytes for local variables. Maximum is 2048 bytes.

Note that the constructor syntax is different. And the buffer allocation is probably different too.

//Adafruit_SSD1306 display(OLED_RESET);
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);

Yes, Adafruit produce excellent libraries, tutorials, products, ...

Your example shows one way to "rub out" a previous letter.
i.e. draw previous in BLACK. draw new letter in WHITE. remember this "letter" because you need it for next time.

A simpler method is to just use setColor(WHITE, BLACK)
This draws the new letters with foreground=WHITE and background=BLACK.
You do not need to remember previous letter.

Another method is to use fillRect(BLACK) to rub out the previous contents.
Then use setColor(WHITE) to draw new letters in transparent mode on a freshly cleaned background.

Adafruit tutorials and examples should explain these techniques.

David.