Womo-Monitor 2.0

Hallo zusammen,
nach über einem Jahr wende ich mich wieder meinem Womo-Monitor zu. Das Projekt hat sich geändert. Es wird ein Arduino Mega ESP32 mit einem 3.5" Display mit ILI9486 Treiber verwendet. Die touch Funktion benutze ich nicht, anstelle davon kommt ein 5-Tasten Shield (KB45037) zum Einsatz. Die Tasten Funktionieren, und die bis dahin implementierten Funktionen (Temperatur und Nivelierung) auch. Allerdings habe ich das Problem, dass mir das Display einfriert....im Serial Monitor läuft alles weiter....sind da die Leichen aus dem alten Projekt hinderlich?
EDIT:
Das Projekt hat sich in den letzten 2 Jahren weiterentwickelt und geändert. Die Version 2.0 wird final folgendermassen betrieben:

  • ESP32-S3 mit 16MB
  • OLED mit 128x64 und 1306 Treiber
  • Gyroskop MPU6050
  • Temperatursensor DHT22
  • Grove Air530 GPS
  • 2x Spannungsteiler 7.5k/30k Ohm
  • 2x Taster
    Der ESP32 fungiert als AP für das Web-Interface
    folgende Funktionen sind bereits implementiert:
  • Auswertung Temperatur/Feuchte
  • Wasserwaage
  • GPS
  • Kompas mit Fahrtrichtung und richtung zu den zuletzt gespeicherten Koordinaten
  • Messung von 2 Batterien
  • Checkliste vor der Fahrt
  • Einstellung für:
    • Farben
    • WiFi
    • Koordinaten setzen
    • diverse Adminfunktionen
      Was noch fehlen würde:
  • Funktionen wie Wasserpumpe oder Wechselrichter per Relais schaltbar machen
    Letzten Sketch reiche ich hier noch nach, sobald ich am eigenen PC sitze
//#######################################################################
//# Wohnmobil-Monitor 2.0 by Roland Kälin
//#
//# Dieses System ist ausgelegt für eine Auflösung von 480x320
//# Benutzt wird ein 3.5" Touch-Display mit einem ILI9486 Treiber

//# Bekannte Bugs:
//# 1. Das Display hängt sich auf
//#
//# Fehlende Funktionen
//# 1. Farbsettings
//# 2. Nullen des Gyroskops
//# 3. Setting Screen
//# 4. Screen Ausschalten (wird bei diesem evtl nict gehen
//# 5. Reset Funktion
//#######################################################################
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
//#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <EEPROM.h>
#include <Wire.h> //Wire Bibliothek einbinden
#include "HardwareSerial.h"
#include "icons.h"
#include <DHT.h>
#include <DHT_U.h>






#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSans24pt7b.h>
#include <Fonts/FreeSans18pt7b.h>
#include <Fonts/FreeSerif9pt7b.h>
#include <Fonts/FreeSerif12pt7b.h>
#include <FreeDefaultFonts.h>

//Programmversion
String Version = "1.1.7";
//Uhr

//Eingang für Buttons
#define ANALOG_PIN A8



//Temperatursensor definieren
#define DHTPIN 33
#define DHTTYPE    DHT22
DHT_Unified dht(DHTPIN, DHTTYPE);


// ALL Touch panels and wiring is DIFFERENT
// copy-paste results from TouchScreen_Calibr_native.ino
//3.5 Calibration
const int XP = 6, XM = A2, YP = A1, YM = 7; //320x480 ID=0x9486
const int offsetx = -20;
const int offsety = -30;
const int TS_LEFT = 722 + offsety, TS_RT = 173 , TS_TOP = 947, TS_BOT = 177 + offsetx;

MCUFRIEND_kbv tft;


//Colors
#define BLACK   0x0000
#define GREY    0x5555
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define DARKGREEN   0x05C0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define GOLD    0xDDC0
#define WHITE   0xFFFF
#define DARKGREY 0x10A2

//Temperaturvariablen
float temp(NAN), hum(NAN);
String temp_alt = "0";
String hum_alt = "0";
String tempval;
String humval;
String tempval_alt;
String humval_alt;




//Buttons
Adafruit_GFX_Button on_btn, off_btn, page1_btn, page2_btn, page3_btn, page4_btn, page5_btn, page6_btn, page7_btn;
Adafruit_GFX_Button ok_btn, cncl_btn, plus_btn, minus_btn, ja_btn, nein_btn, reset_btn, timeout_btn, farben_btn;
Adafruit_GFX_Button menu_btn, info_btn, back_btn, next_btn;
//Adafruit_GFX_Button k1_btn, k2_btn, k3_btn, k4_btn, k5_btn, k6_btn, k7_btn, k8_btn, k9_btn, k0_btn;

// Button calibration
int margin = 5;
int btnWidth = 100;
int btnHeight = 40;
int btnY = 200;

// Software variable
bool enable_nuit = false;
int parameter = 50, old_parameter = 50;
const int rotar = 3; //Display Rotation
float rad = 0.0174532925;

int splashCounter = 0;



//Gyroskop definieren
Adafruit_MPU6050 mpu;

//Colors
String Voreground, Backbround, Fontcolor;

enum pageId {
  TEMP,
  INFO,
  INFO1,
  DISPLAYAUS,
  EINSTELL,
  EINSTELLFARBE,
  LEVEL,
  SPLASH,
  NEUSTART,
  TIMEOUT,
};
unsigned int currentPage = SPLASH, oldPage = -1, aktPage = -1;


//Einstellungen zum Nivelieren
float abwlr = 1.5; //winkelabweichung zum Keilen
float abwhv = 1.5;
float x = 0, y = 0, x_alt = 0, y_alt = 0;
int multi = 4
0;


//Umrechnung RGB in 565
#define RGB565(r, g, b)    ((((r)& 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3))

//Farbeinstellungen
uint16_t Vorder, BtnTextf, Schriftf, Vorder_alt, BtnTextf_alt, Schriftf_alt;
int selRot, selGruen, selBlau, selRot_alt, selGruen_alt, selBlau_alt;
int  pixel_x_alt;    //Touch_getXY() updates global vars

int o = 0;
int n = 1;
int F = 0;
int rot, gruen, blau, fx, fy, cursx, Vbtn, Tbtn, rf, gf, bf;

//Systemreset
void(* resetFunc) (void) = 0;//declare reset function at address 0

//Bildschirm schwarz
unsigned int aus_ee;
long aus;
static uint32_t sekundenloop, looper, debouncer;
static unsigned long debounce = 0;
int zahl[8], ki = 0, ka = 0;
int uebergabe = 0;


//###################################################
//Buttons auswerten
//###################################################

byte button = 0;




//Buttons definieren




//##############################################
//#Setup
//##############################################

void setup(void)
{
  Serial.begin(9600);
  aus_ee = EEPROM[0];
  ////Serial.println(aus_ee);
  //Grundfarben definieren
  Vorder = 0x0ff0;
  BtnTextf = 0x0000;
  Schriftf = 0x0FF0;
  fx = 10;//Position Farbbalken
  fy = 50;
  cursx = 0;

  Vbtn = 0;
  Tbtn = 0;



  //init TFTTouch
  uint16_t ID = tft.readID();
  if (ID == 0xD3D3) ID = 0x9486;  //for 3.5" TFT LCD Shield , 0x9341 for 2.8" TFT LCD Shield
  tft.begin(ID);
  tft.setRotation(rotar); //0-PORTRAIT 1-PAYSAGE 2-REVERSE PORTRAIT 3-REVERSE PAYSAGE

  Serial.println("Adafruit MPU6050 test!");

  // Try to initialize Gyroskope
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_16_G);
  Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
    case MPU6050_RANGE_2_G:
      Serial.println("+-2G");
      break;
    case MPU6050_RANGE_4_G:
      Serial.println("+-4G");
      break;
    case MPU6050_RANGE_8_G:
      Serial.println("+-8G");
      break;
    case MPU6050_RANGE_16_G:
      Serial.println("+-16G");
      break;
  }
  mpu.setGyroRange(MPU6050_RANGE_1000_DEG);
  Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      Serial.println("+- 250 deg/s");
      break;
    case MPU6050_RANGE_500_DEG:
      Serial.println("+- 500 deg/s");
      break;
    case MPU6050_RANGE_1000_DEG:
      Serial.println("+- 1000 deg/s");
      break;
    case MPU6050_RANGE_2000_DEG:
      Serial.println("+- 2000 deg/s");
      break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_260_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      Serial.println("260 Hz");
      break;
    case MPU6050_BAND_184_HZ:
      Serial.println("184 Hz");
      break;
    case MPU6050_BAND_94_HZ:
      Serial.println("94 Hz");
      break;
    case MPU6050_BAND_44_HZ:
      Serial.println("44 Hz");
      break;
    case MPU6050_BAND_21_HZ:
      Serial.println("21 Hz");
      break;
    case MPU6050_BAND_10_HZ:
      Serial.println("10 Hz");
      break;
    case MPU6050_BAND_5_HZ:
      Serial.println("5 Hz");
      break;
  }



  //Wire starten
  Wire.begin();
  Wire.setClock(400000L);
  drawSplashScreen();
  delay(2000);
  {
    currentPage = TEMP;
  }


  //Temperatursensor starten
  dht.begin();
  Serial.println(F("DHTxx Unified Sensor Example"));
  // Print temperature sensor details.
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  Serial.println(F("------------------------------------"));
  Serial.println(F("Temperature Sensor"));
  Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
  Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
  Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
  Serial.println(F("------------------------------------"));
  // Print humidity sensor details.
  dht.humidity().getSensor(&sensor);
  Serial.println(F("Humidity Sensor"));
  Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("%"));
  Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("%"));
  Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("%"));
  Serial.println(F("------------------------------------"));
  // Set delay between sensor readings based on sensor details.

}

