Open
Description
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
Labels
No labels