Skip to content

Fix the screen flickering so it can be smooth #206

Open
@BimoSora2

Description

@BimoSora2

I hope there is an improvement when blinking so that it is smooth

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <SPI.h>
#include <Wire.h>

#include <Fonts/SwanseaBold_D0ox7pt7b.h>

#define TFT_MOSI  D7
#define TFT_SCLK  D5
#define TFT_CS    D8
#define TFT_DC    D3
#define TFT_RST   D4

#define MARGIN 5
#define TEXT_HEIGHT 10

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
Adafruit_BMP280 bmp;
Adafruit_MPU6050 mpu;

float temperature = 0, pressure = 0, altitude = 0;

String tempC, tempF, pressureStr, altitudeStr;
String accX = "X: 0", accY = "Y: 0", accZ = "Z: 0";
String prevTempC, prevTempF, prevPressureStr, prevAltitudeStr;
String prevAccX = "", prevAccY = "", prevAccZ = "";

bool bmpAvailable = false;
bool mpuAvailable = false;
bool isInverted = true;

unsigned long sensorMillis1 = 0;
const long sensorInterval1 = 1000;

unsigned long sensorMillis2 = 0;
const long sensorInterval2 = 1000;

struct TextDimensions {
    int16_t x;
    int16_t y;
    uint16_t w;
    uint16_t h;
    String text;
};

TextDimensions prevDimensions[7];

uint16_t safeColor565(int r, int g, int b) {
    r = constrain(r, 0, 255);
    g = constrain(g, 0, 255);
    b = constrain(b, 0, 255);
    uint8_t r5 = round(r * 31.0 / 255.0);
    uint8_t g6 = round(g * 63.0 / 255.0);
    uint8_t b5 = round(b * 31.0 / 255.0);
    return (r5 << 11) | (g6 << 5) | b5;
}

void getTextBounds(const String& text, int y, TextDimensions& dims) {
    int16_t x1, y1;
    uint16_t w, h;
    tft.getTextBounds(text, 0, 0, &x1, &y1, &w, &h);
    dims.w = w;
    dims.h = h;
    dims.x = (tft.width() - w) / 2;
    dims.y = y;
    dims.text = text;
}

void clearPreviousText(int index) {
    if (prevDimensions[index].text.length() > 0) {
        tft.fillRect(
            prevDimensions[index].x - 2,
            prevDimensions[index].y - prevDimensions[index].h - 2,
            prevDimensions[index].w + 4,
            prevDimensions[index].h + 4,
            safeColor565(0, 0, 0)
        );
    }
}

void centerText(const String& text, int y, uint16_t textColor, int index) {
    TextDimensions currentDims;
    getTextBounds(text, y, currentDims);
    
    clearPreviousText(index);
    
    prevDimensions[index] = currentDims;
    
    tft.setTextColor(textColor);
    tft.setCursor(currentDims.x, currentDims.y);
    tft.print(text);
}

void drawDottedLine(int xStart, int y, int length, int dotSpacing, uint16_t color) {
    for (int x = xStart; x < xStart + length; x += dotSpacing) {
        tft.drawPixel(x, y, color);
    }
}

void drawBlinkingBox(int y, int height, uint16_t color) {
    int width = 80;
    int xStart = (tft.width() - width) / 2;
    
    tft.fillRect(xStart, y - height/2, width, height, safeColor565(0, 0, 0));
    delay(50);
}

String getValidValue(float value, int decimal, String unit) {
    if (isnan(value) || isinf(value)) {
        return "0" + unit;
    }
    return String(value, decimal) + unit;
}

void displayBMP280Data() {
    if (tempC != prevTempC) {
        drawBlinkingBox(29, 15, 0);
        centerText(tempC, 29, safeColor565(255, 255, 255), 0);
        prevTempC = tempC;
    }

    drawDottedLine(38, 35, 55, 4, safeColor565(100, 100, 100));

    if (tempF != prevTempF) {
        drawBlinkingBox(52, 15, 0);
        centerText(tempF, 52, safeColor565(221, 125, 64), 1);
        prevTempF = tempF;
    }

    if (pressureStr != prevPressureStr) {
        drawBlinkingBox(68, 15, 0);
        centerText(pressureStr, 68, safeColor565(255, 100, 100), 2);
        prevPressureStr = pressureStr;
    }

    if (altitudeStr != prevAltitudeStr) {
        drawBlinkingBox(83, 15, 0);
        centerText(altitudeStr, 83, safeColor565(24, 218, 61), 3);
        prevAltitudeStr = altitudeStr;
    }
}

void displayMPU6050Data() {
    if (accX != prevAccX) {
        drawBlinkingBox(111, 15, 0);
        centerText(accX, 111, safeColor565(221, 67, 196), 4);
        prevAccX = accX;
    }

    if (accY != prevAccY) {
        drawBlinkingBox(126, 15, 0);
        centerText(accY, 126, safeColor565(101, 111, 188), 5);
        prevAccY = accY;
    }

    if (accZ != prevAccZ) {
        drawBlinkingBox(141, 15, 0);
        centerText(accZ, 141, safeColor565(249, 218, 188), 6);
        prevAccZ = accZ;
    }
}

void setup() {
    Serial.begin(115200);
    Serial.println("Booting...");

    tft.initR(INITR_GREENTAB);
    delay(100);
    tft.invertDisplay(isInverted);
    tft.setAddrWindow(0, 0, 160, 80);
    tft.setRotation(0);
    tft.fillScreen(safeColor565(0, 0, 0));
    tft.setFont(&SwanseaBold_D0ox7pt7b);
    tft.setTextSize(1);

    bmpAvailable = bmp.begin(0x76);
    if (!bmpAvailable) {
        Serial.println("BMP280 not found! Continuing with default values...");
    }

    mpuAvailable = mpu.begin();
    if (!mpuAvailable) {
        Serial.println("MPU6050 not found! Continuing without IMU data...");
    }

    uint16_t borderColor = safeColor565(30, 30, 30);
    tft.drawRect(0, 0, tft.width(), tft.height(), borderColor);

    for (int i = 0; i < 7; i++) {
        prevDimensions[i].text = "";
    }
}

void loop() {
    if (bmpAvailable) {
        temperature = bmp.readTemperature();
        pressure = bmp.readPressure() / 100.0F;
        altitude = bmp.readAltitude(1013.25);
    }

    float fahrenheit = (temperature * 9 / 5) + 32;

    tempC = getValidValue(temperature, 1, " *C");
    tempF = getValidValue(fahrenheit, 1, " *F");
    pressureStr = getValidValue(pressure, 0, " hPa");
    altitudeStr = getValidValue(altitude, 1, " m");

    sensors_event_t a, g, temp;

    if (mpuAvailable) {
        mpu.getEvent(&a, &g, &temp);
        accX = "X: " + getValidValue(a.acceleration.x, 1, "");
        accY = "Y: " + getValidValue(a.acceleration.y, 1, "");
        accZ = "Z: " + getValidValue(a.acceleration.z, 1, "");
    }

    if(millis() - sensorMillis1 >= sensorInterval1) {
        sensorMillis1 = millis();
        displayBMP280Data();
    }

    if(millis() - sensorMillis2 >= sensorInterval2) {
        sensorMillis2 = millis();
        displayMPU6050Data();
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions