Bool Variable wechselt von ALLEINE ihren Wert!

Morgen zusammen,

ich hab da mal ein Phänomen welches ich absolut nicht verstehe.
Habe mir eine kleine Mini Wettersteuerung programmiert.
Nichts wildes, mit viel Code > da ich nicht so der Programmier Experte bin.

Ein kleines Steuerungsmodul (ESP 8266) holt sich alle paar Minuten Lichtwerte über UDP von einem Außenmodul und verarbeitet sie dann weiter… > gibt Steuerbefehle aus etc.

Der Code ist aber mittlerweile so viel, dass ich ihn beim besten Willen hier nicht reinstellen kann.
Aber glaub das ist auch nicht schlimm…

Im wesentlichen geht es darum:

Ich habe eine „bool“ Variable (StatusBitSofortDisplay) die Urplötzlich einfach ihren Wert ändert (32) und dadurch der Programmablauf natürlich einen ganz anderen Verlauf nimmt.

bool

Ich hab das durch viele „Kontrollausgaben“ im Seriellen Monitor einfangen können.
(von dem ganzen BlaBla im Seriellen Monitor nicht irritieren lassen)
Aber durch die Änderung springt mit das Programm in eine Schleife
(Kontrollausgabe „StatusBitSofortDisplay ist 1“).

Habt ihr hier eine Erklärung oder eine Idee was ich tun kann, woher das kommt...?
Muss / kann ich die Variable einfach alle paar Minuten frisch setzen oder so?

Besten dank

lieber nasly,

der Wert einer Variablen ändert sich

nicht

"von alleine."

Dein Programm

muss

einen bug haben.

es gibt verschiedene Möglichkeiten die das "von alleine ändern" einer Variable verursachen können.

  • speichern einer Zahl / String in ein Array-Element das nicht existiert (out of boundary)
  • Speicherüberlauf wegen sehr häufigem schreiben in Variablen vom Typ String
  • unsaubere Verwendung von pointern. Der pointer zeigt irgendwo falsches in den Speicher

ist eine Methode die noch mehr Fehler verursachen wird weil du die Ursache nicht beseitigst.

Jetzt poste halt deinen kompletten Sketch.
Selbst wenn der 10-tausend Zeilen hat kann man den Sketch mit Strg-F nach bestimmten Sachen durchsuchen.

vgs

In deinem Programm gibt es eine Zeile die genau das macht.
Verwendest du Arrays? Wenn ja ... kontrolliere jede Verwendung dass du sicher die Array Indexe einhältst.

macht für mich keinen Sinn.
Wozu eine Variable - wenn man sie dann auf Grund eines Bugs "auf Verdacht" wieder in den Ursprungswert ändert.

Vielleicht liegt das an sowas wie

if (StatusBitSofortDisplay=32) ...
1 Like

bool kann nur true und false.
Deine 32 sind nicht möglich.

Übrigens, ich weiß wo der Fehler ist:
Er sitzt ca 50cm von deinem Monitor entfernt.

Auch das wird eine bool Variable nur auf true setzen können, was dann einer 1 entspricht.

Eure Hinweise waren schon mal hilfreich.
In der Tat hab ich mit diesem Projekt erstmalig an ein Array getraut und versuche den Mittelwert zu bilden....

@combie
Sehr witzig... Aber wo du recht hast, hast du höchst wahrscheinlich recht...
Daher gibt es ja dieses Forum und euch Profis :crazy_face:

Aber ich hab das StatusBitSofortDisplay als bool deklariert, und gebe einfach den Wert im Seriellen Monitor aus.
Dehalb hat mich es ja gewundert warum da eine "32" steht!

@StefanL38 probieren wirs...
Ich probier es mal einzubinden...
Schon programmiert ist es für euch wahrscheinlich nicht.
Sei aber gesagt, dass ich den Code mitlerweile auf mehrere Tabs aufgeteilt habe.

// Steuerung Version 1.7 / 16.06.2022
// Steuerung_Client (NodeMCE 1.0 ESP-12E/ ESP8266-12F)
// IP Adresse Fritz Box: 192.168.178.200
//--------------------------------------------------------------------------------------------
//--- Deklarationen --------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Wire.h>
#include <LCD.h>                                                                    // Bibo für Display
#include <LiquidCrystal_I2C.h>                                                      // Bibo für I2C Schnittstelle Display,
#include <SimpleDHT.h>                                                              // Sensor Feuchte + Temp DHT11


// Display
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


// WiFi
const char* ssid = "***";                       // Darf bis zu 32 Zeichen haben.
const char* password = "***";                // Mindestens 8 Zeichen jedoch nicht länger als 64 Zeichen.

WiFiUDP UDP;
IPAddress DisplayEG_IP    (192, 168, 178, 205);           // Adresse des Esp, welcher als Empfänger der Nachricht dient.
IPAddress DisplayMobil_IP (192, 168, 178, 208);           // Adresse des Esp, welcher als Empfänger der Nachricht dient.
IPAddress Aussen_IP       (192, 168, 178, 211);           // Adresse des Esp, welcher als Empfänger der Nachricht dient.
IPAddress Wallbox_IP      (192, 168, 178, 212);           // Adresse des Esp, welcher als Empfänger der Nachricht dient.
constexpr uint16_t PORT = 4210;                           // UDP Port an welchen gesendet wird.
char packetBuffer[21];                                    // Puffer für eingehendes Paket.


// ESP8266-12F
#define flashButton 0                                     //
#define Taster 16                                         // Taster für Display


// Sensor Luftfeuchte + Temperatur
const int pinDHT11 = 0;
SimpleDHT11 dht11(pinDHT11);
int err = SimpleDHTErrSuccess;