//##############################################
//#Loop
//##############################################

void loop(void)
{
  checkButtons();
  readMPU();
  Serial.println("");
  if ((millis() / 10000) - (sekundenloop / 10000)  < aus_ee)
  {
    /*   Serial.print("X: ");
       Serial.println(pixel_x);
       Serial.print("Y: ");
       Serial.println(pixel_y);
    */
    switch (currentPage)
    {


      case SPLASH:
        if (currentPage != oldPage) drawSplashScreen();




        if (button == 4)
        {
          currentPage = TEMP;
        }
        if (button == 1)
        {
          currentPage = LEVEL;
        }
        resetButtons();
        break;

      case TEMP: //Menu page
        if (currentPage != oldPage)   drawTempScreen();
        updateTemp();

        if (button == 1)
        {
          resetButtons();
          currentPage = SPLASH;
          splashCounter = 0;

        }
        if (button == 4)
        {
          resetButtons();
          currentPage = LEVEL;
        }
        break;


      case LEVEL: //Nivelieren
        if (currentPage != oldPage)   drawLevelScreen();
        getLevel();
        if (button == 1)
        {
          resetButtons();
          currentPage = TEMP;
        }
        if (button == 4)
        {
          resetButtons();
          splashCounter = 0;
          currentPage = SPLASH;
        }
        break;



      case INFO:
        if (currentPage != oldPage) drawInfoScreen();

        break;

      case EINSTELL:
        if (currentPage != oldPage) drawEinstellScreen();


        break;

      case EINSTELLFARBE:
        if (currentPage != oldPage) drawEinstellFarbeScreen();


        break;


      case NEUSTART: //System zurücksetzen
        if (currentPage != oldPage)   drawResetScreen();
        //  draw0Gauge(tft.width() / 2, tft.height() / 2, 75);

        break;

      case DISPLAYAUS:
        if (currentPage != oldPage)drawDisplayAusScreen();

        break;

      case TIMEOUT:
        if (currentPage != oldPage)drawTimeoutScreen();
        tft.setFont(&FreeSerif12pt7b);
        {
        }

        break;



    }
  }
}
/************************************************************************************
    Screens gestalten
 ************************************************************************************/



void drawSplashScreen()
{
  tft.fillScreen( 0x0000);
  tft.drawBitmap(tft.width() / 2 - 160, tft.height() / 2 - 65, rimor, 250, 65, Schriftf);
  tft.drawBitmap(tft.width() / 2, tft.height() / 2, sailer, 120, 60, Schriftf);

  oldPage = currentPage;
}

void drawTimeoutScreen()
{
  tft.fillScreen( 0x0000);
  tft.setRotation(rotar);
  // Title
  tft.setFont ();
  tft.setTextSize(2);
  tft.setTextColor(Schriftf, 0x0000);
  tft.setCursor(20, 30);
  showmsgXY(20, 30, 1,  &FreeSerif12pt7b, "Timeout fur das Display", Schriftf);
  tft.drawRect(120, 15, 2, 2, Vorder);
  tft.drawRect(126, 15, 2, 2, Vorder);
  tft.drawLine(0, 34, tft.width() * 0.6, 34, Vorder); // Draws the red line
  tft.setFont(&FreeSerif12pt7b);
  tft.setTextSize(1);
  tft.setTextColor(Schriftf, 0x0000);
  tft.setCursor(20, 70);
  tft.print ("Timeout in Sekunden: ");
  tft.setCursor(250, 70);
  tft.print(aus_ee * 10);
  tft.setFont ();
  plus_btn.initButton(&tft, (tft.width() / 2) + (100 + margin / 2), 180, 100, 40, WHITE, Vorder, BtnTextf, "+10", 2);
  plus_btn.drawButton(false);
  minus_btn.initButton(&tft, (tft.width() / 2) - (100 + margin / 2), 180, 100, 40, WHITE, Vorder, BtnTextf, "-10", 2);
  minus_btn.drawButton(false);
  ok_btn.initButton(&tft, (tft.width() / 2), 180 + btnHeight + margin, 100, 40, WHITE, Vorder, BtnTextf, "ok", 2);
  ok_btn.drawButton(false);

  aus_ee = EEPROM[0];

  ////Serial.print("ausEE");
  ////Serial.println(aus_ee);


  showHome();
  oldPage = currentPage;

}
void drawDisplayAusScreen()
{
  tft.fillScreen(0x0000);
  aktPage = oldPage;
  oldPage = currentPage;
}



void drawLevelScreen()
{
  tft.setRotation(rotar);
  tft.fillScreen( 0x0000);
  tft.fillCircle(160, 185, 100, 0x07e0 );
  tft.drawCircle(160, 185, 20,  0x0000);
  tft.drawCircle(160, 185, 101, WHITE);
  //Title
  showmsgXY(20, 30, 1,  &FreeSans12pt7b, "Nivelierung", Schriftf);
  tft.drawLine(0, 34, tft.width() * 0.6, 34, Vorder); // Draws the red line
  tft.setFont ();
  getLevel();

  oldPage = currentPage;
}

void drawInfoScreen()
{
  tft.setRotation(rotar);
  tft.fillScreen( 0x0000);//(100, 155, 203)
  tft.drawRoundRect(10, 50, tft.width() - 20, tft.height() - 60, 5, Vorder); //tft.fillRect (10, 10, 60, 36);
  tft.setFont ();
  tft.setTextColor(Schriftf);
  tft.setCursor(20, 30);
  tft.write("Informationen ");
  tft.write(0x81);
  tft.write("ber das System");
  tft.setCursor(25, 80);
  tft.write("Dieses System wurde in m");
  tft.write(0x81);
  tft.write("hevoller");
  tft.setCursor(25, 105);
  tft.write("Kleinstarbeit und mit viel Zeit");
  tft.setCursor(25, 130);
  tft.write("von Roland zusammengekl");
  tft.write(0x94);
  tft.write("ppelt.");
  tft.setCursor(25, 155);
  tft.write("Bei Fragen gerne melden.");
  tft.setCursor(25, 205);
  tft.write("Tel: +41 79 XXX XX XX");
  tft.setCursor(25, 230);
  tft.write("email: rxxxxxxxxx@gmail.com");
  tft.setCursor(25, 280);
  tft.write("Programmversion: ");
  tft.print(Version);
  // tft.write(0xE0);
  tft.setFont ();
  oldPage = currentPage;
}

void drawEinstellScreen()
{
  tft.setRotation(rotar);
  tft.fillScreen( 0x0000);//(100, 155, 203)
  tft.setFont ();
  tft.setTextColor(Schriftf);
  showmsgXY(20, 30, 1,  &FreeSerif12pt7b, "Einstellungen", Schriftf);
  tft.drawLine(0, 34, tft.width() * 0.6, 34, Vorder); // Draws the red line
  tft.setFont ();
  reset_btn.initButton(&tft, (tft.width() / 2) - (btnWidth) - (margin / 2), 130 + btnHeight + margin, 2 * (btnWidth), btnHeight, WHITE, Vorder, BtnTextf, "Neustart", 2);
  reset_btn.drawButton(false);
  timeout_btn.initButton(&tft, (tft.width() / 2) - (btnWidth) - (margin / 2), 130, 2 * (btnWidth), btnHeight, WHITE, Vorder, BtnTextf, "Display", 2);
  timeout_btn.drawButton(false);
  farben_btn.initButton(&tft, (tft.width() / 2) - (btnWidth) - (margin / 2), 130 - (btnHeight + margin), 2 * (btnWidth), btnHeight, WHITE, Vorder, BtnTextf, "Farben", 2);
  farben_btn.drawButton(false);
  showHome();
  showVor();
  oldPage = currentPage;
}

void drawEinstellFarbeScreen()
{
  tft.fillScreen( 0x0000);
  tft.setRotation(rotar);
  Button(10, 250, 150, 20, 0xffff, Vorder, BtnTextf, "Hauptfarbe");
  Button(330, 250, 150, 20, 0xffff, Vorder, BtnTextf, "BtnTextfarbe");
  Button(330, 300, 100, 20, 0xffff, Vorder, BtnTextf, "OK");

  drawSlider(40, 100, 255, 10, 40, Vorder, BtnTextf);

  tft.setFont ();
  tft.setTextColor(Schriftf);
  showmsgXY(20, 30, 1,  &FreeSerif12pt7b, "Farbeinstellungen", Schriftf);
  tft.drawLine(0, 34, tft.width() * 0.6, 34, Vorder); // Draws the red line  tft.setFont ();
  showHome();
  showZuruck();
  oldPage = currentPage;
}

