Absturzsicher Taschenrechner

Hi ich habe einen Tascschenrechner mit vielen Features auf einen Arduino Uno gequetscht.

Features des Codes


1. Touchscreen-Bedienung

  • 5x5 Tastenfeld auf 3,5" TFT mit MCUFriend
    (Zahlen, Operatoren, Funktionen, Klammern, Löschen usw.)
  • Große Tastenflächen und klare Labels für einfaches Tippen
  • Jede Taste reagiert direkt auf Berührung

2. Serieller Modus (USB/Serial Monitor)

  • Rechnen per Serial Monitor (z.B. Arduino IDE → Werkzeuge → Serieller Monitor)
  • Komplette Rechnungen eingeben (12+34/2, sqrt(16)+2, 1/0)
  • Auch Operatoren-Fortsetzung:
    Wenn ein Ergebnis im Display steht, reicht z.B. /2, um mit diesem Wert weiterzurechnen
    (Anzeige: 20, Serial: /2 → Anzeige: 10)

3. Autokorrektur von Eingaben

  • Automatische Korrektur typischer Syntaxfehler und unvollständiger Eingaben:
    • Komma wird zu Punkt (1,51.5)
    • Doppelte Operatoren werden entfernt (1++21+2)
    • Operatoren direkt nach ( werden entfernt ((+)5(5))
    • Leere Klammern entfernt (() → entfernt)
    • Zahlen direkt vor einer Klammer (2(3+4)) → Multiplikationszeichen eingefügt (2*(3+4))
    • Klammer gefolgt von Zahl ((2)3(2)*3)
    • Fehlende schließende Klammern werden ergänzt
    • Ausdruck ohne Zahl (++--((()))) wird zu "0"
    • Leere Eingabe wird zu "0"
    • End-Operatoren werden entfernt (2+3+2+3)
    • Doppelte Plus/Minus am Anfang werden reduziert (--44)
  • Ergebnis:
    Sehr viel weniger „ERR“ – Eingaben werden wie bei modernen Rechnern interpretiert

4. Mathematik-Parser

  • Eigener Parser für Ausdrücke mit Klammern, Punkt-vor-Strich, mehrere Operatoren
  • Operatoren: +, -, *, /, %
  • Klammern beliebig verschachtelt
  • Funktionen:
    • sqrt(…) (Wurzel)
    • sq(…) (Quadrat)
    • inv(…) (Kehrwert, 1/x)
  • Direkte Quadrat-/Wurzel-Taste am Touchscreen (x^2, sqrt, 1/x)

5. Komfortables Fehlerhandling

  • Division durch Null, zu große/kleine Ergebnisse, Stacküberlauf → Anzeige „ERR“
  • Nach „ERR“ kann weitergerechnet werden (Touch oder Serial, keine Blockade mehr)
  • **„C“ löscht alles und setzt auf „0“ zurück
  • Watchdog-Timer (2s):
    Sollte dennoch ein Fehler im Code (Endlosschleife, Stacküberlauf) passieren, startet das System automatisch neu

6. Ergebnisformatierung

  • Ganze Zahlen werden als Integer angezeigt (ohne .0)
  • Kommazahlen werden ohne unnötige Nullen ausgegeben
  • Sehr große Zahlen (Überlauf) führen zu „ERR“

7. Synchronisierte Anzeige

  • Egal ob über Touch oder Serial gerechnet wird:
    Das Ergebnis ist immer sofort auf dem Display und im Serial Monitor sichtbar

8. Zusätzliche Komfortfunktionen

  • Löschen einzelner Zeichen („<-“)
  • Vorzeichen umschalten („+/-“)
  • Prozent-Umrechnung
  • Automatisches Weiterrechnen nach Touch oder Serial

9. Speichersicher, stabil und absturzfest

  • Alle Array-Kopien und -Längen werden korrekt geprüft (Buffer Overflow-Schutz)
  • Eingabegrößen (Touch und Serial) sind begrenzt (INPUT_MAX)
  • Alle Stackoperationen geprüft:
    Tiefe Klammerausdrücke führen zu „ERR“, nicht zum Absturz

10. Benutzerfreundlichkeit

  • Fehlerkorrektur statt Fehlermeldung
  • Keine Angst mehr vor Syntaxfehlern
  • Funktioniert wie ein smarter Taschenrechner am Smartphone

Funktioniert mit Touchschreen oder Seriel (115200 baud)

#include <MCUFRIEND_kbv.h>
#include <Adafruit_GFX.h>
#include <TouchScreen.h>
#include <avr/wdt.h>

#define MINPRESSURE 200
#define MAXPRESSURE 1000

const int XP = 8, XM = A2, YP = A3, YM = 9;
const int TS_LEFT = 125, TS_RT = 920, TS_TOP = 948, TS_BOT = 97;

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
MCUFRIEND_kbv tft;

#define INPUT_MAX 40
const char* button_labels[5][5] = {
  {"7", "8", "9", "/", "C"},
  {"4", "5", "6", "*", "<-"},
  {"1", "2", "3", "-", "("},
  {"0", ".", "=", "+", ")"},
  {"sqrt", "x^2", "1/x", "%", "+/-"}
};

#define ROWS 5
#define COLS 5
int pixel_x, pixel_y;

#define STACK_MAX 12
float numStack[STACK_MAX];
char opStack[STACK_MAX];
int ns = 0, os = 0;

char input[INPUT_MAX+1] = "0";
bool errorFlag = false;

void serialPrintInput() {
  Serial.print("Display: ");
  Serial.println(input);
}

// --- Erweiterte Autokorrektur ---
void autoCorrect(char* in) {
  // 1. Kommas in Punkte umwandeln
  for (int i = 0; in[i]; i++) if (in[i] == ',') in[i] = '.';

  // 2. Doppelte Operatoren ersetzen
  int len = strlen(in), j = 0;
  char tmp[INPUT_MAX + 1];
  for (int i = 0; i < len && j < INPUT_MAX; i++) {
    if (i > 0 && strchr("+-*/%", in[i]) && strchr("+-*/%", in[i-1]))
      continue;
    tmp[j++] = in[i];
  }
  tmp[j] = 0;
  strncpy(in, tmp, INPUT_MAX); in[INPUT_MAX] = 0;

  // 3. Entferne Operator direkt nach '('
  len = strlen(in); j = 0;
  for (int i = 0; i < len && j < INPUT_MAX; i++) {
    if (in[i] == '(' && strchr("+-*/%.", in[i+1])) continue;
    tmp[j++] = in[i];
  }
  tmp[j] = 0;
  strncpy(in, tmp, INPUT_MAX); in[INPUT_MAX] = 0;

  // 4. Entferne leere Klammern "()"
  len = strlen(in); j = 0;
  for (int i = 0; i < len && j < INPUT_MAX; i++) {
    if (in[i] == '(' && in[i+1] == ')') { i++; continue; }
    tmp[j++] = in[i];
  }
  tmp[j] = 0;
  strncpy(in, tmp, INPUT_MAX); in[INPUT_MAX] = 0;

  // 5. Zahl vor '(' → '*' ergänzen
  len = strlen(in); j = 0;
  for (int i = 0; i < len && j < INPUT_MAX; i++) {
    tmp[j++] = in[i];
    if (isdigit(in[i]) && in[i+1] == '(' && j < INPUT_MAX) tmp[j++] = '*';
  }
  tmp[j] = 0;
  strncpy(in, tmp, INPUT_MAX); in[INPUT_MAX] = 0;

  // 6. ')' gefolgt von Zahl → '*' ergänzen
  len = strlen(in); j = 0;
  for (int i = 0; i < len && j < INPUT_MAX; i++) {
    tmp[j++] = in[i];
    if (in[i] == ')' && isdigit(in[i+1]) && j < INPUT_MAX) tmp[j++] = '*';
  }
  tmp[j] = 0;
  strncpy(in, tmp, INPUT_MAX); in[INPUT_MAX] = 0;

  // 7. Fehlende schließende Klammern ergänzen
  int bal = 0;
  for (int i = 0; in[i]; i++) {
    if (in[i] == '(') bal++;
    if (in[i] == ')') bal--;
  }
  while (bal > 0 && strlen(in) < INPUT_MAX - 1) {
    strcat(in, ")");
    bal--;
  }
  in[INPUT_MAX] = 0;

  // 8. Ausdruck nur Operatoren/Klammern → "0"
  bool hasDigit = false;
  for (int i = 0; in[i]; i++) if (isdigit(in[i])) { hasDigit = true; break; }
  if (!hasDigit) { strcpy(in, "0"); }

  // 9. Leere Eingabe als "0"
  if (strlen(in) == 0) strcpy(in, "0");

  // 10. Wenn mit Operator (außer '-') begonnen wird, 0 davorstellen
  if (strchr("+*/%", in[0])) {
    if (strlen(in) < INPUT_MAX - 1) {
      char tmp2[INPUT_MAX + 1];
      snprintf(tmp2, sizeof(tmp2), "0%s", in);
      strncpy(in, tmp2, INPUT_MAX); in[INPUT_MAX] = 0;
    }
  }

  // 11. Letztes Zeichen: Operator/Punkt/Klammer entfernen
  int n = strlen(in);
  while (n > 0 && strchr("+-*/%.(", in[n-1])) {
    in[--n] = 0;
  }

  // 12. Doppelte Plus/Minus am Anfang reduzieren
  while ((in[0] == '+' || in[0] == '-') && (in[1] == '+' || in[1] == '-')) {
    memmove(in, in+1, strlen(in));
    in[INPUT_MAX] = 0;
  }
}


// --- Sicherheitsprüfung ---
bool isSafeInput(const char* in) {
  int len = strlen(in);
  if (len == 0) return false;
  if (strchr("+-*/%", in[len-1])) return false;
  if (strchr("+*/%)", in[0])) return false;
  for (int i = 1; i < len; i++) {
    if (strchr("+-*/%", in[i]) && strchr("+-*/%", in[i-1])) return false;
  }
  int bal = 0;
  for (int i = 0; i < len; i++) {
    if (in[i] == '(') bal++;
    if (in[i] == ')') bal--;
    if (bal < 0) return false;
    if (in[i] == '(' && in[i+1] == ')') return false;
  }
  if (bal != 0) return false;
  for (int i = 1; i < len; i++) {
    if (in[i] == ')' && strchr("+-*/%(", in[i-1])) return false;
  }
  for (int i = 1; i < len; i++) {
    if (in[i] == '.' && (strchr("+-*/%()", in[i-1]) || in[i-1] == 0)) return false;
  }
  return true;
}

int precedence(char op) {
  if (op == '+' || op == '-') return 1;
  if (op == '*' || op == '/' || op == '%') return 2;
  return 0;
}
bool applyOp() {
  if (ns < 2) return false;
  float b = numStack[--ns], a = numStack[--ns];
  char op = opStack[--os];
  switch(op) {
    case '+': numStack[ns++] = a + b; break;
    case '-': numStack[ns++] = a - b; break;
    case '*': numStack[ns++] = a * b; break;
    case '/': if (b == 0) return false; numStack[ns++] = a / b; break;
    case '%': if (b == 0) return false; numStack[ns++] = fmod(a, b); break;
  }
  return true;
}
float evalExpr(const char* expr, bool& error) {
  ns = os = 0;
  int i = 0;
  while (expr[i]) {
    if (expr[i] == ' ') { i++; continue; }
    if (!strncmp(&expr[i], "sqrt(", 5)) {
      i += 5;
      int start = i, par = 1;
      while (expr[i] && par > 0) {
        if (expr[i] == '(') par++;
        if (expr[i] == ')') par--;
        i++;
      }
      int tocopy = min(i-start-1, (int)INPUT_MAX);
      char inner[INPUT_MAX+1]; strncpy(inner, &expr[start], tocopy); inner[tocopy] = 0;
      bool err = false;
      float x = evalExpr(inner, err);
      if (err || x < 0) { error = true; return 0; }
      if (ns >= STACK_MAX) { error = true; return 0; }
      numStack[ns++] = sqrt(x);
      continue;
    }
    if (!strncmp(&expr[i], "sq(", 3)) {
      i += 3;
      int start = i, par = 1;
      while (expr[i] && par > 0) {
        if (expr[i] == '(') par++;
        if (expr[i] == ')') par--;
        i++;
      }
      int tocopy = min(i-start-1, (int)INPUT_MAX);
      char inner[INPUT_MAX+1]; strncpy(inner, &expr[start], tocopy); inner[tocopy] = 0;
      bool err = false;
      float x = evalExpr(inner, err);
      if (err) { error = true; return 0; }
      if (ns >= STACK_MAX) { error = true; return 0; }
      numStack[ns++] = x * x;
      continue;
    }
    if (!strncmp(&expr[i], "inv(", 4)) {
      i += 4;
      int start = i, par = 1;
      while (expr[i] && par > 0) {
        if (expr[i] == '(') par++;
        if (expr[i] == ')') par--;
        i++;
      }
      int tocopy = min(i-start-1, (int)INPUT_MAX);
      char inner[INPUT_MAX+1]; strncpy(inner, &expr[start], tocopy); inner[tocopy] = 0;
      bool err = false;
      float x = evalExpr(inner, err);
      if (err || x == 0) { error = true; return 0; }
      if (ns >= STACK_MAX) { error = true; return 0; }
      numStack[ns++] = 1.0 / x;
      continue;
    }
    if (isdigit(expr[i]) || expr[i] == '.' || (expr[i] == '-' && (i == 0 || expr[i-1] == '('))) {
      char buf[16]; int bi=0;
      if (expr[i] == '-') buf[bi++] = expr[i++];
      while (isdigit(expr[i]) || expr[i] == '.') buf[bi++] = expr[i++];
      buf[bi]=0;
      if (ns >= STACK_MAX) { error = true; return 0; }
      numStack[ns++] = atof(buf);
    }
    else if (expr[i] == '(') { opStack[os++] = '('; i++; }
    else if (expr[i] == ')') {
      while (os > 0 && opStack[os-1] != '(') {
        if (!applyOp()) { error = true; return 0; }
      }
      if (os == 0) { error = true; return 0; }
      os--; i++;
    }
    else if (strchr("+-*/%", expr[i])) {
      char currOp = expr[i];
      while (os > 0 && precedence(opStack[os-1]) >= precedence(currOp)) {
        if (!applyOp()) { error = true; return 0; }
      }
      opStack[os++] = currOp;
      i++;
    }
    else { error = true; return 0; }
  }
  while (os > 0) {
    if (!applyOp()) { error = true; return 0; }
  }
  if (ns != 1) { error = true; return 0; }
  return numStack[0];
}

#define BTN_W  62
#define BTN_H  56
#define BTN_SX  3
#define BTN_SY  8
#define BTN_X0  5
#define BTN_Y0  140

void drawButtons() {
  tft.setTextSize(2);
  for (int row = 0; row < ROWS; row++) {
    for (int col = 0; col < COLS; col++) {
      int x = BTN_X0 + col * (BTN_W + BTN_SX);
      int y = BTN_Y0 + row * (BTN_H + BTN_SY);
      tft.fillRoundRect(x, y, BTN_W, BTN_H, 14, 0xC618);
      tft.drawRoundRect(x, y, BTN_W, BTN_H, 14, TFT_BLACK);
      int labelLen = strlen(button_labels[row][col]);
      int fontW = 12;
      int fontH = 16;
      int xOffset = BTN_W/2 - (labelLen*fontW)/2;
      int yOffset = BTN_H/2 - fontH/2;
      tft.setTextColor(TFT_BLACK);
      tft.setCursor(x + xOffset, y + yOffset);
      tft.print(button_labels[row][col]);
    }
  }
  tft.setTextSize(2);
}
void handleTouch(int px, int py) {
  for (int row = 0; row < ROWS; row++)
    for (int col = 0; col < COLS; col++) {
      int x = BTN_X0 + col * (BTN_W + BTN_SX);
      int y = BTN_Y0 + row * (BTN_H + BTN_SY);
      if (px >= x && px < x + BTN_W && py >= y && py < y + BTN_H) {
        handleButton(button_labels[row][col]);
        serialPrintInput();
      }
    }
}
void drawScreen() {
  tft.fillScreen(TFT_WHITE);
  tft.fillRoundRect(10, 40, 300, 65, 8, 0xFFFF);
  tft.drawRoundRect(10, 40, 300, 65, 8, 0x0000);
  drawButtons();
}
void showInput() {
  tft.fillRoundRect(15, 50, 280, 55, 6, 0xFFFF);
  tft.setTextColor(TFT_BLACK);
  tft.setTextSize(3);
  tft.setCursor(22, 67);
  int len = strlen(input);
  if (len > 12) tft.print("..." + String(&input[len-12]));
  else tft.print(input);
  serialPrintInput();
}
void resetCalc() {
  strcpy(input, "0");
  errorFlag = false;
  serialPrintInput();
}

void setup() {
  Serial.begin(115200);
  wdt_enable(WDTO_2S);
  uint16_t ID = tft.readID();
  tft.begin(ID);
  tft.setRotation(0);
  drawScreen();
  resetCalc();
  showInput();
  Serial.println("Touch-Taschenrechner bereit! Eingabe per Touch ODER Serial Monitor.");
  Serial.println("Beispiele:");
  Serial.println("1+2*3  -> 7");
  Serial.println("sqrt(9) -> 3");
  Serial.println("inv(2) -> 0.5");
  Serial.println("sq(5)  -> 25");
  Serial.println("C      -> Reset");
}

// --------- BUTTON HANDLER -----------
void handleButton(const char* btn) {
  int len = strlen(input);
  if (errorFlag && strcmp(btn,"C") && !(isdigit(btn[0]) && strlen(btn)==1)) return;
  if (!strcmp(btn,"C")) {
    resetCalc();
  }
  else if (!strcmp(btn,"<-")) {
    if (len > 1) { input[len-1]=0; }
    else strcpy(input, "0");
  }
  else if (!strcmp(btn,"=")) {
    autoCorrect(input);
    if (!isSafeInput(input)) {
      strcpy(input, "ERR");
      errorFlag = true;
      Serial.println("ERR");
      return;
    }
    bool error = false;
    float res = evalExpr(input, error);
    if (error || isinf(res) || isnan(res) || fabs(res) > 999999999) {
      strcpy(input, "ERR");
      errorFlag = true;
      Serial.println("ERR");
      return;
    }
    if (fabs(res - (long)res) < 1e-6) sprintf(input, "%ld", (long)res);
    else {
      dtostrf(res, 1, 6, input);
      char* p = input+strlen(input)-1;
      while (*p == '0' && p > input && *(p-1) != '.') *p-- = 0;
      if (*p == '.') *p = 0;
    }
    Serial.println(input);
  }
  else if (!strcmp(btn,"+/-")) {
    if (strcmp(input, "0") && strcmp(input, "ERR")) {
      if (input[0]=='-') memmove(input, input+1, strlen(input));
      else if (len < INPUT_MAX) { memmove(input+1, input, len+1); input[0]='-'; }
    }
  }
  else if (!strcmp(btn,"sqrt")) {
    float val = atof(input);
    if (val<0) { strcpy(input, "ERR"); errorFlag=true; Serial.println("ERR"); return; }
    val = sqrt(val);
    if (fabs(val - (long)val) < 1e-6) sprintf(input, "%ld", (long)val);
    else dtostrf(val, 1, 6, input);
    Serial.println(input);
  }
  else if (!strcmp(btn,"x^2")) {
    float val = atof(input); val *= val;
    if (fabs(val - (long)val) < 1e-6) sprintf(input, "%ld", (long)val);
    else dtostrf(val, 1, 6, input);
    Serial.println(input);
  }
  else if (!strcmp(btn,"1/x")) {
    float val = atof(input);
    if (val==0) { strcpy(input, "ERR"); errorFlag=true; Serial.println("ERR"); return; }
    val = 1.0/val;
    if (fabs(val - (long)val) < 1e-6) sprintf(input, "%ld", (long)val);
    else dtostrf(val, 1, 6, input);
    Serial.println(input);
  }
  else if (!strcmp(btn,"%")) {
    float val = atof(input);
    val = val / 100.0;
    if (fabs(val - (long)val) < 1e-6) sprintf(input, "%ld", (long)val);
    else dtostrf(val, 1, 6, input);
    Serial.println(input);
  }
  else if (!strcmp(btn,".") && !strchr(input, '.') && len < INPUT_MAX-1) {
    input[len] = '.'; input[len+1]=0;
  }
  else if (strlen(btn)==1 && isdigit(btn[0])) {
    if (!strcmp(input,"0") || !strcmp(input,"ERR")) { input[0]=btn[0]; input[1]=0; }
    else if (len < INPUT_MAX-1) { input[len]=btn[0]; input[len+1]=0; }
  }
  else if (strchr("+-*/()", btn[0]) && len < INPUT_MAX-1) {
    char last = (len>0) ? input[len-1] : 0;
    if ((strchr("+-*/%", last) && btn[0] != '(' && btn[0] != ')') ||
        (len == 0 && btn[0]!='(' && btn[0]!='-') ||
        (last == '(' && strchr("*/%)", btn[0]))) {
      return;
    }
    input[len]=btn[0]; input[len+1]=0;
  }
}

bool Touch_getXY(void)
{
  TSPoint p = ts.getPoint();
  pinMode(YP, OUTPUT);
  pinMode(XM, OUTPUT);
  digitalWrite(YP, HIGH);
  digitalWrite(XM, HIGH);
  bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
  if (pressed) {
    pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width());
    pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
  }
  return pressed;
}

