Probleme mit millis

Moin Zusammen,
ich habe da ein kleines Problem und komme nicht dahinter woran es liegt.
Der Code denn ich unten eingefügt habe ist noch nicht komplett bzw. habe ich daran noch etwas geändert um den Problem auf die Spur zu kommen.
Mein Problem ist jedoch, das die millis() bei über 4000000 starten und somit meine Timerbedingung direkt erfüllt ist. Der zweite Durchlauf des Timers passt dann, danach sind die Millis immer Null.
Weiß zufällig jemand woran das liegen könnte?
Vielen Dank.

#include <SoftwareSerial.h>
#include <SD.h>
#include "LedControl.h"


const int chipSelect = 10;

SoftwareSerial RS232(2, 3);

long myTimer2 = millis();
long myTimeout2 = 20000;

byte rs232_inChar;
float O2;
byte H2S1;
byte H2S2;
byte H2S3;
byte H21;
byte H22;
byte H23;
byte CO21;
byte CO22;
byte CO23;
byte CH41;
byte CH42;
byte CH43;
byte idx;

float deltaH2S[2];
int deltaCO2[2];
int deltaCH4[2];
int vergleich = 3;


int i = 4;
int s = 1;
int t = 1;
int z = 0;

byte a[9] = { B00000010, B00011100, B00011110, B00010000, B00011110, B00011110, B00111110, B00111110, B00000000 };
byte b[9] = { B00000110, B00100010, B00000010, B00010010, B00010000, B00010000, B00100010, B00100010, B00000001 };
byte c[9] = { B00001010, B00000010, B00000010, B00010010, B00010000, B00010000, B00000010, B00100010, B00000010 };
byte d[9] = { B00000010, B00000100, B00001110, B00011110, B00011110, B00011110, B00000100, B00111110, B00000100 };
byte e[9] = { B00000010, B00001000, B00000010, B00000010, B00000010, B00010010, B00001000, B00100010, B10001000 };
byte f[9] = { B00000010, B00010000, B00000010, B00000010, B00000010, B00010010, B00010000, B00100010, B01010000 };
byte g[9] = { B00000010, B00111110, B00011110, B00000010, B00011110, B00011110, B00100000, B00111110, B00100000 };
byte h[9] = { B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000 };


void setup() {
 
  deltaH2S[1] = 100;
  deltaCO2[1] = 100;
  deltaCH4[1] = 100;
  deltaH2S[2] = 1000;
  deltaCO2[2] = 1000;
  deltaCH4[2] = 1000;
  
  // PIN 4-9 und 14-15 als Output für Relais
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);

  digitalWrite(i, HIGH);  // öffnet Relais1 an PIN 4

  Serial.begin(9600);
 while (!Serial)
    ;

  RS232.begin(9600);

  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1)
      ;
  }
  Serial.println("card initialized.");
}



void einlesen() { 

  if (RS232.available() > 0) {
    rs232_inChar = RS232.read();
    {
      // *INDENT-OFF*
      switch (idx) {
        case 0:
          [[fallthrough]] case 2 : if (rs232_inChar == 86) {
            idx++;
          }
          else {
            idx = 0;
          }
          break;
        case 1:
          if (rs232_inChar == 171) {
            idx++;
          } else {
            idx = 0;
          }
          break;
        case 3:
          if (rs232_inChar == 2) {
            idx++;
          } else {
            idx = 0;
          }
          break;
        case 4 ... 116:
          {
            idx++;
          }
          break;
        case 117: O2 = rs232_inChar;
        case 118: H2S1 = rs232_inChar;
        case 119: H2S2 = rs232_inChar;
        case 120: H2S3 = rs232_inChar;
        case 121: H21 = rs232_inChar;
        case 122: H22 = rs232_inChar;
        case 123: H23 = rs232_inChar;
        case 124: CO21 = rs232_inChar;
        case 125: CO22 = rs232_inChar;
        case 126: CO23 = rs232_inChar;
        case 127: CH41 = rs232_inChar;
        case 128: CH42 = rs232_inChar;
        case 129:
          CH43 = rs232_inChar;
          idx++;
          break;
        default:
          idx = 0;
          break;
      }
      // *INDENT-ON*
    }
  }
}