void drawTempScreen()
{
  tft.setRotation(rotar);
  tft.fillScreen( 0x0000);//(100, 155, 203)
  //showHome();
  // showVor();
  oldPage = currentPage;
  getTemp();
  updateTemp();
  tft.setTextColor(Schriftf,  0x0000);
  tft.setTextSize(3);
  tft.setCursor(50, 150);
  tft.setTextColor(Schriftf,  0x0000);
  tft.setTextSize(2);
  tft.setCursor(272, 150);
  showmsgXY(20, 50, 1, &FreeSans18pt7b, "Temperatur", Schriftf);
  showmsgXYs(20, 200, 2, &FreeSans24pt7b, " ", BLACK);
  showmsgXYs(20, 200, 2, &FreeSans24pt7b, tempval, Schriftf);
  tft.drawCircle(150, 150, 10, Schriftf);
  tft.drawCircle(150, 150, 11, Schriftf);
  tft.drawCircle(150, 150, 12, Schriftf);
  tft.drawCircle(150, 150, 13, Schriftf);
  tft.drawCircle(150, 150, 14, Schriftf);
  tft.setTextSize(3);
  tft.setCursor(170, 200);
  tft.setFont(&FreeSans24pt7b);
  tft.setTextSize(2);
  tft.write("C");
  tft.drawLine(240, 1, 240, 319, Schriftf);
  showmsgXY(260, 50, 1, &FreeSans18pt7b, "Feuchtigkeit", Schriftf);
  showmsgXYs(260, 200, 2, &FreeSans24pt7b, " ", BLACK);
  showmsgXYs(260, 200, 2, &FreeSans24pt7b, humval, Schriftf);
  showmsgXYs(390, 200, 2, &FreeSans24pt7b, "%", Schriftf);


}

////////////////////////////////////////////////////////////////////
//WetterTrend
////////////////////////////////////////////////////////////////////

void drawResetScreen()
{
  tft.setRotation(rotar);
  tft.fillScreen( 0x0000);
  tft.setFont ();
  tft.setTextColor(Schriftf);
  showmsgXY(20, 30, 1,  &FreeSerif12pt7b, "Neustart", Schriftf);
  tft.drawLine(0, 34, tft.width() * 0.6, 34, Vorder); // Draws the red line  tft.setFont ();
  tft.setCursor(25, 70);
  tft.setTextSize(2);
  tft.write("Bei einem Neustart des Systems");
  tft.setCursor(25, 95);
  tft.write("werden alle Parameter neu geladen.");
  tft.setCursor(25, 120);
  tft.write("Das Fahrzeug muss dabei ganz");
  tft.setCursor(25, 145);
  tft.write("gerade stehen, da der Niveausensor");
  tft.setCursor(25, 170);
  tft.write("dabei neu kalibriert wird.");
  tft.setCursor(25, 220);
  tft.write("Neu starten?");
  tft.setFont ();

  ja_btn.initButton(&tft, (tft.width() / 2) - 100, 280, 100, btnHeight, WHITE, Vorder, BtnTextf, "Ja", 2);
  ja_btn.drawButton(false);
  nein_btn.initButton(&tft, (tft.width() / 2) + 100, 280, 100, btnHeight, WHITE, Vorder, BtnTextf, "Nein", 2);
  nein_btn.drawButton(false);
  oldPage = currentPage;
}
/************************************************************************************
    Zusätzliche Funktionen
*************************************************************************************/



//##############################################
//#Temperatursensor auswerten
//##############################################
void getTemp()
{
  // Get temperature event and print its value.
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    //   Serial.println(F("Error reading temperature!"));
  }
  else {
    temp = event.temperature;
    //   Serial.print(F("Temperature: "));
    //    Serial.print(event.temperature);
    //    Serial.println(F("°C"));
    tempval = String(temp, 0);
    tempval_alt = tempval;
    //   Serial.print("Temppppp: ");
    //    Serial.println(tempval);
  }
  // Get humidity event and print its value.
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    //   Serial.println(F("Error reading humidity!"));
  }
  else {
    hum = event.relative_humidity;
    humval_alt = humval;
    //   Serial.print(F("Humidity: "));
    //    Serial.print(event.relative_humidity);
    //    Serial.println(F("%"));
    humval = String(hum, 0);
    //    Serial.print("Hummmmm: ");
    //    Serial.println(humval);
  }


}


void updateTemp()
{
  // Serial.println("Update");
  getTemp();
  // Serial.print("temp= ");
  // Serial.println(temp);
  //  Serial.print("temp_alt= ");
  // Serial.println(temp_alt);
  if (isnan(temp)) temp = 0;
  if ((tempval) != (temp_alt))
  {
    tft.setTextColor(Schriftf,  0x0000);
    showmsgXYs(20, 200, 2, &FreeSans24pt7b, temp_alt, BLACK);
    showmsgXYs(20, 200, 2, &FreeSans24pt7b, tempval, Schriftf);

    temp_alt = tempval;
  }
  if (isnan(hum)) hum = 0;
  if ((humval) != (hum_alt))
  {

    showmsgXYs(260, 200, 2, &FreeSans24pt7b, hum_alt, BLACK);
    showmsgXYs(260, 200, 2, &FreeSans24pt7b, humval, Schriftf);
    hum_alt = humval;
  }
}
//#######################################################
//Nivelierung
//#######################################################

void getLevel()

{
  readMPU();

  if (x_alt != x or y_alt != y)
  {
    tft.fillCircle(x_alt * multi + 160, y_alt * multi + 185, 12, 0x07e0);
    tft.drawCircle(160, 185, 20,  0x0000);
    tft.fillCircle(x * multi + 160, y * multi + 185, 12, RED);
    x_alt = x;
    y_alt = y;
  }
  else
  {
    tft.fillCircle(160, 185, 12, RED);
  }
}


//##############################################
//#Nachricht an Position mit Schriftart etc.
//##############################################

void showmsgXY(int x, int y, int sz, const GFXfont * f, const char *msg, uint16_t Farbe)
{
  // int16_t x1, y1;
  // uint16_t wid, ht;
  tft.setFont(f);
  tft.setCursor(x, y);
  tft.setTextColor(Farbe);
  tft.setTextSize(sz);
  tft.print(msg);
  tft.setFont();
  tft.setTextSize(1);
}

void showmsgXYs(int x, int y, int sz, const GFXfont * f, String msg, uint16_t Farbe)
{
  // int16_t x1, y1;
  // uint16_t wid, ht;
  tft.setFont(f);
  tft.setCursor(x, y);
  tft.setTextColor(Farbe);
  tft.setTextSize(sz);
  tft.print(msg);
  tft.setFont();
  tft.setTextSize(1);
}
//#######################################################
//Ringmeter
//#######################################################


// #########################################################################
// Return a 16 bit rainbow colour
// #########################################################################

unsigned int rainbow(byte value)
{
  // Value is expected to be in range 0-127
  // The value is converted to a spectrum colour from 0 = blue through to 127 = red

  byte red = 0; // Red is the top 5 bits of a 16 bit colour value
  byte green  = 0;// 0x07e0  is the middle 6 bits
  byte blue = 0; // Blue is the bottom 5 bits

  byte quadrant = value / 32;

  if (quadrant == 0) {
    blue = 31;
    green  = 2 * (value % 32);
    red = 0;
  }
  if (quadrant == 1) {
    blue = 31 - (value % 32);
    green  = 63;
    red = 0;
  }
  if (quadrant == 2) {
    blue = 0;
    green  = 63;
    red = value % 32;
  }
  if (quadrant == 3) {
    blue = 0;
    green  = 63 - 2 * (value % 32);
    red = 31;
  }
  return (red << 11) + (green  << 5) + blue;
}

//#######################################################
//Fest platzierte Buttons
//#######################################################

void showHome()//Home Button anzeigen
{
  tft.drawRGBBitmap(20, tft.height() - 32, HOMEP, 32, 32);
}


void showVor()//Vorwärts Button anzeigen
{
  tft.drawBitmap((tft.width() / 2) + 5, (tft.height() - 32), VOR, 32, 32, Vorder);
}



void showZuruck()//Zurück Button anzeigen
{
  tft.drawBitmap((tft.width() / 2) - 37, (tft.height() - 32), ZURUCK, 32, 32, Vorder);
}




void farben()
{
  cursx = 0;
  for (rot = 0; rot < 255; rot++)
  {
    Vorder = RGB565(rot, 0, 0);
    tft.fillRect(fx + cursx, fy, 1, 30, Vorder);
    cursx++;
    ////Serial.println(fx + cursx);
    tft.drawRect(fx - 1, fy - 1, 256, 30, 0xFFFF);
  }
  cursx = 0;
  for (gruen = 0; gruen < 255; gruen++)
  {
    Vorder = RGB565(0, gruen, 0);
    tft.fillRect(fx + cursx, fy + 50, 1, 30, Vorder);
    cursx++;
    tft.drawRect(fx - 1, fy + 50 - 1, 256, 30, 0xFFFF);
  }
  cursx = 0;
  for (blau = 0; blau < 255; blau++)
  {
    Vorder = RGB565(0, 0, blau);
    tft.fillRect(fx + cursx, fy + 100, 1, 30, Vorder);
    cursx++;
    tft.drawRect(fx - 1, fy + 100 - 1, 256, 30, 0xFFFF);
  }
  selBlau = 0;
  selRot = 0;
  selGruen = 0;

}

//##############################################
//#Button zeichnen
//##############################################
void Button (int x, int y, int breite, int hoehe, uint16_t rahmen, uint16_t fuell, uint16_t schrift, String btntxt)
{
  tft.fillRect(x + 1, y + 1, breite - 1, hoehe - 1, fuell);
  tft.drawRect(x, y, breite, hoehe, rahmen);
  tft.setCursor(((x + breite / 2) - ((btntxt.length()) / 3 * 8)), (y + hoehe / 2 - 4));
  tft.setTextColor(schrift);
  tft.print(btntxt);
  //////Serial.println(btntxt.length());

}