// Zeitzähler
unsigned long aktuelleMillis;                             // Speicher aktuelle Millis
unsigned long SpeicherMillisTRLZ;                         // Speicher Restladezeit, Startzeit = 0
long SpeicherMillis1  = 0;                                // Speicher bisherige Zeit, Startzeit = 0
long SpeicherMillis2  = 0;                                // Speicher bisherige Zeit, Startzeit = 0
long SpeicherMillis3  = 0;                                // Speicher bisherige Zeit, Startzeit = 0
long SpeicherMillis4  = 0;                                // Speicher bisherige Zeit, Startzeit = 0
long SpeicherMillisTG = 0;                                // Speicher bisherige Zeit, Startzeit = 0
const long T  = 15000;                                    // Testzeit
//const long T  = 180000;                                   // Speicher für Zykluszeit T1, T2, T3 in ms = 3 min
const int TG  = 1000;                                     // T Programmzyklus in ms
long nPG;                                                 // Zähler Programmgeschwindigkeit in einer Sekunde


// Datenverarbeitung
bool StatusBitSofortDisplay = false;                      // Status Bit Display mit Startzustand
bool StatusBitLadezeit      = false;                      // Status Bit Display mit Startzustand

const int Anzahl_LUX = 10;                                // Anzahl der Speicherplätze in dem Array
float LUX[Anzahl_LUX];                                    // Array Lux zur Durschnittberechnung
float Mittelwert_LUX = 0;                                 // gemittelter Wert
float Summe_LUX;                                          // Speicher zum lux Wertberechnung


// Fehlerbehandlung
int StatusError1 = 0;                                     // Status Error mit Startzustand
int StatusError2 = 0;                                     // Status Error mit Startzustand
int nID205 = 0;                                           // Zähler für Prüfung der Datenverbindung
int nID208 = 0;
int nID211 = 0;
int nID212 = 0;
const byte n = 20;                                        // Maximalanzahl bis Fehlerauslösung; n * T = 20 * 3 min = 30min


// Steuerung
float TempSpeicherSteuerung;                              // Temepraturspeicher für Steuerung
float FeuchteSpeicherSteuerung;                           // Feuchtigkeitsspeicher Steuerung


// Displays
int LadeStatusVonDisplays = 88;                           // Status von Display mit Eingaben, 88 Startzusatnd
int EnergieStatusAnDisplays;                              //
unsigned long LadeZeit = 0;                               // Speicher welche Restladezeit gewünscht
unsigned long Restladezeit;                               // Restladezeit bis Ladestopp


// Display EG
float TempSpeicherDisplayEG;                              // Temepraturspeicher für Steuerung
float FeuchteSpeicherDisplayEG;                           // Feuchtigkeitsspeicher Steuerung
float DruckSpeicherDisplayEG;                             // Druckspeicher für DisplayEG


// Display OG
float TempSpeicherDisplayOG;                              // Temepraturspeicher für Steuerung
float FeuchteSpeicherDisplayOG;                           // Feuchtigkeitsspeicher Steuerung


// Display Mobil
float TempSpeicherDisplayMobil;                           // Temepraturspeicher für Steuerung
float FeuchteSpeicherDisplayMobil;                        // Feuchtigkeitsspeicher Steuerung


// Aussenmodul
float TempSpeicherAussen;                                 // Temepraturspeicher für Aussenmodul
float LuxSpeicherAussen;                                  // Luxspeicher für Aussenmodul
float DruckSpeicherAussen;                                // Luftdruckspreicher Aussenmodul
float FeuchteSpeicherAussen;                              // Feuchtigkeitsspeicher Aussenmodul


// Wallbox
float TempSpeicherWallbox;                                // Temepraturspeicher für Wallbox
int StatusAnWallbox = 0;                                  // Status Speicher für Wallbox (Relais und Freigabe) inkl. Starteinstellung
int StatusVonWallbox;                                     // Status von Wallbox zur Kontrolle
int StatusAltVonWallbox;                                  // Status von Wallbox zur Kontrolle
bool StatusBitSofortWallbox = 0;                          // Status Bit Wallbox mit Startzustand
const int Ladesperre  = 0;                                // 00000 Relaisstellung
const int Strom6A     = 1;                                // 10000 Relaisstellung
const int Strom8A     = 2;                                // 10100 Relaisstellung
const int Strom10A    = 3;                                // 10010 Relaisstellung
const int Strom12A    = 4;                                // 10110 Relaisstellung
const int Strom14A    = 5;                                // 10001 Relaisstellung
const int Strom16A    = 6;                                // 10101 Relaisstellung


//--------------------------------------------------------------------------------------------
//--- Setup ----------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------

void setup() {

  // Setup IO
  pinMode(flashButton, INPUT_PULLUP);                       // für ESP8266-12F

  // Starte Serielle Verbindung
  Serial.begin(115200);
  while (!Serial);
  delay(100);
  Serial.printf("\nSketchname: %s\nBuild: %s\t\tIDE: %d.%d.%d\n%s\n\n",
                (__FILE__), (__TIMESTAMP__), ARDUINO / 10000, ARDUINO % 10000 / 100, ARDUINO % 100 / 10 ? ARDUINO % 100 : ARDUINO % 10, ESP.getFullVersion().c_str());

  // Starte I2C
  // On esp8266 devices you can select SCL and SDA pins using Wire.begin(D1= CLk, D2=Data);
  Wire.begin();


  // LCD Display
  lcd.begin(20, 4);
  lcd.clear();
  lcd.setBacklight(HIGH);


  // Starte WiFi Verbindung
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    lcd.print(".");
  }
  Serial.println("\nVerbunden mit: " + WiFi.SSID());                                // verbundenes Netzwerk anzeigen
  Serial.print("meine ID: ");             Serial.println (WiFi.localIP());          // Adresse mit der im Netzwerk bekannt anzeigen

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (WiFi.SSID());
  lcd.setCursor(0, 1);
  lcd.print (WiFi.localIP());
  delay(5000);
  lcd.clear();


  // Begin UDP port
  UDP.begin(PORT);
  Serial.print("Opening UDP port ");        Serial.println(PORT);


  //--- Pins
  pinMode(LED_BUILTIN, OUTPUT);                                                       // onboard LED als Output definieren
  digitalWrite(LED_BUILTIN, HIGH);                                                    // LED aus

  pinMode(Taster, INPUT);                                                             // Taster = Eingang
}