// --- SERIELLER INTERPRETER ---
void interpretSerial(char* buf) {
  int l = strlen(buf);
  while (l > 0 && (buf[l-1]=='\n'||buf[l-1]=='\r')) buf[--l]=0;
  if (l==0) return;

  // Fehlerflag nach ERR zurücksetzen, falls kein C
  if ((errorFlag || strcmp(input, "ERR") == 0) && strcmp(buf, "C") && strcmp(buf, "c")) {
    errorFlag = false;
    if (strchr("+-*/%", buf[0])) strcpy(input, "0");
  }

  if (!strcmp(buf, "C") || !strcmp(buf, "c")) { resetCalc(); showInput(); return; }
  if (!strcmp(buf, "exit")) { asm volatile ("jmp 0"); return; }

  // Operator am Anfang → aktuellen Wert voranstellen
  if (strchr("+-*/%", buf[0]) && !errorFlag && strcmp(input, "ERR") != 0 && strlen(input) > 0) {
    char combined[INPUT_MAX*2+2];
    snprintf(combined, sizeof(combined), "%s%s", input, buf);
    strncpy(buf, combined, INPUT_MAX);
    buf[INPUT_MAX] = 0;
  }

  autoCorrect(buf);
  if (!isSafeInput(buf)) {
    strcpy(input, "ERR"); errorFlag = true;
    showInput();
    Serial.println("ERR");
    return;
  }
  bool error = false;
  float res = evalExpr(buf, error);
  if (error || isinf(res) || isnan(res) || fabs(res) > 999999999) {
    strcpy(input, "ERR"); errorFlag = true;
    showInput();
    Serial.println("ERR");
    return;
  }
  if (fabs(res - (long)res) < 1e-6)
    sprintf(input, "%ld", (long)res);
  else {
    dtostrf(res, 1, 6, input);
    char* p = input+strlen(input)-1;
    while (*p == '0' && p > input && *(p-1) != '.') *p-- = 0;
    if (*p == '.') *p = 0;
  }
  showInput();
  Serial.println(input);
}