//##############################################
//#Farben von Touchscreen
//##############################################
void Farbenwahl()
{
  /*
    if (Vbtn != 0 or Tbtn != 0)
    {
      selRot = 0;
      selGruen = 0;
      selBlau = 0;
      if (Vbtn != 0)
      {
        F = 1;
      }

      else if (Tbtn != 0)
      {
        F = 2;
      }
    }
    ////Serial.println(Tbtn);
    ////Serial.println(Vbtn);
    ////Serial.print("F: ");
    ////Serial.println(F);
    if (pixel_x >= fx * 2 and pixel_x <= fx * 2 + 254 and pixel_y > fy and pixel_y < fy + 30)
    {
      selRot = pixel_x - fx * 2;
      // ////Serial.print("Pixelfarbe rot= ");
      //////Serial.println(selRot);
    }

    if (pixel_x >= fx * 2 and pixel_x <= fx * 2 + 254 and pixel_y > fy + 50 and pixel_y < fy + 80)
    {
      selGruen = pixel_x - fx * 2;
      // ////Serial.print("Pixelfarbe1 gruen= ");
      //  ////Serial.println(selGruen);

    }

    if (pixel_x >= fx * 2 and pixel_x <= fx * 2 + 254 and pixel_y > fy + 100 and pixel_y < fy + 130)
    {
      selBlau = pixel_x - fx * 2;
      //   ////Serial.print("Pixelfarbe blau= ");
      //   ////Serial.println(selBlau);

    }
    if (pixel_x != pixel_x_alt and ((pixel_y > fy and pixel_y < fy + 30) or (pixel_y > fy + 50 and pixel_y < fy + 80) or (pixel_y > fy + 100 and pixel_y < fy + 130)))
    {
      tft.setFont ();
      tft.setTextSize(3);
      tft.setCursor(300, 50);
      tft.setTextColor(0xFFFF);
      tft.print("Vorschau");
      if (F == 1)
      {
        Vorder = RGB565(selRot, selGruen, selBlau);


        tft.fillRect(320, 100, 100, 100, Vorder);
        tft.drawRect(319, 99, 102, 102, 0xFFFF);
        tft.setTextColor(BtnTextf);

        tft.setCursor(335, 140);
        tft.print("TEST");


        F = 0;
      }
      if (F == 2)
      {

        ////Serial.println("TEST");
        BtnTextf = RGB565(selRot, selGruen, selBlau);
        tft.setTextColor(BtnTextf);

        tft.setCursor(335, 140);
        tft.print("TEST");
        F = 0;

      }
      tft.setTextSize ();

      pixel_x_alt = pixel_x;
    }*/
}

void drawSlider(int x, int y, int slideLength,  int sliderWidth, int sliderHeight, int color, int bordercolor)
{
  tft.drawRect(x - sliderWidth / 2 - 1, y - sliderHeight / 2 - 1, slideLength + sliderWidth / 2 + 1, sliderHeight + 2, color);
  tft.fillRect(x - sliderWidth / 2 + 1 / 2, y - sliderHeight / 2 + 1 / 2, sliderWidth - 2, sliderHeight - 2, color);
  tft.drawRect(x - sliderWidth / 2, y - sliderHeight / 2, sliderWidth, sliderHeight, bordercolor);
}

void drawSwitch (int x, int y, int swLength, int swWidth, int color, int swStatus)
{
  if (swStatus == 0)
  {
    tft.drawRoundRect(x, y - swWidth / 2, swLength, swWidth, swWidth / 2, color);
    tft.fillCircle(x + 2 + swWidth / 2 , y, swWidth / 2 - 4, color);
    tft.fillCircle(x + swLength - 2 - swWidth / 2, y, swWidth / 2 - 4, 0x0000);
  }
  if (swStatus == 1)
  {
    tft.drawRoundRect(x, y - swWidth / 2, swLength, swWidth, swWidth / 2, color);
    tft.fillCircle(x + swLength - 2 - swWidth / 2, y, swWidth / 2 - 4, color);
    tft.fillCircle(x + 2 + swWidth / 2, y, swWidth / 2 - 4, 0x0000);
  }
}



/*
  void readSerial2()
  {
  if (Serial2.available())
  {
    //Serial.println("Serial2 verfügbar");
    alarm = Serial2.readStringUntil('\n\r');
    //Serial.print(alarm);
    //Serial.println("=");
    if (alarm == "ALARM")
    {
      alarmstatus = 2;
    }

    else if (alarm == "AUS")
    {
      alarmstatus = 0;
    }
    else if (alarm == "EIN")
    {
      alarmstatus = 1;
    }

    //Serial.println(alarmstatus);
  }
  }
*/
void readMPU()
{
  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  Serial.print("Acceleration X: ");
  x = a.acceleration.x;
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  y = a.acceleration.y;
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");

  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");

  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degC");
}

//############################################
//Buttons auswerten
//############################################
void checkButtons()
{
  if (analogRead(ANALOG_PIN) >= 0 and analogRead(ANALOG_PIN) < 10)
  {
    debouncer = millis();
    if (debouncer - debounce > 500)
      debounce = debouncer;
    button = 1;
  }
  if (analogRead(ANALOG_PIN) > 20 and analogRead(ANALOG_PIN) < 40)
  {
    debouncer = millis();
    if (debouncer - debounce > 500)
      debounce = debouncer;
    button = 2;
  }
  if (analogRead(ANALOG_PIN) > 70 and analogRead(ANALOG_PIN) < 100)
  {
    debouncer = millis();
    if (debouncer - debounce > 500)
      debounce = debouncer;
    button = 3;
  }
  if (analogRead(ANALOG_PIN) > 160 and analogRead(ANALOG_PIN) < 180)
  {
    debouncer = millis();
    if (debouncer - debounce > 500)
      debounce = debouncer;
    button = 4;
  }
  if (analogRead(ANALOG_PIN) > 340 and analogRead(ANALOG_PIN) < 400)
  {
    debouncer = millis();
    if (debouncer - debounce > 500)
      debounce = debouncer;
    button = 5;
  }
  Serial.println("");
  Serial.println(analogRead(ANALOG_PIN));
  Serial.print("Button ");
  Serial.print(button);
  Serial.println(" pressed");
}

void resetButtons()
{
  button = 0;

}

ja ich weiss, da sind noch ganz viele sachen wie Strings und delays, die da nicht reingehören. Das wird dann noch ausgemistet. Aber hätte jemand @my_xy_projekt oder @fony im speziellen eine idee?
Womo_Monitor_OLED-260729a.zip (1,8 MB)

Wenn der Display einfriert, dann alles, was dessen Kommunikation ist, auf einen neuen Sketch schieben und ohne alles andere testen.

Das wird Fleißarbeit.
Und ja, ausmisten ist zwingend erforderlich, sonst macht das keinen Sinn.

ich habs befürchtet.....aber ich werde dann mal alles was noch übrig ist entsorgen und bei bedarf neu schreiben

So, ich habe das ganze jetzt auf rund 550 Zeilen runtergekürzt, und nur das dringelassen was sein muss. Jetzt läuft es seit 15min. stabil, wo es gestern nach 3 minuten eingefroren ist. Ich glaube ich hatte beim grossen Display eine Funktion drin, die das Display nach einer gewissen Zeit ausschaltet. Das könnte der Hänger gewesen sein. Ich muss dann doch noch mal schauen, ob ich die Hintergrundbeleuchtung irgendwie ausschalten kann.
Sieht hier sonst noch jemand etwas, das mir über längere Zeit auf die Füsse fallen könnte? Das Delay in Zeile 200 sollte, denke ich, kein Problem darstellen, da das ja nur einmal ausgeführt wird. Falls die Strings noch problematisch werden könnten, wäre ich da um etwas Hilfe ganz froh
Kompiliert wird ohne Fehler

//#######################################################################
//# Wohnmobil-Monitor 2.0 by Roland Kälin
//#
//# Dieses System ist ausgelegt für eine Auflösung von 480x320
//# Benutzt wird ein 3.5" Touch-Display mit einem ILI9486 Treiber

//# Bekannte Bugs:
//# 1. Das Display hängt sich auf
//#
//# Fehlende Funktionen
//# 1. Farbsettings
//# 2. Nullen des Gyroskops
//# 3. Setting Screen
//# 4. Screen Ausschalten (wird bei diesem evtl nict gehen
//# 5. Reset Funktion
//#######################################################################
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
//#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
//#include <EEPROM.h>
#include <Wire.h> //Wire Bibliothek einbinden
#include "HardwareSerial.h"
#include "icons.h"
#include <DHT.h>
#include <DHT_U.h>

//#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSans24pt7b.h>
#include <Fonts/FreeSans18pt7b.h>
//#include <Fonts/FreeSerif9pt7b.h>
//#include <Fonts/FreeSerif12pt7b.h>
//#include <FreeDefaultFonts.h>

//Programmversion
String Version = "1.1.7";

//Eingang für Buttons
#define ANALOG_PIN A8

//Temperatursensor definieren
#define DHTPIN 33
#define DHTTYPE    DHT22
DHT_Unified dht(DHTPIN, DHTTYPE);

//Display definieren
MCUFRIEND_kbv tft;

//Vordefinierte Farben
#define BLACK   0x0000
#define GREY    0x5555
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define DARKGREEN   0x05C0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define GOLD    0xDDC0
#define WHITE   0xFFFF
#define DARKGREY 0x10A2