//--------------------------------------------------------------------------------------------
//---Hauptprogramm----------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
void loop() {
  aktuelleMillis = millis();                                                        // schreibe in aktuelle Mills die Mills des Arduino

  //---Sofortiger Handlungsbedarf durch Änderung Display ---
  if (StatusBitSofortDisplay == true) {
    Serial.println("StatusBitSofortDisplay ist 1");
    Serial.println("Unterprogramm > Sende an Wallbox und lösche Status Bit");
    Wallbox();
    StatusBitSofortDisplay = false;                                                // Status Bit Display rückhgesetzt => normaler zeitlicher Durchlauf
  }



  //---Sofortiger Handlungsbedarf durch Änderung Wallbox ---
  if (StatusBitSofortWallbox == true) {
    Serial.println("StatusBitSofort Wallbox ist 1");
    Serial.println("Unterprogramm > Sende an Display und lösche Status Bit");
    DisplayEG();
    DisplayMobil();
    StatusBitSofortWallbox = false;                                                 // Status Bit Wallbox rückhgesetzt => normaler zeitlicher Durchlauf
  }



  //---Hauptintervall --- allg. Kontrollausgabe nach Zeitablauf, Fehlerbehandlung, Wallbox  ---
  if (aktuelleMillis - SpeicherMillis1 > T) {                                       // frage ab: ist aktuelle Mills - SpeicherMills noch größer als Wunschzeit
    SpeicherMillis1 = aktuelleMillis;                                               // schreibe in Speicher die aktuelle Millis
    Serial.println("");                                                             // Leerzeile
    Serial.println("Hauptzeitintervall ist abgelaufen.");                           // Kontrollausgabe
    Serial.print("StatusBitSofortWallbox: ");       Serial.println(StatusBitSofortWallbox);
    Serial.print("StatusBitSofortDisplay: ");       Serial.println(StatusBitSofortDisplay);
    Serial.print("StatusBitLadezeit: ");            Serial.println(StatusBitLadezeit);

    //---Fehlerbehandlung n = 20, T = 3 min > 20x3= 60 min ---
    if (nID205 > n) {                                                               // Display EG
      //ErrorBitID205 = true;                                                         // Error bit setzen
      Serial.print("Fehler Datenübertragung Display EG: ");                         // Kontrollausgabe
      Serial.print(DisplayEG_IP);
      Serial.print(" Anzahl Verbindungsfehler: ");  Serial.println(nID205);
      TempSpeicherDisplayEG     = 0;                                                // (Q) Temepraturspeicher für Steuerung auf 0 setzen
      FeuchteSpeicherDisplayEG  = 0;                                                // (R) Feuchtigkeitsspeicher Steuerung auf 0 setzen
      DruckSpeicherDisplayEG    = 0;                                                // (O) Druckspeicher für DisplayEG auf 0 setzen
    }
    else {
    }
    if (nID208 > n) {                                                               // Display Mobil
      //ErrorBitID208 = true;                                                       // Error bit setzen
      Serial.print("Fehler Datenübertragung Display Mobil: ");                      // Kontrollausgabe
      Serial.print(DisplayMobil_IP);
      Serial.print(" Anzahl Verbindungsfehler: ");  Serial.println(nID208);
      TempSpeicherDisplayMobil    = 0;                                              // (V) Temepraturspeicher für Steuerung auf 0 setzen
      FeuchteSpeicherDisplayMobil = 0;                                              // (W) Feuchtigkeitsspeicher Steuerung auf 0 setzen
    }
    else {
    }
    if (nID211 > n) {                                                               // Aussenmodul
      //   ErrorBitID211 = true;                                                         // Error bit setzen
      Serial.print("Fehler Datenübertragung Aussenmodul: ");                        // Kontrollausgabe
      Serial.print(Aussen_IP);
      Serial.print(" Anzahl Verbindungsfehler: ");  Serial.println(nID211);
      StatusError1 = nID211 * 3;                                                    // Schreibe in Status > Umrechnung in Minuten > Zykluszeit alles 3 min
      TempSpeicherAussen    = 0;                                                    // (M) Temepraturspeicher für Aussenmodul auf 0 setzen
      LuxSpeicherAussen     = 0;                                                    // (L) Luxspeicher für Aussenmodul auf 0 setzen
      DruckSpeicherAussen   = 0;                                                    // (P) Luftdruckspreicher Aussenmodul auf 0 setzen
      FeuchteSpeicherAussen = 0;                                                    // (N) Feuchtigkeitsspeicher Aussenmodul auf 0 setzen
    }
    else {
      StatusError1 = 0;
    }
    if (nID212 > n) {                                                               // Wallbox
      //   ErrorBitID212 = true;                                                         // Error bit setzen
      Serial.print("Fehler Datenübertragung Wallbox: ");                            // Kontrollausgabe
      Serial.print(Wallbox_IP);
      Serial.print(" Anzahl Verbindungsfehler: ");  Serial.println(nID212);
      StatusError2 = nID212 * 3;                                                    // Schreibe in Status > Umrechnung in Minuten > Zykluszeit alles 3 min
      TempSpeicherWallbox = 0;                                                      // (I) Temepraturspeicher für Wallbox auf 0 setzen
      StatusVonWallbox    = 0;                                                      // (J) Status von Wallbox zur Kontrolle auf 0 setzen
    }
    else {
      StatusError2 = 0;
    }
    nID205++;                                                                       // Zähler für Verlust Datenverbindung hochzählen
    nID208++;
    nID211++;
    nID212++;

    //---Wallbox ---
    Serial.println("Unterprogramm > Sende an Wallbox");
    Wallbox();
  }



  //---Hauptintervall + 100ms --- hole neuste Daten nach Zeitablauf---
  if (aktuelleMillis - SpeicherMillis2 > T + 100) {                                 // frage ab: ist aktuelle Mills - SpeicherMills noch größer als Wunschzeit
    SpeicherMillis2 = aktuelleMillis;                                               // schreibe in Speicher die aktuelle Millis
    Serial.println("Unterprogramm > Abfrage Außenmodul");
    Abfrage_Aussenmodul();
    Durchschnitt_LUX();                                                             // Durchschnittsberechnung aufrufen
  }



  //---Hauptintervall + 200ms ---Sende Daten Display nach Zeitablauf---             // Display als letztes senden damit aller neuesten Infos angezeigt werden
  if (aktuelleMillis - SpeicherMillis3 > T + 200) {                                 // frage ab: ist aktuelle Mills - SpeicherMills noch größer als Wunschzeit
    SpeicherMillis3 = aktuelleMillis;                                               // schreibe in Speicher die aktuelle Millis
    Serial.println("Unterprogramm > Sende an Display EG");
    DisplayEG();
  }


  //---Hauptintervall + 700ms ---Sende Daten Display nach Zeitablauf---             // Display als letztes senden damit aller neuesten Infos angezeigt werden
  if (aktuelleMillis - SpeicherMillis4 > T + 700) {                                 // frage ab: ist aktuelle Mills - SpeicherMills noch größer als Wunschzeit
    SpeicherMillis4 = aktuelleMillis;                                               // schreibe in Speicher die aktuelle Millis
    Serial.println("Unterprogramm > Sende an Display Mobil");
    DisplayMobil();
  }


  //---kleiner Intervall (1s) --- Zähler Programmgeschwindigkeit, Temperatur, LCD_Display Ausgabe ---
  nPG++;                                                                             // Zähler hochzählen
  //---Programmgeschwindigkeit ---
  if (aktuelleMillis - SpeicherMillisTG > TG) {                                      // frage ab: ist aktuelle Mills - SpeicherMills noch größer als Wunschzeit
    SpeicherMillisTG = aktuelleMillis;                                               // schreibe in Speicher die aktuelle Millis
    //Serial.print("Programmgeschwindigkeit: "); Serial.println(nPG);                  // Kontrollausgabe
    //digitalWrite(LED_BUILTIN, !(digitalRead(LED_BUILTIN)));                         // onboard LED umschalten Ausschalten

    //---Luftfeuchte + Temperatur Steuerung ---
    if ((err = dht11.read2(&TempSpeicherSteuerung, &FeuchteSpeicherSteuerung, NULL)) != SimpleDHTErrSuccess) {
      //  Serial.print("Lesefehler DHT11, err=");     Serial.println(err);              // Kontrollausgabe
    }
    //Serial.print("Temperatur Steuerung: ");     Serial.println((float)TempSpeicherSteuerung);
    //Serial.print("Luftfeuchte Steuerung: ");    Serial.println((float)FeuchteSpeicherSteuerung);
    LCD_Display();                                                                  // Aufruf LCD Display
    nPG = 0;                                                                        // reset Programmdurchlaufszähler
  }


  //---Datenempfang ---
  uint16_t packetSize = UDP.parsePacket();                                          // Eingehende UDP-Pakete empfangen.
  if (packetSize) {                                                                 // Prüfen ob UDP-Pakete empfangen wurden.
    UDP.read(packetBuffer, sizeof(packetBuffer));                                   // Einlesen des UDP Paket in den Buffer.
    packetBuffer[packetSize] = 0;                                                   // String Ende hinzufügen.
    //Serial.print("Rohwert packetBuffer: ");    Serial.println(packetBuffer);        // Visualisierung des empfangenen Packets.
    Datenempfang(packetBuffer);                                                     // Rufe Unterprogramm auf > welche Daten wurden Empfangen
  }

  //--- Datenverarbeitung Restladezeit ---
  if (StatusBitLadezeit == true ) {                                                 // Laden mit Restladezeit läuft
    //Serial.print ("aktuelle millis: "); Serial.println (aktuelleMillis);
    Restladezeit = SpeicherMillisTRLZ - aktuelleMillis;                             // ermittle Restladezeit = Endzeit - aktuelleMillis
    //Serial.print ("Restladezeit nach Rechnung (SpeicherMillisTRLZ - aktuelleMillis): "); Serial.println (Restladezeit);
    if (SpeicherMillisTRLZ < aktuelleMillis) {                                      //laden mit Restladezeit ist vorbei
      Serial.println("Restladezeit vorbei!");
      //StatusBitLadezeit     = false;                                                // Restladezeit vorbei
      Restladezeit          = 0;                                                    // Restladezeit exakt 0!
      LadeStatusVonDisplays = 0;                                                    // LadeStatusVonDisplays reseten damit beim nächsten Programmdurchlauf kein Autostart erfolgt
      StatusAnWallbox = Ladesperre;                                                 // setze Ladesperre!
      Wallbox();                                                                    // Sende an Wallbox
    }
  }

  //---Datenverarbeitung Wallbox Laden !!!> hier auch Solarmanagment!!! ---
  switch (LadeStatusVonDisplays) {
    case 0:
      StatusAnWallbox = Ladesperre;
      Restladezeit = 0;
      break;
    case 1:
      StatusAnWallbox = Strom6A;
      break;
    case 2:
      StatusAnWallbox = Strom10A;
      break;
    case 3:
      StatusAnWallbox = Strom16A;
      break;
    default:;
  }


  //--- Bestimmung Reststrom durch Mittelwert ---
  if (Mittelwert_LUX < 200)                             EnergieStatusAnDisplays = 0;
  if (Mittelwert_LUX >= 200  && Mittelwert_LUX < 350)   EnergieStatusAnDisplays = 1;
  if (Mittelwert_LUX >= 350  && Mittelwert_LUX < 1000)  EnergieStatusAnDisplays = 2;
  if (Mittelwert_LUX >= 1000 && Mittelwert_LUX < 3000)  EnergieStatusAnDisplays = 3;
  if (Mittelwert_LUX >= 3000 && Mittelwert_LUX < 7000)  EnergieStatusAnDisplays = 4;
  if (Mittelwert_LUX > 7000)                            EnergieStatusAnDisplays = 5;


}