void loop() {
  wdt_reset();
  static bool prevTouch = false;
  bool currTouch = Touch_getXY();
  if (prevTouch && !currTouch) {
    handleTouch(pixel_x, pixel_y);
    showInput();
  }
  prevTouch = currTouch;
  static char serBuf[INPUT_MAX + 1];
  static uint8_t serIdx = 0;
  while (Serial.available()) {
    char c = Serial.read();
    if (c == '\r' || c == '\n') {
      serBuf[serIdx] = 0;
      if (serIdx > 0) {
        interpretSerial(serBuf);
        serIdx = 0;
      }
    } else if (serIdx < INPUT_MAX && (isprint(c) || c == '\t')) {
      serBuf[serIdx++] = c;
    }
  }
}

Viel spass damit :)

Hallo,

das ist alles sehr löblich. Du müsstest nur etwas mehr schreiben welche Hardware genau benötigt wird und Links zu den verwendeten Libs mitteilen. Es gibt zu viele gleichnamige Libs die nicht untereinander kompatibel sind. Display ist auch so ein Glückspiel wenn man Pech hat. Da kommt es auf den verbauten Controller an usw. Dann stehen die Chancen gut das jemand verwenden kann bzw. wird.

Eine Frage am Anfang. Warum verwendest du den WatchDog?
Ändere einmal bitte die #define zu echten Konstanten mit constexpr.

Es ist halt nicht auszuschliessen das das Teil wenn man es drauf anlegt zum Beispiel durch veränderung des Codes abschmiert aber kein Problem einfach neustart :wink:

Verwendet wird das 3.5 TFT LCD Shild (3.5 inch TFT Full Color Screen Module 480x320 LCD Shield for Arduino Mega2560 | eBay.de)
Libarys:

Adafruit_TouchScreen
Adafruit_BusIO
Adafruit_GFX_Libary
MCUFRIEND_kbv

Der Sketch verwendet 30988 Bytes (96%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 935 Bytes (45%) des dynamischen Speichers, 1113 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.

Das stimmt wohl...

Viel spass damit :slight_smile:

Moin!

Ich sehe die Arbeit die du dir damit gemacht hast.
Sieht nach Gehirnschmalz aus.

Aber ich sehe auch viele Dinge, die mir nicht so schmecken, die gegen meine eigenen Regeln gehen.
Das sind alles Dinge die nicht wirklich die Funktion beeinflussen, somit eher mein Problem und nicht deins.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.