//Temperaturvariablen
float temp(NAN), hum(NAN);
String temp_alt = "0";
String hum_alt = "0";
String tempval;
String humval;
String tempval_alt;
String humval_alt;

// Software variable
const int rotar = 3; //Display Rotation
//float rad = 0.0174532925;

//Gyroskop definieren
Adafruit_MPU6050 mpu;

//Farben
uint16_t Vorder, Schriftf, Vorder_alt, BtnTextf_alt, Schriftf_alt;

//Screens definieren
enum pageId {
  TEMP,
  LEVEL,
  SPLASH,
  INFO,
};
unsigned int currentPage = SPLASH, oldPage = -1, aktPage = -1;

//Einstellungen zum Nivelieren
float x = 0, y = 0, x_alt = 0, y_alt = 0;
int multi = 20;

//Umrechnung RGB in 565
//#define RGB565(r, g, b)    ((((r)& 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3))

//Systemreset
//void(* resetFunc) (void) = 0;//declare reset function at address 0

//###################################################
//Buttons auswerten
//###################################################
byte button = 0;
//Debounce Variablen
static uint32_t debouncer;
static unsigned long debounce = 0;

//##############################################
//#Setup
//##############################################

void setup(void)
{
  Serial.begin(9600);
  ////Serial.println(aus_ee);
  //Grundfarben definieren
  Vorder = 0x0ff0;
  Schriftf = 0x0FF0;
  //init TFTTouch
  uint16_t ID = tft.readID();
  Serial.print("ID: ");
  Serial.println(tft.readID());
  if (ID == 0xD3D3) ID = 0x9486;  //for 3.5" TFT LCD Shield , 0x9341 for 2.8" TFT LCD Shield
  Serial.print("ID: ");
  Serial.println(tft.readID());
  tft.begin(ID);
  tft.setRotation(rotar); //0-PORTRAIT 1-PAYSAGE 2-REVERSE PORTRAIT 3-REVERSE PAYSAGE
  Serial.println("Adafruit MPU6050 test!");
  // Try to initialize Gyroskope
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
    }
  }
  Serial.println("MPU6050 Found!");
  mpu.setAccelerometerRange(MPU6050_RANGE_16_G);
  Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
    case MPU6050_RANGE_2_G:
      Serial.println("+-2G");
      break;
    case MPU6050_RANGE_4_G:
      Serial.println("+-4G");
      break;
    case MPU6050_RANGE_8_G:
      Serial.println("+-8G");
      break;
    case MPU6050_RANGE_16_G:
      Serial.println("+-16G");
      break;
  }
  mpu.setGyroRange(MPU6050_RANGE_1000_DEG);
  Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      Serial.println("+- 250 deg/s");
      break;
    case MPU6050_RANGE_500_DEG:
      Serial.println("+- 500 deg/s");
      break;
    case MPU6050_RANGE_1000_DEG:
      Serial.println("+- 1000 deg/s");
      break;
    case MPU6050_RANGE_2000_DEG:
      Serial.println("+- 2000 deg/s");
      break;
  }
  mpu.setFilterBandwidth(MPU6050_BAND_260_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      Serial.println("260 Hz");
      break;
    case MPU6050_BAND_184_HZ:
      Serial.println("184 Hz");
      break;
    case MPU6050_BAND_94_HZ:
      Serial.println("94 Hz");
      break;
    case MPU6050_BAND_44_HZ:
      Serial.println("44 Hz");
      break;
    case MPU6050_BAND_21_HZ:
      Serial.println("21 Hz");
      break;
    case MPU6050_BAND_10_HZ:
      Serial.println("10 Hz");
      break;
    case MPU6050_BAND_5_HZ:
      Serial.println("5 Hz");
      break;
  }
  //Wire starten
  Wire.begin();
  Wire.setClock(400000L);
  drawSplashScreen();
  delay(2000);
  {
    currentPage = TEMP;
  }
  //Temperatursensor starten
  dht.begin();
  Serial.println(F("DHTxx Unified Sensor Example"));
  // Print temperature sensor details.
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  Serial.println(F("------------------------------------"));
  Serial.println(F("Temperature Sensor"));
  Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
  Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
  Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
  Serial.println(F("------------------------------------"));
  // Print humidity sensor details.
  dht.humidity().getSensor(&sensor);
  Serial.println(F("Humidity Sensor"));
  Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("%"));
  Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("%"));
  Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("%"));
  Serial.println(F("------------------------------------"));
  // Set delay between sensor readings based on sensor details.
}
//##############################################
//#Loop
//##############################################
void loop(void)
{
  checkButtons();
  readMPU();
  Serial.println("");
  switch (currentPage)
  {
    case SPLASH:
      if (currentPage != oldPage) drawSplashScreen();
      if (button == 4)
      {
        currentPage = TEMP;
      }
      if (button == 1)
      {
        currentPage = INFO;
      }
      resetButtons();
      break;

    case TEMP: //Menu page
      if (currentPage != oldPage)   drawTempScreen();
      updateTemp();

      if (button == 1)
      {
        resetButtons();
        currentPage = SPLASH;
      }
      if (button == 4)
      {
        resetButtons();
        currentPage = LEVEL;
      }
      break;

    case LEVEL: //Nivelieren
      if (currentPage != oldPage)   drawLevelScreen();
      getLevel();
      if (button == 1)
      {
        resetButtons();
        currentPage = TEMP;
      }
      if (button == 4)
      {
        resetButtons();
        currentPage = INFO;
      }
      break;

    case INFO:
      if (currentPage != oldPage) drawInfoScreen();
      if (button == 1)
      {
        resetButtons();
        currentPage = LEVEL;
      }
      if (button == 4)
      {
        resetButtons();
        currentPage = SPLASH;
      }
      break;
  }
}
/************************************************************************************
    Screens anzeigen
************************************************************************************/
void drawSplashScreen()
{
  tft.fillScreen( 0x0000);
  tft.drawBitmap(tft.width() / 2 - 160, tft.height() / 2 - 65, rimor, 250, 65, Schriftf);
  tft.drawBitmap(tft.width() / 2, tft.height() / 2, sailer, 120, 60, Schriftf);
  oldPage = currentPage;
}

void drawTempScreen()
{
  tft.setRotation(rotar);
  tft.fillScreen( 0x0000);//(100, 155, 203)
  oldPage = currentPage;
  getTemp();
  updateTemp();
  tft.setTextColor(Schriftf,  0x0000);
  tft.setTextSize(3);
  tft.setCursor(50, 150);
  tft.setTextColor(Schriftf,  0x0000);
  tft.setTextSize(2);
  tft.setCursor(272, 150);
  showmsgXY(20, 50, 1, &FreeSans18pt7b, "Temperatur", Schriftf);
  showmsgXYs(20, 200, 2, &FreeSans24pt7b, " ", BLACK);
  showmsgXYs(20, 200, 2, &FreeSans24pt7b, tempval, Schriftf);
  tft.drawCircle(150, 150, 10, Schriftf);
  tft.drawCircle(150, 150, 11, Schriftf);
  tft.drawCircle(150, 150, 12, Schriftf);
  tft.drawCircle(150, 150, 13, Schriftf);
  tft.drawCircle(150, 150, 14, Schriftf);
  tft.setTextSize(3);
  tft.setCursor(170, 200);
  tft.setFont(&FreeSans24pt7b);
  tft.setTextSize(2);
  tft.write("C");
  tft.drawLine(240, 1, 240, 319, Schriftf);
  showmsgXY(260, 50, 1, &FreeSans18pt7b, "Feuchtigkeit", Schriftf);
  showmsgXYs(260, 200, 2, &FreeSans24pt7b, " ", BLACK);
  showmsgXYs(260, 200, 2, &FreeSans24pt7b, humval, Schriftf);
  showmsgXYs(390, 200, 2, &FreeSans24pt7b, "%", Schriftf);
}

void drawLevelScreen()
{
  tft.setRotation(rotar);
  tft.fillScreen( 0x0000);
  tft.fillCircle(160, 185, 100, 0x07e0 );
  tft.drawCircle(160, 185, 20,  0x0000);
  tft.drawCircle(160, 185, 101, WHITE);
  showmsgXY(20, 30, 1,  &FreeSans12pt7b, "Nivelierung", Schriftf);
  tft.drawLine(0, 34, tft.width() * 0.6, 34, Vorder);
  tft.setFont ();
  getLevel();
  oldPage = currentPage;
}

void drawInfoScreen()
{
  tft.setRotation(rotar);
  tft.fillScreen( 0x0000);
  tft.drawRoundRect(10, 50, tft.width() - 20, tft.height() - 60, 5, Vorder);
  tft.setFont ();
  tft.setTextColor(Schriftf);
  tft.setCursor(20, 30);
  tft.write("Informationen ");
  tft.write(0x81);
  tft.write("ber das System");
  tft.setCursor(25, 80);
  tft.write("Dieses System wurde in m");
  tft.write(0x81);
  tft.write("hevoller");
  tft.setCursor(25, 105);
  tft.write("Kleinstarbeit und mit viel Zeit");
  tft.setCursor(25, 130);
  tft.write("von Roland zusammengekl");
  tft.write(0x94);
  tft.write("ppelt.");
  tft.setCursor(25, 155);
  tft.write("Bei Fragen gerne melden.");
  tft.setCursor(25, 205);
  tft.write("Tel: +41 79 XXX XX XX");
  tft.setCursor(25, 230);
  tft.write("email: rxxxxxxxxx@gmail.com");
  tft.setCursor(25, 280);
  tft.write("Programmversion: ");
  tft.print(Version);
  tft.setFont ();
  oldPage = currentPage;
}