//--------------------------------------------------------------------------------------
//---Unterprogramme --------------------------------------------------------------------
//--------------------------------------------------------------------------------------
void Durchschnitt_LUX() {
  for (int i = Anzahl_LUX; i > 0; i--) {
    LUX[i] = LUX[i - 1];                                                            // Lux werte im Array weiterrücken
  }

  LUX[0] = LuxSpeicherAussen;                                                       // Neuen Luxwert an größte Stelle schreiben
  Summe_LUX = 0;                                                                    // Speicher für neue Berechnng löschen
  Serial.print("Lux Array: ");

  for (int i = Anzahl_LUX; i > 0; i = i - 1) {                                      // Schleife um Lux Array Inhalte zu addieren
    Serial.print("  ");                 Serial.print(LUX[i]);                       // Kontrollausgabe
    Summe_LUX = Summe_LUX + LUX[i];                                                 // Array addieren
  }

  Mittelwert_LUX = Summe_LUX / Anzahl_LUX;                                          // Durchschnitt bilden
  Serial.println (" ");
  Serial.print("Summe LUX Array: ");    Serial.println(Summe_LUX);
  Serial.print("Mittelwert Lux: ");     Serial.println(Mittelwert_LUX);
}
void Abfrage_Aussenmodul() {
  UDP.beginPacket(Aussen_IP, PORT);
  UDP.write("Werte");                                                             // Werte anfordern
  UDP.endPacket();
}
void Datenempfang(const char* str) {

  //--- Display EG---
  if (UDP.remoteIP() == DisplayEG_IP) {                                                                         // kam die Nachricht vom Display?
    nID205 = 0;                                                                                                 // Zähler Datenverbindung rücksetzen}

    switch (str[0]) {
      case 'F':
        switch (str[1]) {
          case 'A':
            DruckSpeicherDisplayEG = atof(str + 2);
            Serial.print("Druck von Display EG nach case Vergleich: ");       Serial.println(DruckSpeicherDisplayEG);
            break;

          case 'B':
            TempSpeicherDisplayEG = atof(str + 2);
            Serial.print("Temperatur von Display EG nach case Vergleich: ");  Serial.println(TempSpeicherDisplayEG);
            break;

          case 'C':
            FeuchteSpeicherDisplayEG = atof(str + 2);
            Serial.print("Feuchte von Display EG nach case Vergleich: ");     Serial.println(FeuchteSpeicherDisplayEG);
            break;
        }
        break;

      case 'X':
        switch (str[1]) {
          case 'A':
            LadeStatusVonDisplays = atof(str + 2);
            Serial.print("Status von Display EG nach case Vergleich: ");      Serial.println(LadeStatusVonDisplays);
            StatusBitSofortDisplay = true;                                                                          // Neuer Status > Benutzer wünscht Änderung > Status bit setzen
            break;

          case 'B':
            LadeZeit = atof(str + 2);
            Serial.print("LadeZeit von Displays nach case Vergleich: ");      Serial.println(LadeZeit);
            if (LadeZeit == 310) StatusBitLadezeit = false;                                                      // Dauerladen
            if (LadeZeit < 310) {                                                                                // Benutzer wünscht Ladung mit Zeit!
              Restladezeit = LadeZeit * 60000;                                                                   // echte RestLadeZeit in ms ermitteln (Zeit * 60.000ms)
              Serial.print("RestLadeZeit = LadeZeit*60000): ");               Serial.println(Restladezeit);
              StatusBitLadezeit = true;
              SpeicherMillisTRLZ = aktuelleMillis + Restladezeit;                                                // rechne zu aktuellen Millis die Ladezeit um die Endzeit zu ermitteln
              Serial.print("SpeicherMillisTRLZ = aktuelleMillis + Restladezeit: ");    Serial.println(SpeicherMillisTRLZ);
            }
            break;
        }
        break;
    }
  }


  //--- Display Mobil ---
  if (UDP.remoteIP() == DisplayMobil_IP) {                                                                      // kam die Nachricht vom Display?
    nID208 = 0;                                                                                                 // Zähler Datenverbindung rücksetzen}

    switch (str[0]) {
      case 'G':
        switch (str[1]) {
          case 'A':
            TempSpeicherDisplayMobil = atof(str + 2);
            Serial.print("Temperatur von Display Mobil nach case Vergleich: ");  Serial.println(TempSpeicherDisplayMobil);
            break;

          case 'B':
            FeuchteSpeicherDisplayMobil = atof(str + 2);
            Serial.print("Feuchte von Display Mobil nach case Vergleich: ");     Serial.println(FeuchteSpeicherDisplayMobil);
            break;
        }
        break;

      case 'X':
        switch (str[1]) {
          case 'A':
            LadeStatusVonDisplays = atof(str + 2);
            Serial.print("Status von Display Mobil nach case Vergleich: ");      Serial.println(LadeStatusVonDisplays);
            StatusBitSofortDisplay = true;                                                                       // Neuer Status > Benutzer wünscht Änderung > Status bit setzen
            break;

          case 'B':
            LadeZeit = atof(str + 2);
            Serial.print("LadeZeit von Displays nach case Vergleich: ");        Serial.println(LadeZeit);
            if (LadeZeit == 310) StatusBitLadezeit = false;                                                      // Dauerladen
            if (LadeZeit < 310) {                                                                                // Benutzer wünscht Ladung mit Zeit!
              Restladezeit = LadeZeit * 60000;                                                                   // echte RestLadeZeit in ms ermitteln (Zeit * 60.000ms)
              Serial.print("RestLadeZeit = LadeZeit*60000): ");                 Serial.println(Restladezeit);
              StatusBitLadezeit = true;
              SpeicherMillisTRLZ = aktuelleMillis + Restladezeit;                                                // rechne zu aktuellen Millis die Ladezeit um die Endzeit zu ermitteln
              Serial.print("SpeicherMillisTRLZ = aktuelleMillis + Restladezeit: ");    Serial.println(SpeicherMillisTRLZ);
            }
            break;
        }
        break;
    }
  }



  //--- Aussenmodul ---
  if (UDP.remoteIP() == Aussen_IP) {                                                                            // kam die Nachricht vom Aussenmodul?
    nID211 = 0;                                                                                                 // Zähler Datenverbindung rücksetzen

    switch (str[0]) {
      case 'J':
        switch (str[1]) {
          case 'A':
            LuxSpeicherAussen = atof(str + 2);
            Serial.print("Luxwert Aussen nach case Vergleich: ");             Serial.println(LuxSpeicherAussen);
            break;

          case 'B':
            TempSpeicherAussen = atof(str + 2);
            Serial.print("Tempwert Aussen nach case Vergleich: ");            Serial.println(TempSpeicherAussen);
            break;

          case 'C':
            FeuchteSpeicherAussen = atof(str + 2);
            Serial.print("Feuchtigkeit Aussen nach case Vergleich: ");        Serial.println(FeuchteSpeicherAussen);
            break;

          case 'D':
            DruckSpeicherAussen = atof(str + 2);
            Serial.print("Luftdruck Aussen nach case Vergleich: ");           Serial.println(DruckSpeicherAussen);
            break;
        }
        break;
    }
  }

  //--- Wallbox ---
  if (UDP.remoteIP() == Wallbox_IP) {                                                                             // kam die Nachricht vom Aussenmodul?
    nID212 = 0;                                                                                                   // Zähler Datenverbindung rücksetzen}

    switch (str[0]) {
      case 'K':
        switch (str[1]) {
          case 'A':
            TempSpeicherWallbox = atof(str + 2);
            Serial.print("Tempwert Wallbox nach case Vergleich: ");           Serial.println(TempSpeicherWallbox);
            break;

          case 'B':
            StatusVonWallbox = atof(str + 2);
            Serial.print("Status von Wallbox nach case Vergleich: ");         Serial.println(StatusVonWallbox);
            if (StatusVonWallbox != StatusAltVonWallbox) {                                                          // neuer Zusatand empfangen!
              Serial.print("alter Status von Wallbox: ");                     Serial.println(StatusAltVonWallbox);
              StatusAltVonWallbox = StatusVonWallbox;                                                                 // Status für nächsten Vergleich sichern
              StatusBitSofortWallbox = true;                                                                          // Neuer Status von Wallbox > Status bit setzen
            }
            break;
        }
        break;
    }
  }
}
void DisplayMobil() {

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("AA%i", StatusError1);                                                          // Fehlerzeit in Minuten
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("AB%i", StatusError2);                                                          // Fehlerzeit in Minuten
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("AF%i", EnergieStatusAnDisplays);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("AG%f", Mittelwert_LUX);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("AK%i", (Restladezeit / 60000));                                                   // inkl. Umrechnung in Minuten
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("KA%.2f", TempSpeicherWallbox);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("KB%i", StatusVonWallbox);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("JA%.2f", LuxSpeicherAussen);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("JB%.2f", TempSpeicherAussen);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("JC%.2f", FeuchteSpeicherAussen);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("JD%.2f", DruckSpeicherAussen);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("FA%.2f", DruckSpeicherDisplayEG);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("FB%.2f", TempSpeicherDisplayEG);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("FC%.2f", FeuchteSpeicherDisplayEG);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("AI%.2f", TempSpeicherSteuerung);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("AJ%.2f", FeuchteSpeicherSteuerung);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("HA%.2f", TempSpeicherDisplayOG);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.printf("HB%.2f", FeuchteSpeicherDisplayOG);
  UDP.endPacket();
  delay(20);

  UDP.beginPacket(DisplayMobil_IP, PORT);
  UDP.write("Werte");                                                                         // Werte anfordern
  UDP.endPacket();
  delay(20);
}
void LCD_Display() {                                                          // 20 Zeichen  / 4 Zeilen

  lcd.clear();

  // --- Zeile 1 ---
  lcd.setCursor(0, 0);
  lcd.print (TempSpeicherSteuerung, 0);         lcd.print ("*C");

  lcd.setCursor(6, 0);
  lcd.print (FeuchteSpeicherSteuerung, 0);      lcd.print ("%");

  lcd.setCursor(11, 0);
  lcd.print ("out: ");  lcd.print(TempSpeicherAussen, 0);   lcd.print ("*C"); // Temperatur außen


  // --- Zeile 2 ---
  lcd.setCursor(0, 1);
  if (StatusVonWallbox == 0) {
    lcd.print("Ladestopp");

  }
  if (StatusVonWallbox == 1) {
    lcd.print("Lade: 4,1kW");
  }
  if (StatusVonWallbox == 2) {
    lcd.print("Lade: 5,5kW");
  }
  if (StatusVonWallbox == 3) {
    lcd.print("Lade: 6,9kW");
  }
  if (StatusVonWallbox == 4) {
    lcd.print("Lade: 8,3kW");
  }
  if (StatusVonWallbox == 5) {
    lcd.print("Lade: 9,7kW");
  }
  if (StatusVonWallbox == 6) {
    lcd.print("Lade: 11kW");
  }

  // --- Zeile 3 ---
  lcd.setCursor(0, 2);
  lcd.print("D:");        lcd.print( Mittelwert_LUX, 0);   lcd.print (" lx"); // Helligkeit ausgeben
  lcd.setCursor(11, 2);
  lcd.print("Status: ");  lcd.print(EnergieStatusAnDisplays);


  // --- Zeile 4 ---
  lcd.setCursor(0, 3);
  lcd.print("a:");        lcd.print(LuxSpeicherAussen, 0); lcd.print (" lx");            // Helligkeit ausgeben
  
  if ((nID205 > n) || (nID208 > n) || (nID211 > n) || (nID212 > n)) {
    lcd.setCursor(0, 3);
    lcd.print ("Error > Taste");
  }
  lcd.setCursor(15, 3);                                                       // Programmdurchlauf Typisch 70.000
  lcd.print (nPG);


  // Tastendruck
  if (digitalRead(Taster) == LOW) {                                           // Taster gedrückt > Masse
    lcd.clear();
    if (nID205 > n) {
      lcd.setCursor(0, 0);
      lcd.print("ID205: ");    lcd.print(nID205 * 3);   lcd.print(" min");    // Ausgabe und Umrechnung in min (*3)
    }
    if (nID208 > n) {
      lcd.setCursor(0, 1);
      lcd.print("ID208: ");    lcd.print(nID208 * 3);   lcd.print(" min");    // Ausgabe und Umrechnung in min (*3)
    }
    if (nID211 > n) {
      lcd.setCursor(0, 2);
      lcd.print("ID211: ");    lcd.print(nID211 * 3);   lcd.print(" min");    // Ausgabe und Umrechnung in min (*3)
    }
    if (nID212 > n) {
      lcd.setCursor(0, 3);
      lcd.print("ID212: ");    lcd.print(nID212 * 3);   lcd.print(" min");    // Ausgabe und Umrechnung in min (*3)
    }
  }

}
void Wallbox() {
  UDP.beginPacket(Wallbox_IP, PORT);
  UDP.printf("K%i", StatusAnWallbox);                                                 // sendet String mit Kennung "S" und int Zahl
  UDP.endPacket();
  Serial.print("StatusAnWallbox: ");    Serial.println (StatusAnWallbox);
}

