Close

Minimizing redraw flicker

A project log for Pill dispenser robot

An intelligent robot that manages my medication regimen.

m-bindhammerM. Bindhammer 05/01/2023 at 16:550 Comments

Redraw flicker is mostly an issue with color LCD or OLED screens, where graphics are rendered with every function call. To minimize the effect I had to use an offscreen canvas, respectively the 1-bit canvas type for the animated robot face. You can think of it as all the graphics primitives or text that are on the canvas are converted to a bitmap and then drawn on the OLED.

// Screen dimensions
#define SCREEN_WIDTH  128
#define SCREEN_HEIGHT 128 

// Use HW SPI (MOSI, SCK, MISO) and those pins
#define DC_PIN   4
#define CS_PIN   5
#define RST_PIN  6

// Color definitions
#define    BLACK        0x0000
#define    BLUE         0x001F
#define    RED          0xF800
#define    GREEN        0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0  
#define WHITE           0xFFFF

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>
#include <SPI.h>

Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, CS_PIN, DC_PIN, RST_PIN);
GFXcanvas1 canvas(126, 58);
bool MAGENTA_prim = true;

void setup(void) {
  tft.begin();
  randomSeed(analogRead(0));
  tft.fillScreen(WHITE);
}

void loop() {
  // Only draw once and not on the canvas
  if(MAGENTA_prim == true) {
    tft.fillRoundRect(10, 59, 22, 10, 5, MAGENTA); 
    tft.fillRoundRect(98, 59, 22, 10, 5, MAGENTA);
    MAGENTA_prim = false;
  }
  canvas.fillScreen(0);    // Clear canvas (not display)
  int randmouth1 = random(-4, 4);
  canvas.fillCircle(20, 27, 18, WHITE);
  canvas.fillCircle(17 + randmouth1, 24 + randmouth1, 4, BLACK);
  canvas.fillCircle(107, 27, 18, WHITE); 
  canvas.fillCircle(104 + randmouth1, 24 + randmouth1, 4, BLACK);
  // Talking
  int randmouth2 = random(7, 22);
  canvas.fillCircle(64, 41, 16, WHITE);
  canvas.fillRect(48, randmouth2, 33, 32, BLACK);
  tft.drawBitmap(0, 0, canvas.getBuffer(),
  canvas.width(), canvas.height(), BLACK, WHITE);
}

Discussions