/************************************************************************************
    Zusätzliche Funktionen
*************************************************************************************/

//##############################################
//#Temperatursensor auswerten
//##############################################
void getTemp()
{
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    //   Serial.println(F("Error reading temperature!"));
  }
  else {
    temp = event.temperature;
    tempval = String(temp, 0);
    tempval_alt = tempval;
  }
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    //   Serial.println(F("Error reading humidity!"));
  }
  else {
    hum = event.relative_humidity;
    humval_alt = humval;
    humval = String(hum, 0);
  }
}


void updateTemp()
{
  getTemp();
  if (isnan(temp)) temp = 0;
  if ((tempval) != (temp_alt))
  {
    tft.setTextColor(Schriftf,  0x0000);
    showmsgXYs(20, 200, 2, &FreeSans24pt7b, temp_alt, BLACK);
    showmsgXYs(20, 200, 2, &FreeSans24pt7b, tempval, Schriftf);
    temp_alt = tempval;
  }
  if (isnan(hum)) hum = 0;
  if ((humval) != (hum_alt))
  {
    showmsgXYs(260, 200, 2, &FreeSans24pt7b, hum_alt, BLACK);
    showmsgXYs(260, 200, 2, &FreeSans24pt7b, humval, Schriftf);
    hum_alt = humval;
  }
}
//#######################################################
//Nivelierung
//#######################################################
void getLevel()
{
  readMPU();
  if (x_alt != x or y_alt != y)
  {
    tft.fillCircle(x_alt * multi * -1 + 160, y_alt * multi + 185, 12, 0x07e0);
    tft.drawCircle(160, 185, 20,  0x0000);
    tft.fillCircle(x * multi * -1 + 160, y * multi + 185, 12, RED);
    x_alt = x;
    y_alt = y;
  }
  else
  {
    tft.fillCircle(160, 185, 12, RED);
  }
}
//##############################################
//#Nachricht an Position mit Schriftart etc.
//##############################################
void showmsgXY(int x, int y, int sz, const GFXfont * f, const char *msg, uint16_t Farbe)
{
  tft.setFont(f);
  tft.setCursor(x, y);
  tft.setTextColor(Farbe);
  tft.setTextSize(sz);
  tft.print(msg);
  tft.setFont();
  tft.setTextSize(1);
}

void showmsgXYs(int x, int y, int sz, const GFXfont * f, String msg, uint16_t Farbe)
{
  tft.setFont(f);
  tft.setCursor(x, y);
  tft.setTextColor(Farbe);
  tft.setTextSize(sz);
  tft.print(msg);
  tft.setFont();
  tft.setTextSize(1);
}
//##############################################
//#Gyroskop abfragen
//##############################################
void readMPU()
{
  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  Serial.print("Acceleration X: ");
  x = a.acceleration.x;
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  y = a.acceleration.y;
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");

}
//############################################
//Buttons auswerten
//############################################
void checkButtons()
{
  if (analogRead(ANALOG_PIN) >= 0 and analogRead(ANALOG_PIN) < 10)
  {
    debouncer = millis();
    if (debouncer - debounce > 500)
      debounce = debouncer;
    button = 1;
  }
  if (analogRead(ANALOG_PIN) > 20 and analogRead(ANALOG_PIN) < 40)
  {
    debouncer = millis();
    if (debouncer - debounce > 500)
      debounce = debouncer;
    button = 2;
  }
  if (analogRead(ANALOG_PIN) > 70 and analogRead(ANALOG_PIN) < 100)
  {
    debouncer = millis();
    if (debouncer - debounce > 500)
      debounce = debouncer;
    button = 3;
  }
  if (analogRead(ANALOG_PIN) > 160 and analogRead(ANALOG_PIN) < 180)
  {
    debouncer = millis();
    if (debouncer - debounce > 500)
      debounce = debouncer;
    button = 4;
  }
  if (analogRead(ANALOG_PIN) > 340 and analogRead(ANALOG_PIN) < 400)
  {
    debouncer = millis();
    if (debouncer - debounce > 500)
      debounce = debouncer;
    button = 5;
  }
  Serial.println("");
  Serial.println(analogRead(ANALOG_PIN));
  Serial.print("Button ");
  Serial.print(button);
  Serial.println(" pressed");
}

void resetButtons()
{
  button = 0;
}

man sieht

  • keine durchgänginge Verwendung des F-Makro

  • zu viele String Objekte ohne .reserve()

  • precompiler defines die auch mit constexpr gemacht werden könnten

  • einige zwei bytige integer Variablen die auch locker in ein byte (rotar) passen.

  • mixture von uint32_t und unsigned long zwei Zeilen hintereinander für Variablen die sich durch ein Zeichen unterscheiden. Also die könnten erstens den gleichen Variablentyp habn und zweitens kannst du klarer machen was was ist - oder zumindest ein vernünftiges Kommentar setzen. Dabei kann man auch nachdenken, ob eine globale Variable in c++ noch extra static gekennzeichnet werden soll

//Debounce Variablen
static uint32_t debouncer;
static unsigned long debounce = 0;
  • switch case gehen auch mit Bereichsangaben damit erspart man sich solche Wiederholungen
 if (analogRead(ANALOG_PIN) >= 0 and analogRead(ANALOG_PIN) < 10)

und "Temperaturvariablen" in einem String halten zu wollen, sieht zumindest eigenartig aus:

//Temperaturvariablen
float temp(NAN), hum(NAN);
String temp_alt = "0";
String hum_alt = "0";
String tempval;
String humval;
String tempval_alt;
String humval_alt;

Das sind gute Inputs...danke dafür. Die einen werde ich alleine umsetzen können, bei anderen brauche ich dann evtl. Hilfe.
Aber momentan läuft es stabil.

Update 17.8.24 12:43:
Also, folgendes wurde gemacht:

  1. Eine Funktion showmessageXYi eingefügt, um Integerwerte anzuzeigen
  2. Die ganzen Stringvariablen für die Temperaturen entfernt
  3. es gibt nur noch einen String für die Programmversion
  4. Integer Werte für die Temperatur definiert, da Nachkommastellen keinen Sinn machen
  5. das Debouncing mit 2 Variablen des gleichen Typs
  6. durchgängig F-Makro
  7. Die Abfrage der Taster wurde jetzt so gelöst (jetzt habe ich auch keine zufälligen Sprünge mehr)
void checkButtons()
{
  button = analogRead(ANALOG_PIN);
  switch (button)
  {
    case 0 ... 10:
      debouncer = millis();
      if (debouncer - debounce > 50)
      {
        debounce = debouncer;
        button = 1;
      }
      break;
    case 20 ... 40:
      debouncer = millis();
      if (debouncer - debounce > 50)
      {
        debounce = debouncer;
        button = 2;
      }
      break;
    case 70 ... 100:
      debouncer = millis();
      if (debouncer - debounce > 50)
      {
        debounce = debouncer;
        button = 3;
      }
      break;
    case 160 ... 180:
      debouncer = millis();
      if (debouncer - debounce > 50)
      {
        debounce = debouncer;
        button = 4;
      }
      break;
    case 340 ... 400:
      debouncer = millis();
      if (debouncer - debounce > 50)
      {
        debounce = debouncer;
        button = 5;
      }
      break;
    case 500 ... 1023:
      button = 0;
      break;
  }
}

da bräuchte ich noch etwas mehr informationen wenn es geht

Hier mal noch der komplette code inkl. Infoscreen und Reset per Software

//#######################################################################
//# Wohnmobil-Monitor 2.0 by Roland Kälin
//#
//# Dieses System ist ausgelegt für eine Auflösung von 480x320
//# Benutzt wird ein 3.5" Touch-Display mit einem ILI9486 Treiber

//# Bekannte Bugs:
//# 1. Das Display hängt sich auf
//#
//# Fehlende Funktionen
//# 1. Farbsettings
//# 2. Setting Screen
//# 3. Screen Ausschalten (wird bei diesem evtl nicht gehen
//#######################################################################
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
//#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
//#include <EEPROM.h>
#include <Wire.h> //Wire Bibliothek einbinden
#include "HardwareSerial.h"
#include "icons.h"
#include <DHT.h>
#include <DHT_U.h>
#include <SPI.h>

//#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSans24pt7b.h>
#include <Fonts/FreeSans18pt7b.h>
//#include <Fonts/FreeSerif9pt7b.h>
//#include <Fonts/FreeSerif12pt7b.h>
//#include <FreeDefaultFonts.h>

//Programmversion
String Version = "2.0";

//Eingang für Buttons
#define ANALOG_PIN A8

//Temperatursensor definieren
#define DHTPIN 33
#define DHTTYPE    DHT22
DHT_Unified dht(DHTPIN, DHTTYPE);

//Display definieren
MCUFRIEND_kbv tft;

//Vordefinierte Farben
#define BLACK   0x0000
#define GREY    0x5555
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define DARKGREEN   0x05C0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define GOLD    0xDDC0
#define WHITE   0xFFFF
#define DARKGREY 0x10A2

//Temperaturvariablen
byte temp, hum;
byte temp_alt = 0;
byte hum_alt = 0;

// Software variable
const byte rotar = 3; //Display Rotation
//float rad = 0.0174532925;

//Gyroskop definieren
Adafruit_MPU6050 mpu;