wenn Anzahl_LUX = 10 ist, schreibst du da das erste mal in LUX[10]

Hallo
mal als Beispiel ich habe bei der ersten Stelle aufgehört zu suchen.
schau mal hier , Anzahl_Lux ist mit 10 global festgelegt. Damit gibt es genau 10 Elemente. Arrays fangen mit dem Index 0 an damit hat das 10 Element den Index 9 .

Heinz

@noiasca
sehe ich ein Wenig anders , er schreibt das an die nächste Speicherstelle, da kann aber ganz was anderes sein.
Gruß Heinz

Das nennt sich "Undefined Behavior".
Das ist eine ganz wichtige Geschichte!

Die Ursachen sind im Grunde immer die gleichen.
Flüchtigkeitsfehler, oder auch evtl. Irrtum auf Grund fehlender Sprachkenntnisse,

Und es dürfte hier ziemlich sicher genau die Speicherzelle für StatusBitSofortDisplay sein.

Danke vorab!

Ich GLAUBE ich habs verstanden.
Versuch es mal mit meinen Worten zu beschreiben:
Dadurch, dass ich "const int Anzahl_LUX = 10;" deklariere habe ein Array mit 10 stellen von 0 bis 9.

Da ich aber im Code dann auch Anzahl_LUX schreibe