void timer_und_ausgeben() {
 
  if ((abs((deltaH2S[1] - deltaH2S[2]) / deltaH2S[2] * 100)) <=1 ){//&& (abs((deltaCH4[1] - deltaCH4[2]) / deltaCH4[2] * 100)) <= 1 && (abs((deltaCO2[1] - deltaCO2[2]) / deltaCO2[2] * 100) <= 1)) {

    Serial.println(deltaH2S[1]);
    Serial.println(deltaH2S[2]);
    Serial.println(vergleich);
    Serial.println((deltaH2S[1] - deltaH2S[2]) / deltaH2S[2] * 100);
    Serial.println(abs(deltaH2S[1] - deltaH2S[2]));
    Serial.print(" Vol.-% O2");
    Serial.print(",");
    Serial.print(H2S1);
    Serial.print(",");
    Serial.print(H2S2);
    Serial.print(",");
    Serial.print(H2S3);
    Serial.print(",");
    Serial.print("H2S");
    Serial.print(",");
    Serial.print(H21);
    Serial.print(",");
    Serial.print(H22);
    Serial.print(",");
    Serial.print(H23);
    Serial.print(",");
    Serial.print("H2");
    Serial.print(",");
    Serial.print(CO21);
    Serial.print(",");
    Serial.print(CO22);
    Serial.print(",");
    Serial.print(CO23);
    Serial.print(",");
    Serial.print("CO2");
    Serial.print(",");
    Serial.print(CH41);
    Serial.print(",");
    Serial.print(CH42);
    Serial.print(",");
    Serial.print(CH43);
    Serial.print(",");
    Serial.print("CH4");
    Serial.println();


    File dataFile = SD.open("datalog.txt", FILE_WRITE);

    // if the file is available, write to it:
    if (dataFile) {

      dataFile.print(" Gassack: ");
      dataFile.print(t);
      dataFile.print(" ;");
      dataFile.print(O2 / 10);
      dataFile.print(";Vol.-% O2;");
      dataFile.print(H2S1 + H2S2 * 256 + H2S3 * 65536);
      dataFile.print(";ppm H2S;");
      dataFile.print(H21 + H22 * 256 + H23 * 65536);
      dataFile.print(";ppm H2;");
      dataFile.print(CO21 + CO22 * 256 + CO23 * 65536);
      dataFile.print(";ppm CO2;");
      dataFile.print(CH41 + CH42 * 256 + CH43 * 65536);
      dataFile.print(";ppm CH4 ;");
      dataFile.print(O2);
      dataFile.print(" ;");
      dataFile.print(H2S1);
      dataFile.print(";H2S1;");
      dataFile.print(H2S2);
      dataFile.print(";H2S2;");
      dataFile.print(H2S3);
      dataFile.print(";H2S3;");
      dataFile.print(H21);
      dataFile.print(";H21;");
      dataFile.print(H22);
      dataFile.print(";H22;");
      dataFile.print(H23);
      dataFile.print(";H23;");
      dataFile.print(CO21);
      dataFile.print(";CO21;");
      dataFile.print(CO22);
      dataFile.print(";CO22;");
      dataFile.print(CO23);
      dataFile.print(";CO23;");
      dataFile.print(CH41);
      dataFile.print(";CH41;");
      dataFile.print(CH42);
      dataFile.print(";CH42;");
      dataFile.print(CH43);
      dataFile.print(";CH43;");
      dataFile.println();
      dataFile.close();
    }

    t = t + 1;

    digitalWrite(i, LOW);
    delay(5000);
    deltaH2S[1] = 100;
    deltaCO2[1] = 100;
    deltaCH4[1] = 100;
    deltaH2S[2] = 1000;
    deltaCO2[2] = 1000;
    deltaCH4[2] = 1000;
    myTimeout2 = 10000;

    


    // if (z == 8) z = 0;


    s = s + 1;
    i = i + 1;
    if (i == 10) i = 14;
    // if (i == 16) i = 4;
    if (i == 16) {
      Serial.print("Ende der Messung");
      delay(5000);
      exit(0);  //beendet Lauf nach Relais 8
    }
  } else
    digitalWrite(i, HIGH);
 
  if (millis() - myTimer2 > myTimeout2) {
    myTimer2 = millis();
    myTimeout2 = 20000;
       Serial.print("Anfang ");
       Serial.println(vergleich);
    deltaH2S[vergleich] = (H2S1 + H2S2 * 256 + H2S3 * 65536);
    deltaCO2[vergleich] = (CO21 + CO22 * 256 + CO23 * 65536);
    deltaCH4[vergleich] = (CH41 + CH42 * 256 + CH43 * 65536);
    vergleich = vergleich + 1;
    if (vergleich >= 3) vergleich = 1;
    Serial.print("Ende ");
    Serial.println(vergleich);
    Serial.println(abs((deltaH2S[1] - deltaH2S[2]) / deltaH2S[2] * 100));
    Serial.print("Zeit: ");
    Serial.println(millis());
    
   

  }
}
void loop() {
  einlesen();
  timer_und_ausgeben();
}

Huch, da seh ich Schnipsel von mir... :slight_smile:
Aehm... Mein erster Blick geht immer in den Gültigkeitsbereich einer Variable.
Alles was mit millis() zu tun hat, und irgendwie dahingehend gerechnet wird, muss das auch aufnehmen können.
Da millis() uint32_t / unsigned long ist, ist das definieren auf long evtl. eine schlechte Idee.
Alle Deine Variablen von long nach unsigned long ändern. Dann nochmal probieren.

Das hat leider nichts gebracht.

Und ja, da sind einige Schnipsel zusammengefügt. :innocent:

Welche Deiner Ausgaben ist denn anfangs falsch?

Nicht wenn sie die Variablen in setup() mit den aktuellen millis() vorbesetzt werden.

Hier ist mal die Ausgabe vom seriellen Monitor nach 20 Sekunde.
Die erste If-Abfrage in void timer_und_ausgeben() wird richtigerweise übersprungen und dann geht es mit dem If nach else weiter.

Initializing SD card...card initialized.
Anfang 3
Ende 1
90.00
Zeit: 4487690
Anfang 1
Ende 2
100.00
Zeit: 4507688

Aehmm..
Kannst Du mal bitte im SerMon die Ausgabe der aktuellen Zeit mit anhaken?
Und dann die ersten Ausgaben ab SD-Card init mit 3-4 Umläufen, das ich was habe zum suchen?

Das ändert leider auch nichts, der Timer ist sofort erfüllt.

Hier sind mal die Daten vom Monitor.

10:56:08.637 -> Anfang 3

10:56:08.637 -> Ende 1

10:56:08.637 -> 90.00

10:56:08.682 -> Zeit: 4487680

10:56:28.661 -> Anfang 1

10:56:28.661 -> Ende 2

10:56:28.661 -> 100.00

10:56:28.661 -> Zeit: 4507681

10:56:48.657 -> Anfang 2

10:56:48.657 -> Ende 1

10:56:48.689 -> nan

10:56:48.689 -> Zeit: 0

10:56:48.689 -> Anfang 1

10:56:48.689 -> Ende 2

10:56:48.733 -> nan

10:56:48.733 -> Zeit: 0

10:57:08.685 -> Anfang 2

10:57:08.685 -> Ende 1

10:57:08.685 -> nan

10:57:08.718 -> Zeit: 0

10:57:08.718 -> Anfang 1

10:57:08.718 -> Ende 2

10:57:08.718 -> nan

10:57:08.761 -> Zeit: 0

10:57:28.697 -> Anfang 2

10:57:28.697 -> Ende 1

10:57:28.697 -> nan

10:57:28.730 -> Zeit: 0

10:57:28.730 -> Anfang 1

10:57:28.730 -> Ende 2

10:57:28.773 -> nan

10:57:28.774 -> Zeit: 0

long myTimer2 = millis();
long myTimeout2 = 20000;
unsigned long myTimer2 = 0;
unsigned long myTimeout2 = 20000;

wieso alle deine Timeout's werden immer wieder neu geschrieben? hast du Aufgabe erhalten nicht mehr als 1 Variable zu nutzen?

float deltaH2S[2];
int deltaCO2[2];
int deltaCH4[2];

...

  deltaH2S[1] = 100;
  deltaCO2[1] = 100;
  deltaCH4[1] = 100;
  deltaH2S[2] = 1000;
  deltaCO2[2] = 1000;
  deltaCH4[2] = 1000;
int i = 4;
...
digitalWrite(i, HIGH);  // öffnet Relais1 an PIN 4

was ist das:

        case 0:
          [[fallthrough]] case 2 :

Die Antwort/Frage verstehe ich leider nicht.

Zum Timeout:
Ich hatte myTimer2 am Anfang mal auf Millis gesetzt um zu sehen ob es dann funktioniert. Eigentlich ist er am Anfang auf Null gesetzt und dann nach dem Durchlauf auf die aktuellen Millis.

wieso sprichst du über Timer2 und wie du millis() probierst, obwohl etwas zu Timeouts sagen wolltest?
was ist mit anderen meinen Fragen?

Ok, dann verstehe ich deine Post überhaupt nicht, bzw. was sind den deine Fragen?

zu erst die.

So ist hübscher...

   case 0 :
   case 2 :      [[fallthrough]] 

Oder für ältere GCC (wird im Kommentar erkannt)

   case 0 :
   case 2 :      /* fallthrough */

geht es hübscher?

      case 4 ... 116:
        idx++;
        break;
      case 117: O2 = inChar;
      case 118: H2S1 = inChar;
      case 119: H2S2 = inChar;
      case 120: H2S3 = inChar;
      case 121: H21 = inChar;
      case 122: H22 = inChar;
      case 123: H23 = inChar;
      case 124: CO21 = inChar;
      case 125: CO22 = inChar;
      case 126: CO23 = inChar;
      case 127: CH41 = inChar;
      case 128: CH42 = inChar;

Bei scharf gestellten Warnungen meldet der Kompiler einen fall through (Durchfall).
Der Kommentar, oder das Attribut, sagt dem Kompiler, dass der Durchfall von 0 zu 2 beabsichtigt ist, verhindert also die Meldung

Also die Aussage mit dem Fragezeichen kann ich leider nicht beantworten.

Zu dem "was ist das:" : Hier werden beide Fälle in einem zusammengefasst.

Keine Ahnung, funktioniert aber.

danke dir.

darf man so definieren mehrere identische case's ?