//Farben
uint16_t Vorder, Schriftf, Vorder_alt, BtnTextf_alt, Schriftf_alt;

//Screens definieren
enum pageId {
  TEMP,
  LEVEL,
  SPLASH,
  INFO,
  NEUSTART
};
unsigned int currentPage = SPLASH, oldPage = -1, aktPage = -1;

//Einstellungen zum Nivelieren
float x = 0, y = 0, x_alt = 0, y_alt = 0, x_corr, y_corr;
byte multix = 40, multiy = 30; //multiplikator für anzeige
uint32_t nivel, startnivel; //Verzögerungsfunktion beim nivelieren, damit es nicht so flackert
//wartefunktion
uint32_t looper, startlooper;

//Umrechnung RGB in 565
//#define RGB565(r, g, b)    ((((r)& 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3))



//###################################################
//Buttons auswerten
//###################################################
byte button = 0;
//Debounce Variablen
uint32_t debouncer, startdebouncer;
//Systemreset
void(* resetFunc) (void) = 0;//declare reset function at address 0

//##############################################
//#Setup
//##############################################

void setup(void)
{
  Serial.begin(9600);
  ////Serial.println(aus_ee);
  //Grundfarben definieren
  Vorder = 0x0ff0;
  Schriftf = 0x0FF0;
  //init TFTTouch
  uint16_t ID = tft.readID();

  if (ID == 0xD3D3) ID = 0x9486;  //for 3.5" TFT LCD Shield , 0x9341 for 2.8" TFT LCD Shield

  tft.begin(ID);
  tft.setRotation(rotar); //0-PORTRAIT 1-PAYSAGE 2-REVERSE PORTRAIT 3-REVERSE PAYSAGE
  Serial.println(F("Adafruit MPU6050 test!"));
  // Try to initialize Gyroskope
  if (!mpu.begin()) {
    Serial.println(F("Failed to find MPU6050 chip"));
    while (1) {
    }
  }
  Serial.println(F("MPU6050 Found!"));
  mpu.setAccelerometerRange(MPU6050_RANGE_16_G);
  Serial.print(F("Accelerometer range set to: "));
  switch (mpu.getAccelerometerRange()) {
    case MPU6050_RANGE_2_G:
      Serial.println(F("+-2G"));
      break;
    case MPU6050_RANGE_4_G:
      Serial.println(F("+-4G"));
      break;
    case MPU6050_RANGE_8_G:
      Serial.println(F("+-8G"));
      break;
    case MPU6050_RANGE_16_G:
      Serial.println(F("+-16G"));
      break;
  }
  mpu.setGyroRange(MPU6050_RANGE_1000_DEG);
  Serial.print(F("Gyro range set to: "));
  switch (mpu.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      Serial.println(F("+- 250 deg/s"));
      break;
    case MPU6050_RANGE_500_DEG:
      Serial.println(F("+- 500 deg/s"));
      break;
    case MPU6050_RANGE_1000_DEG:
      Serial.println(F("+- 1000 deg/s"));
      break;
    case MPU6050_RANGE_2000_DEG:
      Serial.println(F("+- 2000 deg/s"));
      break;
  }
  mpu.setFilterBandwidth(MPU6050_BAND_260_HZ);
  Serial.print(F("Filter bandwidth set to: "));
  switch (mpu.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      Serial.println(F("260 Hz"));
      break;
    case MPU6050_BAND_184_HZ:
      Serial.println(F("184 Hz"));
      break;
    case MPU6050_BAND_94_HZ:
      Serial.println(F("94 Hz"));
      break;
    case MPU6050_BAND_44_HZ:
      Serial.println(F("44 Hz"));
      break;
    case MPU6050_BAND_21_HZ:
      Serial.println(F("21 Hz"));
      break;
    case MPU6050_BAND_10_HZ:
      Serial.println(F("10 Hz"));
      break;
    case MPU6050_BAND_5_HZ:
      Serial.println(F("5 Hz"));
      break;
  }
  readMPU();
  x_corr = x;
  y_corr = y;
  Serial.print(F("X: "));
  Serial.println(x);
  Serial.print(F("Y: "));
  Serial.println(y);
  if (x_corr > 0) x_corr = x_corr * -1;
  else x_corr = x_corr * -1;
  if (y_corr > 0) y_corr = y_corr * -1;
  else y_corr = y_corr * -1;
  x = x + x_corr;
  y = y + y_corr;
  Serial.print(F("X_corr: "));
  Serial.println(x_corr);
  Serial.print(F("Y_corr: "));
  Serial.println(y_corr);
  Serial.print(F("X: "));
  Serial.println(x);
  Serial.print(F("Y: "));
  Serial.println(y);
  //Wire starten
  Wire.begin();
  Wire.setClock(400000L);
  drawSplashScreen();
  delay(2000);
  {
    currentPage = TEMP;
  }
  //Temperatursensor starten
  dht.begin();
  Serial.println(F("DHTxx Unified Sensor Example"));
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  // Print humidity sensor details.
  dht.humidity().getSensor(&sensor);
  startdebouncer = 0;
}
//##############################################
//#Loop
//##############################################
void loop(void)
{
  checkButtons();
  readMPU();
  switch (currentPage)
  {
    case SPLASH:
      if (currentPage != oldPage) drawSplashScreen();
      if (button == 4)
      {
        currentPage = TEMP;
      }
      if (button == 1)
      {
        currentPage = NEUSTART;
      }
      break;

    case TEMP: //Menu page
      if (currentPage != oldPage)   drawTempScreen();
      updateTemp();

      if (button == 1)
      {
        resetButtons();
        currentPage = SPLASH;
      }
      if (button == 4)
      {
        resetButtons();
        currentPage = LEVEL;
      }
      break;

    case LEVEL: //Nivelieren
      if (currentPage != oldPage)   drawLevelScreen();
      getLevel();
      if (button == 1)
      {
        resetButtons();
        currentPage = TEMP;
      }
      if (button == 4)
      {
        resetButtons();
        currentPage = INFO;
      }
      break;

    case INFO:
      if (currentPage != oldPage) drawInfoScreen();
      if (button == 1)
      {
        resetButtons();
        currentPage = LEVEL;
      }
      if (button == 4)
      {
        resetButtons();
        currentPage = NEUSTART;
      }
      break;
    case NEUSTART: //System zurücksetzen
      if (currentPage != oldPage) drawResetScreen();
      if (button == 5)
      {
        resetFunc();
      }
      if (button == 1)
      {
        resetButtons();
        currentPage = INFO;
      }
      if (button == 4)
      {
        resetButtons();
        currentPage = SPLASH;
      }
      break;

  }
}
/************************************************************************************
    Screens anzeigen
************************************************************************************/
void drawSplashScreen()
{
  resetButtons();
  tft.fillScreen( 0x0000);
  tft.drawBitmap(tft.width() / 2 - 160, tft.height() / 2 - 65, rimor, 250, 65, Schriftf);
  tft.drawBitmap(tft.width() / 2, tft.height() / 2, sailer, 120, 60, Schriftf);
  oldPage = currentPage;
}

void drawTempScreen()
{
  resetButtons();
  tft.setRotation(rotar);
  tft.fillScreen( 0x0000);//(100, 155, 203)
  oldPage = currentPage;
  getTemp();
  updateTemp();
  tft.setTextColor(Schriftf,  0x0000);
  tft.setTextSize(3);
  tft.setCursor(50, 150);
  tft.setTextColor(Schriftf,  0x0000);
  tft.setTextSize(2);
  tft.setCursor(272, 150);
  showmsgXY(20, 50, 1, &FreeSans18pt7b, "Temperatur", Schriftf);
  showmsgXYi(20, 200, 2, &FreeSans24pt7b, temp, Schriftf);
  tft.drawCircle(150, 150, 10, Schriftf);
  tft.drawCircle(150, 150, 11, Schriftf);
  tft.drawCircle(150, 150, 12, Schriftf);
  tft.drawCircle(150, 150, 13, Schriftf);
  tft.drawCircle(150, 150, 14, Schriftf);
  tft.setTextSize(3);
  tft.setCursor(170, 200);
  tft.setFont(&FreeSans24pt7b);
  tft.setTextSize(2);
  tft.write("C");
  tft.drawLine(240, 1, 240, 319, Schriftf);
  showmsgXY(260, 50, 1, &FreeSans18pt7b, "Feuchtigkeit", Schriftf);
  showmsgXYi(260, 200, 2, &FreeSans24pt7b, hum, Schriftf);
  showmsgXY(390, 200, 2, &FreeSans24pt7b, "%", Schriftf);
}

void drawLevelScreen()
{
  resetButtons();
  tft.setRotation(rotar);
  tft.fillScreen( 0x0000);
  tft.fillCircle(160, 185, 100, 0x07e0 );
  tft.drawCircle(160, 185, 20,  0x0000);
  tft.drawCircle(160, 185, 101, WHITE);
  showmsgXY(20, 30, 1,  &FreeSans12pt7b, "Nivelierung", Schriftf);
  tft.drawLine(0, 34, tft.width() * 0.6, 34, Vorder);
  tft.setFont ();
  getLevel();
  oldPage = currentPage;
}