for (int i = Anzahl_LUX; i > 0; i--) {
LUX[i] = LUX[i - 1];
}

wäre das sozusagen die 11te Stelle welches es nicht gibt und wahrscheinlich bei StausBit ist.
Stimmt der Gedanke soweit?

Dann wäre der korrigierte Code einfach Anzahl_LUX-1?:

void Durchschnitt_LUX() {                                                           
  for (int i = Anzahl_LUX-1; i > 0; i--) {
    LUX[i] = LUX[i - 1];                                                            // Lux werte im Array weiterrücken
  }

  LUX[0] = LuxSpeicherAussen;                                                       // Neuen Luxwert an Stelle 0 schreiben
  Summe_LUX = 0;                                                                    // Speicher für neue Berechnng löschen
  Serial.print("Lux Array: ");

  for (int i = Anzahl_LUX-1; i > 0; i = i - 1) {                                      // Schleife um Lux Array Inhalte zu addieren
    Serial.print("  ");                 Serial.print(LUX[i]);                       // Kontrollausgabe
    Summe_LUX = Summe_LUX + LUX[i];                                                 // Array addieren
  }

  Mittelwert_LUX = Summe_LUX / Anzahl_LUX;                                          // Durchschnitt bilden
  Serial.println (" ");
  Serial.print("Summe LUX Array: ");    Serial.println(Summe_LUX);
  Serial.print("Mittelwert Lux: ");     Serial.println(Mittelwert_LUX);
}

