add software debounce

This commit is contained in:
melody 2025-08-18 13:54:26 +02:00
commit 5fd1543e3f

View file

@ -4,15 +4,15 @@
#include <ArtronShop_SHT3x.h> #include <ArtronShop_SHT3x.h>
#include <SPI.h> #include <SPI.h>
#include <Adafruit_GFX.h> #include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h> #include <Adafruit_ST7735.h>
ArtronShop_SHT3x sht3x(0x44, &Wire); ArtronShop_SHT3x sht3x(0x44, &Wire);
#define TFT_CS 10 #define TFT_CS 10
#define TFT_RST 9 #define TFT_RST 9
#define TFT_DC 8 #define TFT_DC 8
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // Set HW SPI pins Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // Set HW SPI pins
#define BACKGROUND_COLOUR ST77XX_BLACK #define BACKGROUND_COLOUR ST77XX_BLACK
#define PRIMARY_FOREGROUND_COLOUR tft.color565(187, 0, 255) #define PRIMARY_FOREGROUND_COLOUR tft.color565(187, 0, 255)
@ -20,7 +20,7 @@ Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // Set HW SPI pi
const int buttonPin = 16; const int buttonPin = 16;
const int AMOUNT_DATAPOINTS = 30; // ~120 max on Arduino Nano (2kB SRAM) const int AMOUNT_DATAPOINTS = 30; // ~120 max on Arduino Nano (2kB SRAM)
const float WAIT_TIME = 60; const float WAIT_TIME = 60;
class DataStorage { class DataStorage {
@ -46,12 +46,14 @@ public:
} }
float getDataByIndex(int logicalIndex) { float getDataByIndex(int logicalIndex) {
if(logicalIndex < 0 || logicalIndex >= this->rCount) return 0; if (logicalIndex < 0 || logicalIndex >= this->rCount) return 0;
int realIndex = (this->rIndex + this->MAX_DATA_POINTS - this->rCount + logicalIndex) % this->MAX_DATA_POINTS; // pain int realIndex = (this->rIndex + this->MAX_DATA_POINTS - this->rCount + logicalIndex) % this->MAX_DATA_POINTS; // pain
return this->data[realIndex]; return this->data[realIndex];
} }
int getCursor() const { return this->rCount; } int getCursor() const {
return this->rCount;
}
float getMaxDataPoint() { float getMaxDataPoint() {
if (this->rCount == 0) return 0; if (this->rCount == 0) return 0;
@ -82,7 +84,9 @@ public:
return sum / this->rCount; return sum / this->rCount;
} }
String getUnit() { return this->UNIT; } String getUnit() {
return this->UNIT;
}
}; };
class Element { class Element {
@ -110,7 +114,7 @@ public:
}; };
class MaxAvgMinElement : public Element { class MaxAvgMinElement : public Element {
public: public:
using Element::Element; using Element::Element;
void render() override { void render() override {
if (this->DRAW_BOARDER) this->drawBoarder(); if (this->DRAW_BOARDER) this->drawBoarder();
@ -130,7 +134,6 @@ class MaxAvgMinElement : public Element {
tft.print(F("Min: ")); tft.print(F("Min: "));
tft.print(this->data.getMinDataPoint(), 1); tft.print(this->data.getMinDataPoint(), 1);
tft.print(unit); tft.print(unit);
}; };
}; };
@ -144,7 +147,9 @@ private:
return X + 2 + (int)(i * (this->WIDTH - 3) / (this->AMOUNT_DATAPOINTS - 1)); return X + 2 + (int)(i * (this->WIDTH - 3) / (this->AMOUNT_DATAPOINTS - 1));
} }
int getScaledY(float value) { return this->getScaledY(value, this->data.getMinDataPoint(), this->data.getMaxDataPoint()); }; // OOP is soo cool int getScaledY(float value) {
return this->getScaledY(value, this->data.getMinDataPoint(), this->data.getMaxDataPoint());
}; // OOP is soo cool
int getScaledY(float value, float minY, float maxY) { int getScaledY(float value, float minY, float maxY) {
if (maxY - minY == 0) return this->Y + this->HEIGHT / 2; if (maxY - minY == 0) return this->Y + this->HEIGHT / 2;
@ -163,7 +168,7 @@ public:
int count = this->data.getCursor(); int count = this->data.getCursor();
if (count == 0) return; if (count == 0) return;
const float minY = this->data.getMinDataPoint(); const float minY = this->data.getMinDataPoint();
const float maxY = this->data.getMaxDataPoint(); const float maxY = this->data.getMaxDataPoint();
@ -187,28 +192,30 @@ class Screen {
protected: protected:
Element** elements; Element** elements;
public: public:
Screen(Element** elems) : elements(elems){}; Screen(Element** elems)
void draw(){ : elements(elems){};
for(int i = 0; this->elements[i] != nullptr; i++) { void draw() {
for (int i = 0; this->elements[i] != nullptr; i++) {
this->elements[i]->render(); this->elements[i]->render();
}; };
}; };
}; };
class DisplayConfig { class DisplayConfig {
private: private:
Screen** screens; Screen** screens;
int screenIndex; int screenIndex;
int screenCount; int screenCount;
public: public:
DisplayConfig(Screen** screens) : screens(screens), screenIndex(0), screenCount(0){ DisplayConfig(Screen** screens)
: screens(screens), screenIndex(0), screenCount(0) {
while (this->screens[this->screenCount] != nullptr) this->screenCount++; while (this->screens[this->screenCount] != nullptr) this->screenCount++;
tft.initR(INITR_MINI160x80); tft.initR(INITR_MINI160x80);
tft.setRotation(1); tft.setRotation(1);
tft.fillScreen(BACKGROUND_COLOUR); tft.fillScreen(BACKGROUND_COLOUR);
}; };
Screen* applyScreen(int index){ Screen* applyScreen(int index) {
this->screenIndex = index; this->screenIndex = index;
tft.fillScreen(BACKGROUND_COLOUR); tft.fillScreen(BACKGROUND_COLOUR);
return this->screens[index]; return this->screens[index];
@ -218,17 +225,23 @@ class DisplayConfig {
return this->applyScreen(this->screenIndex); return this->applyScreen(this->screenIndex);
} }
Screen* getCurrentScreen() {return this->screens[this->screenIndex];} Screen* getCurrentScreen() {
Screen* getCurrentScreenIndex() {return this->screenIndex;} return this->screens[this->screenIndex];
}
Screen* getCurrentScreenIndex() {
return this->screenIndex;
}
}; };
unsigned long previousMillis = -1000000000; unsigned long previousMillis = -1000000000;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
bool buttonPressedLastCycle = false; bool buttonPressedLastCycle = false;
bool sht3xErrorLastCycle = false; bool sht3xErrorLastCycle = false;
// CONFIG START // CONFIG START
DataStorage* tempData; DataStorage* tempData;
DataStorage* humData; DataStorage* humData;
@ -274,7 +287,7 @@ void setup() {
screenBigHum = new Screen(elemBigArrHum); screenBigHum = new Screen(elemBigArrHum);
// Screen 'collections' / arrays: Arguments: Array containing pointers to screens, nullptr must be at the end. // Screen 'collections' / arrays: Arguments: Array containing pointers to screens, nullptr must be at the end.
static Screen* screenArr[] = { screenTemp, screenHum, screenBigTemp, screenBigHum, nullptr}; static Screen* screenArr[] = { screenTemp, screenHum, screenBigTemp, screenBigHum, nullptr };
// Config. Arguments: A screen array. // Config. Arguments: A screen array.
config = new DisplayConfig(screenArr); config = new DisplayConfig(screenArr);
@ -312,7 +325,7 @@ void loop() {
tempData->addData(temp); tempData->addData(temp);
humData->addData(hum); humData->addData(hum);
currentScreen->draw(); currentScreen->draw();
@ -330,15 +343,17 @@ void loop() {
tft.print(F("SENSOR\nREAD\nERROR")); tft.print(F("SENSOR\nREAD\nERROR"));
delay(500); delay(500);
Wire.begin(); Wire.begin();
sht3x.begin(); sht3x.begin();
sht3xErrorLastCycle = true; sht3xErrorLastCycle = true;
} }
} }
if (digitalRead(buttonPin)){
if (!buttonPressedLastCycle){ if (digitalRead(buttonPin)) {
config->cycleScreen()->draw(); if (!buttonPressedLastCycle && millis() - lastDebounceTime > debounceDelay) {
buttonPressedLastCycle = true; config->cycleScreen()->draw();
} buttonPressedLastCycle = true;
lastDebounceTime = millis();
}
} else { } else {
buttonPressedLastCycle = false; buttonPressedLastCycle = false;
} }