void drawInfoScreen()
{
  resetButtons();
  tft.setRotation(rotar);
  tft.fillScreen( 0x0000);
  tft.setFont(&FreeSans12pt7b);
  tft.drawRoundRect(10, 50, tft.width() - 20, tft.height() - 60, 5, Vorder);
  tft.setTextColor(Schriftf);
  tft.setCursor(20, 30);
  tft.write("Informationen uber das System");
  tft.drawRect(173, 13, 2, 2, Schriftf);
  tft.drawRect(177, 13, 2, 2, Schriftf);
  tft.setCursor(25, 80);
  tft.write("Dieses System wurde in muhevoller");
  tft.drawRect(303, 63, 2, 2, Schriftf);
  tft.drawRect(307, 63, 2, 2, Schriftf);
  tft.setCursor(25, 105);
  tft.write("Kleinstarbeit und mit viel Zeit");
  tft.setCursor(25, 130);
  tft.write("von Roland zusammengekloppelt");
  tft.drawRect(310, 113, 2, 2, Schriftf);
  tft.drawRect(314, 113, 2, 2, Schriftf);
  tft.setCursor(25, 155);
  tft.write("Bei Fragen gerne melden.");
  tft.setCursor(25, 205);
  tft.write("Tel: +41 79 XXX XX XX");
  tft.setCursor(25, 230);
  tft.write("email: rxxxxxxxxx@gmail.com");
  tft.setCursor(25, 280);
  tft.write("Programmversion: ");
  tft.print(Version);
  tft.setFont ();
  oldPage = currentPage;
}
/*##################################################################
  ## Screen für: Neustart
  ##################################################################*/
void drawResetScreen()
{
  resetButtons();
  tft.fillScreen( 0x0000);

  showmsgXY(20, 30, 1, &FreeSans12pt7b, "Neustart", Schriftf);
  tft.drawLine(0, 34, tft.width() * 0.6, 34, Vorder);
  showmsgXY(25, 70, 1, &FreeSans12pt7b, "Bei einem Neustart des Systems", Schriftf);
  showmsgXY(25, 95, 1, &FreeSans12pt7b, "werden alle Parameter neu geladen.", Schriftf);
  showmsgXY(25, 120, 1, &FreeSans12pt7b, "Das Fahrzeug muss dabei ganz", Schriftf);
  showmsgXY(25, 145, 1, &FreeSans12pt7b, "gerade stehen, da der Niveausensor", Schriftf);
  showmsgXY(25, 170, 1, &FreeSans12pt7b, "dabei neu kalibriert wird.", Schriftf);
  showmsgXY(25, 220, 1, &FreeSans12pt7b, "Ok = Neu starten", Schriftf);
  oldPage = currentPage;
}
/************************************************************************************
    Zusätzliche Funktionen
*************************************************************************************/

//##############################################
//#Temperatursensor auswerten
//##############################################
void getTemp()
{
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  temp = event.temperature;

  dht.humidity().getEvent(&event);
  hum = event.relative_humidity;
}


void updateTemp()
{
  getTemp();
  if ((temp) != (temp_alt))
  {
    tft.setTextColor(Schriftf,  0x0000);
    showmsgXYi(20, 200, 2, &FreeSans24pt7b, temp_alt, BLACK);
    showmsgXYi(20, 200, 2, &FreeSans24pt7b, temp, Schriftf);
    temp_alt = temp;
  }
  if ((hum) != (hum_alt))
  {
    showmsgXYi(260, 200, 2, &FreeSans24pt7b, hum_alt, BLACK);
    showmsgXYi(260, 200, 2, &FreeSans24pt7b, hum, Schriftf);
    hum_alt = hum;
  }
}
//#######################################################
//Nivelierung
//#######################################################
void getLevel()
{
  readMPU();
  nivel = millis();
  if (x_alt != x or y_alt != y)
  {
    if (nivel - startnivel > 500)
    {
      Serial.print(F("Verzögerung: "));
      Serial.println(nivel - startnivel);
      tft.fillCircle(x_alt * multix + 160, y_alt * multiy + 185, 12, 0x07e0);
      tft.drawCircle(160, 185, 20,  0x0000);
      tft.fillCircle(x * multix + 160, y * multiy + 185, 12, RED);
      x_alt = x;
      y_alt = y;
      startnivel = nivel;
    }
  }
  else
  {
    tft.fillCircle(x * multix + 160, y * multiy + 185, 12, RED);
  }
}
//##############################################
//#Nachricht an Position mit Schriftart etc.
//##############################################
void showmsgXY(int x, int y, int sz, const GFXfont * f, const char *msg, uint16_t Farbe)
{
  tft.setFont(f);
  tft.setCursor(x, y);
  tft.setTextColor(Farbe);
  tft.setTextSize(sz);
  tft.print(msg);
  tft.setFont();
  tft.setTextSize(1);
}

void showmsgXYi(int x, int y, int sz, const GFXfont * f, int msg, uint16_t Farbe)
{
  tft.setFont(f);
  tft.setCursor(x, y);
  tft.setTextColor(Farbe);
  tft.setTextSize(sz);
  tft.print(msg);
  tft.setFont();
  tft.setTextSize(1);
}

void showmsgXYf(int x, int y, int sz, const GFXfont * f, float msg, uint16_t Farbe)
{
  tft.setFont(f);
  tft.setCursor(x, y);
  tft.setTextColor(Farbe);
  tft.setTextSize(sz);
  tft.print(msg);
  tft.setFont();
  tft.setTextSize(1);
}
//##############################################
//#Gyroskop abfragen
//##############################################
void readMPU()
{
  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
  /* Print out the values */
  y = (a.acceleration.x + y_corr);
  x = a.acceleration.y + x_corr;
  Serial.println(F("-----------------------------------------"));
  Serial.print(F("X: "));
  Serial.println(x);
  Serial.print(F("Y: "));
  Serial.println(y);
}
//############################################
//Buttons auswerten
//############################################
void checkButtons()
{
  button = analogRead(ANALOG_PIN);
  switch (button)
  {
    case 0 ... 10:
      debouncer = millis();
      if (debouncer - startdebouncer > 50)
      {
        button = 1;
        startdebouncer = debouncer;
      }
      break;
    case 20 ... 40:
      debouncer = millis();
      if (debouncer - startdebouncer > 50)
      {
        button = 2;
        startdebouncer = debouncer;
      }
      break;
    case 70 ... 100:
      debouncer = millis();
      if (debouncer - startdebouncer > 50)
      {
        button = 3;
        startdebouncer = debouncer;
      }
      break;
    case 160 ... 180:
      debouncer = millis();
      if (debouncer - startdebouncer > 50)
      {
        button = 4;
        startdebouncer = debouncer;
      }
      break;
    case 340 ... 400:
      debouncer = millis();
      if (debouncer - startdebouncer > 50)
      {
        button = 5;
        startdebouncer = debouncer;
      }
      break;
    case 500 ... 1023:
      button = 0;
      break;
  }
}

void resetButtons()
{
  button = 0;
  looper = millis();
  if (looper - startlooper > 500)
  {
    Serial.print(F("Verzögerung: "));
    Serial.println(looper - startlooper);
    Serial.print(F("looper: "));
    Serial.println(looper); //warten
    startlooper = looper;
  }
}

könntest auch so schreiben:

constexpr uint8_t DHTPIN {33}; 

besser, mit kleinem Buchstaben beginnen - dann musst du aber mehr adaptieren:

constexpr uint8_t dhtPin {33}; 

es gäbe auch ein else if.
noch besser ... du kannst auch in einem Switch case noch einen weiteren switch case machen...

Das ist eher Geschmacksfrage, finde ich.
War auch mal guter Stil, Konstante GROSS zu schreiben.

Schlimmer finde ich die globale Variable button, die zwischendurch das Ergebnis eines analogRead hat und manchmal einen Wert von 0 .. 5. Und dass checkButtons den Rückgabetyp void hat.

ui...das habe ich gar nicht bedacht...aber es hat funktioniert :grimacing:
was sollte das denn haben?

was ist denn der Vorteil von constexpr?

wenn ich das richtig interpretiere ist das Speicherrelevant.....da ist es auf dem Mega aber in meinem Fall irrelevant

Der Sketch verwendet 57602 Bytes (22%) des Programmspeicherplatzes. Das Maximum sind 253952 Bytes.
Globale Variablen verwenden 1267 Bytes (15%) des dynamischen Speichers, 6925 Bytes für lokale Variablen verbleiben.

Falsch interpretiert.

Ich fass das mal kurz zusammen:
der compiler sieht #define nicht.
Das ist Textersetzung, die im code unendlich oft wiederholt werden kann, und nur der letzte / ein Wert gewinnt.

const ist da schon stabiler, da der Compiler das sieht, wenn Du mehrmals die selbe Bezeichnung wählst.

constexpr überprüft dann auch noch den Inhalt.

Nicht wirklich.

#define nutzt den alten C Preprozessor.
constexpr ist C++ und gibt der Konstanten einen Datentyp, wodurch der Compiler eventuelle Fehler von dir besser erkennen kann.

Kann denn

#define ANALOG_PIN A8

auch als constexpr definiert werden?

constexpr byte ANALOG_PIN {A8};

vielleicht?

ja danke.....hatte da bedenken wegen byte und A8

A8 ist in dem Fall ein Mapping und stellt nur eine Ersetzung für eine echte Zahl dar.

Welche Sorgen plagen dich da?

Übrigens:
const heißt im C/C++ Umfeld weniger Konstant, sondern eher ReadOnly.
Es trifft keine Aussage darüber, ob sich die Dinge im Programmlauf verändern.
Es verhindert bestenfalls, dass man sie versehentlich ändert.

constexpr und consteval Dinge sind dagegen wirklich unveränderlich