Ein wenig verwirrt bin ich schon :crazy_face:

Das Wort "Stellen" finde ich an dieser Stelle unpassend. "Stelle" hört sich an wie "einzelne Zahl".

Es ist ein Array mit 10 Elementen wobei jedes Element den Datentyp hat der in der Deklaration steht.

vgs

imho brauchst du die Werte nicht kopieren/verschieben.
Du hast Platz für 10 Felder ("Array") und schreibst jedesmal in ein neues Feld.
Dazu merkst du dir die Schreibeposition und erhöhst diese fürs nächste Schreiben.
Am Ende / nach dem 10. Wert, fangst wieder bei 0 an.

void Durchschnitt_LUX()
 {    
  static byte pos = 0;                             // aktuelle Schreibeposition                                           
  LUX[pos] = LuxSpeicherAussen;                    // Neuen Luxwert an Stelle pos schreiben
  Summe_LUX = 0;                                   // Speicher für neue Berechnng löschen
  Serial.print("Lux Array: ");
  for (auto & i : LUX) {                           // Schleife um Lux Array Inhalte zu addieren
    Serial.print("  ");  Serial.print(i);          // Kontrollausgabe
    Summe_LUX += i;                                // Array addieren
  }
  pos++;
  if (pos >= Anzahl_LUX) pos = 0;                    

  Mittelwert_LUX = Summe_LUX / Anzahl_LUX;                                          // Durchschnitt bilden
  Serial.println ();
  Serial.print("Summe LUX Array: ");    Serial.println(Summe_LUX);
  Serial.print("Mittelwert Lux: ");     Serial.println(Mittelwert_LUX);
}

Meine Fresse!
Ich hab schon ein DIN A5 Ballt gekraxelt.... und kam nicht weiter. :face_with_peeking_eye:
Irgendwie hat es die Speicherstellen nicht richtig addiert.

Und dein Code geht auf anhieb! :heart_eyes:

Danke!

Codepassage versteh ich überhaupt nicht:

  for (auto & i : LUX) {                           // Schleife um Lux Array Inhalte zu addieren
    Summe_LUX += i;                                // Array addieren
  }

was macht auto?

das ist der richtige Weg! Jedes gute Programm beginnt mit einem Blatt Papier!

das andere findest du unter dem Suchbegriff "auto range based for loop"

mit auto bestimmt der Kompiler selbst den notwendigen Variablentyp
& setzt eine Referenz i auf den nten Wert im Feld LUX beim durchgehen der For Schleife

Ich teile die Verwirrung...

// Datenverarbeitung
bool StatusBitSofortDisplay = false;                      // Status Bit Display mit Startzustand
bool StatusBitLadezeit      = false;                      // Status Bit Display mit Startzustand

const int Anzahl_LUX = 10;                                // Anzahl der Speicherplätze in dem Array
float LUX[Anzahl_LUX];                                    // Array Lux zur Durschnittberechnung
float Mittelwert_LUX = 0;                                 // gemittelter Wert
float Summe_LUX;

Unter der Annahme, dass die Dinge so hintereinander im Speicher liegen wie sie deklariert wurden, zerschießt du dir mit dem Zugriff auf das Element hinter dem Array nämlich statt StatusBitSofortDisplay die Variable Mittelwert_LUX.

Meine Annahme kann falsch sein.

Die Annahme ist nicht nur höchstvermutlich falsch, sondern auch hochgradig irrational.

Nur innerhalb von struct oder class gibt es eine vorhersagbare Reihenfolge

Oder Deine Schleife läuft for (int i=1; i < Anzahl_LUX; i++)

Nachtrag für @Doc_Arduino : damit müßten nur die Werte von hinten nach vorne kopiert werden, was für mich erst einmal logisch war. Für den Mittelwert ändert sich garnichts, der wird mit LUX[0] initialisiert.

Und noch eine Variante für einen kompletten Durchlauf:

for (int i = Anzahl_LUX; --i >= 0; )

Hallo,

@ Dr.: Womit dann ein Index fehlt.

Der klassische Weg zum verstehen.

const byte ANZAHL {10};
int myArray[ANZAHL];

// oder automatisch ermittelt
const byte ANZ = sizeof(myArray)/sizeof(myArray[0]);

void setup (void)
{
  Serial.begin(250000);
  Serial.println("\nuC Reset #### ####");

  Serial.print("autom. ermittelt ");
  Serial.println(ANZ);
  
  Serial.println("vorwärts");
  for (byte i=0; i<ANZAHL; i++)
  {
    Serial.print("index ");
    Serial.println(i);
  }

  Serial.println("rückwärts");
  for (int i=ANZAHL-1; i>=0; i--)
  {
    Serial.print("index ");
    Serial.println(i);
  }
}

void loop (void)
{

}