Wartet die Zeit nicht ab

Hallo zusammen,

ich hab gerade ein kleines Problem mit meinen “automatischen Durchläufen”.

Folgender Gedanke:

Alle 30 Sekunden soll das Steuergerät alle Terminal-ID’s zwischen scheibe_von und scheibe_bis durchlaufen. Dabei hat jedes Terminal 3 Sekunden Zeit zu antworten. Andernfalls wird es als Offline vermerkt.
Zudem werden ja auch Daten versendet oder eingesammelt, hier das selbe Spiel: Nachdem das Steuergerät seine Befehle gegeben hat, hat das Terminal 3 Sekunden Zeit zu reagieren.

Ich benutze folgenden Code (gekürtzt) :

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include <Keypad.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Streaming.h>

// Serial Daten
const int MAX_NUMBERS = 25;
int conSerial[MAX_NUMBERS];
int last_serial_check_time = 0;
int wait_serial = 0;
int do_what = 0;

// Turnierkonfigurationsvariablen
int scheiben[61];
int scheibe_von;
int scheibe_bis;
int scheibe_fehlt_quittier = 1;
int terminal_status = 0;
int talk_scheibe = 0;
int talk_mode = 0;

void setup()
{
  // Serialstart
  pinMode(2, OUTPUT);
  Serial.begin(115200);
  
  
  last_serial_check_time = millis();
  scheibe_von = 20;
  scheibe_bis = 24;
}

void loop()
{
  // Abfrage, ob Daten von Terminals warten
  if (readSerial())
  {
    if (conSerial[0] == 998)
    {
      if (((talk_mode == 1) || (talk_mode == 2) || (talk_mode == 3)) && ((conSerial[2] == 2) || (conSerial[2] == 1) || (conSerial[2] == 3)))
      {
        if (conSerial[1] == talk_scheibe)
        {
          scheiben[talk_scheibe] = 1;
          if (talk_scheibe < scheibe_bis) {
            talk_scheibe += 1; }
          else {
            talk_scheibe = scheibe_von;
            talk_mode = 0; }
        }
        else
        {
          if ((conSerial[1] >= scheibe_von) && (conSerial[1] <= scheibe_bis)) {
            scheiben[conSerial[1]] = 1; }
        }
        last_serial_check_time = millis();
        wait_serial = 0;
      }
      else if ((talk_mode == 4) && (conSerial[2] == 4))
      {
        if (client.connect(server_ip, 80)) 
        {
          
          wait_ethernet = 1;
        }
        else
        {
          ethernet_error = 1;
        }
      }
      display_new = 1;
    }
  }
  
  // Wenn Scheibe nach 3 Sek. nicht reagiert nächste
  if (((last_serial_check_time + 3000) <= millis()) && (wait_serial == 1))
  {
    //lcd.print(F("Hallo"));
    if (talk_scheibe < scheibe_bis)
    {
      talk_scheibe += 1;
    }
    else
    {
      talk_scheibe = scheibe_von;
      talk_mode = 0;
    }
    wait_serial = 0;
  }

  // Scheibennummern einsammeln und kontrollieren (Aufruf nächster Scheibe)
  if ((talk_mode == 1) && (wait_serial == 0))
  {
    digitalWrite(2,HIGH);
      Serial << "#" << talk_scheibe << F(",2") << endl;
    digitalWrite(2,LOW);
    wait_serial = 1;
    last_serial_check_time = millis();
  }
  
  // Vollständigkeit Scheiben prüfen (Start des Durchlaufs; Aufruf nächster Scheibe)
  if (((last_serial_check_time + (10 * 1000)) <= millis()) && (talk_mode == 0))
  {
    talk_mode = 2;
    talk_scheibe = scheibe_von;
    wait_serial = 0;
  }
  
  if ((talk_mode == 2) && (wait_serial == 0))
  {
    digitalWrite(2,HIGH);
      Serial << "#" << talk_scheibe << F(",3") << endl;
    digitalWrite(2,LOW);
    wait_serial = 1;
    last_serial_check_time = millis();
  }
  
  // Daten der Scheiben einsammeln (Aufruf nächster Scheibe)
  if ((talk_mode == 4) && (wait_serial == 0) && (wait_ethernet == 0))
  {
    digitalWrite(2,HIGH);
      Serial << "#" << talk_scheibe << F(",4") << endl;
    digitalWrite(2,LOW);
    wait_serial = 1;
    last_serial_check_time = millis();
  }

  
  // Daten an Scheibe senden
  if ((talk_mode == 3) && (wait_serial == 3) && (wait_ethernet == 0))
  {
    if (client.connect(server_ip, 80)) 
    {
      
      wait_ethernet = 1;
      check_scheibe = 0;
    }
    else
    {
      ethernet_error = 1;
    }
  }
}

// Serialempfänger
bool readSerial()
{
  static byte index;
  
  if(Serial.available())
  {
    char c = Serial.read();

    if(c >= '0' && c <= '9' && index < MAX_NUMBERS)
    {
      conSerial[index] = conSerial[index] * 10 + c - '0';
    }
    else if (c == '#')
    {
      conSerial[0] = 0;
      conSerial[1] = 0;
      conSerial[2] = 0;
    }
    else if(c == ',' && index < MAX_NUMBERS)
    {
      index++;
      conSerial[index] = 0;
    }
    else if(c == '\n')
    {
      index = 0;
      return true;
    }
    lcd.print("hallo");
  }

  return false;
}

Ich hab jetzt zum testen die 30 Sekunden auf 10 runter geschraubt, sonst wart ich mir hier ja nen Ast.

Mein Aufbau sieht gerade so aus, dass das Steuergerät am PC am Serial Monitor hängt.

Ich schalt das Steuergerät ein, mach nichts, außer zu warten, dass der Check durchläuft.
Tut er auch, nach 10 Sekunden erscheint: “#20,3”, 3 Sekunden später “#21,3” usw. bis “#24,3”. Dann ist 10 Sekunden Pause und er fängt wieder mit “#20,3” an. Aber dann ist Sense. Es passiert nichts mehr. Tipp ich jetzt am Serial Monitor “#20,1” ein, dann überschlägt sich der Atmega328P-PU und bombt den Serial Monitor mit den Zeilen:
#20,3
#21,3
#22,3
#23,3
#24,3”
voll und wiederholt das ständig. Ohne die von mir gesetzten Pausen. Nach ungefähr 10 - 15 Sekunden hört er auf und sendet nichts mehr. Und reagiert auch nicht drauf, wenn ich ihm über den Serial Monitor antworte.
Warum?

Fall zwei:
Ich schalt das Steuergerät ein und lass es die Terminals abchecken. Für ein Terminal antworte ich einfach mal via Serial Monitor mit “#998,22,1”. Das erkennt er und frägst sofort nach dem nächsten. Dann macht er seinen Durchlauf bis “24,3” fertig und lässt nichts mehr von sich hören. Wenn ich mit “#998,24,1” antworte, interessiert es ihn nicht. Aufgehängt hat er sich aber nicht, da ich am Display noch “arbeiten” kann via Tastatur.
Warum?

Mir kam mal der Gedanke, ob ich mir vllt. mit irgendwas den Speicher vollbomb, dass er dann nicht’s mehr machen will, aber ich wüsste nicht mit was. Alle Variablen werden nur überschrieben, alle print-Ausgaben sind in “F()” geschrieben.

An mir nagt wieder die Ahnungslosigkeit.
Mein Gefühl sagt mir, dass es entweder ein Leichtssinnsfehler ist, auf den ich schon tausend hingewiesen wurde oder der Fehler so tief in der Materie liegt, dass ich absaufen würde.

Ich hoffe mal, ihr könnt mir leicht verständlich auf die Sprünge helfen.

Schönen Abend noch und LG

Fipsi

Eine Lösung kann ich dir nicht anbieten, dein Code ist sehr verschachtelt und daher von außen schwer zu verstehen was das ablaufen soll.

Meine Idee wäre eine Klasse vom Typ Terminal zu erstellen.
Diese soll eine ID die Lebenszeit, Daten und die Methoden enthalten.

Davon dann soviel Instanzen erzeugen wie du brauchst.

Mein Gedanke ist, das es einfacher wird das ganze zu "handeln"

Dass er sehr verschachtelt ist, weiß ich.. ich hab offen gestanden auch manchmal ein paar Probleme da durchzublicken^^. Des ganze war heut früh noch schlimmer, hab heut schon 3 Stunden in's umschreiben gesteckt.

Mit Klassen kenn ich mich in C Null aus.

Und die Terminals sind auch nicht in dem Programm selber mit dirn. Das sind komplett eigenständige Geräte. Ich wüsste nicht, was der Sinn wäre, die als Klassen in das Programm des steuergeräts einzubetten.

LG

Fipsi

Das mit den Klassen war nur so eine Idee, der helfen könnte den Code etwas zu entwirren.

Das es sich beim den Terminals und ext. Geräte handelt ist mir schon klar.
Aber auch die müssen vom "Server" verwaltet werden.

Wenn du meinst das dir das SRAM ausgeht bzw dies der Grund ist warum deine Anwendung nicht das tut was es soll dann lass die den freien Sram anzeigen:

unsigned int get_free_memory()
{
    unsigned int free_memory;

   if((unsigned int)__brkval == 0)
       free_memory = ((unsigned int)&free_memory) - ((unsigned int)&__bss_end);
   else
      free_memory = ((unsigned int)&free_memory) - ((unsigned int)__brkval);

   return free_memory;

}

Dann hast du schon eine mögliche Fehlerquelle ausgeschlossen, auch memory leaks kannst du damit schön sehen.
Also Anwendung läuft, und der Speicher wird mit der Laufzeit immer kleiner-

Ich wüsste ehrlich gesagt nicht, wie ich die Klassen da anwenden sollte. Bzw. wie schon gesagt, in C hab ich kein Plan von Klassen.

Hab den Code gerade getestet (musste ihn umbauen, Kompilierer hat gejammert^^) und das scheint wohl nicht der Fehler zu sein: Kommt immer 2284 raus. Die ganze zeit. Also der Speicher wird wohl nicht blockiert.

Diesmal war's jetzt sogar schon so, dass er nach dem ersten kompletten Durchlauf aller Scheiben nicht mehr weiter gemacht hat (also nach den 10 Sekunden) und dann sofort as flitzen angefangen hat, als ich "#998,24,1" eingegeben hab.
Das Ding ist mir ein Rätsel..

LG

Fipsi

Hätte noch jemand ne Idee, wo sich der Wurm vergraben hat? Ich bin leider immer noch keinen Schritt weiter gekommen und würde die Software Ende Januar ungern getürkt präsentieren, sondern wirklich funktionsfähig.

Ich bin für jeden Ratschlag dankbar!

LG

Fipsi

P.S.: Ganz schön wenig los um die Zeit hier hust :smiley:

Programm auf das nötigste verkleinern und testen. Die ganze Verschachtlung ist wie bereits erwähnt überhaupt nicht gut lesbar.

Ich benutze folgenden Code (gekürtzt) :

...

Ich schalt das Steuergerät ein, mach nichts, außer zu warten, dass der Check durchläuft.
Tut er auch, nach 10 Sekunden erscheint: "#20,3", 3 Sekunden später "#21,3" usw. bis "#24,3". Dann ist 10 Sekunden Pause und er fängt wieder mit "#20,3" an. Aber dann ist Sense. Es passiert nichts mehr. Tipp ich jetzt am Serial Monitor "#20,1" ein, dann überschlägt sich der Atmega328P-PU und bombt den Serial Monitor mit den Zeilen:
"#20,3
#21,3
#22,3
#23,3
#24,3"
voll und wiederholt das ständig. Ohne die von mir gesetzten Pausen. Nach ungefähr 10 - 15 Sekunden hört er auf und sendet nichts mehr. Und reagiert auch nicht drauf, wenn ich ihm über den Serial Monitor antworte.
Warum?

Lief dieser Test mit dem gekürzten Code oder mit Deiner vollständigen Variante? Falls letzteres der Fall war, solltest Du den kompletten Code posten (notfalls als Anhang), selbst wenn dieser so unübersichtlich ist wie die gekürzte Version.

Hab den Code gerade getestet (musste ihn umbauen, Kompilierer hat gejammert^^) und das scheint wohl nicht der Fehler zu sein: Kommt immer 2284 raus. Die ganze zeit. Also der Speicher wird wohl nicht blockiert.

Du schreibst von einem ATmega328p, dann kann dieser Wert aber nicht korrekt sein, denn der hat nur 2kB RAM. Wenn also mehr frei sein soll als überhaupt eingebaut ist, dann würde ich dieser Ausgabe nicht vertrauen :). Könnte durchaus darauf hindeuten, dass der Speicher bereits übervoll ist.

Der Memory Free Code kommt ursprünglich von dort

Dann teste es mit dem Orginalen Code.

Ich hatte diesen etwas verändert, weil es bei der Ausgabe zu einem Varaiblenüberlauf kam.
Ist Teil meinens Webservers Mega2560 mit Ram Ext.

So, hab das Programm nochmal so gut gekürzt, wie es ging:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <Streaming.h>

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

// Serial Daten
const int MAX_NUMBERS = 25;
int conSerial[MAX_NUMBERS];
int last_serial_check_time = 0;
int wait_serial = 0;
int do_what = 0;

// Ethernetbuffer
int wait_ethernet = 0;

// Turnierkonfigurationsvariablen
int scheiben[61];
int scheibe_von;
int scheibe_bis;
int terminal_status = 0;
int talk_scheibe = 0;
int talk_mode = 0;
int a = 0;

// Navigiervariablen
int in_menue;

// Display neu laden
int display_new;

void setup()
{
  // Serialstart
  pinMode(2, OUTPUT);
  Serial.begin(115200);
  
  // LCDstart
  lcd. begin(20,4);
  for (int i = 0; i < 2; i++)
  {
    lcd.backlight();
    delay(750);
    lcd.noBacklight();
    delay(750);
  }
  lcd.backlight();

  lcd.clear();
  lcd.setCursor(2,1);
  lcd.print("Archery Results");
  lcd.setCursor(2,2);
  lcd.print("Phillip Seelig");
  delay(5000);
  lcd.clear();

  // Navigiervariablen stetzen
  in_menue = 0;
  display_new = 1;
  
  last_serial_check_time = millis();
  scheibe_von = 20;
  scheibe_bis = 24;
}

void loop()
{
  // Abfrage, ob Daten von Terminals warten
  if (readSerial())
  {
    if (conSerial[0] == 000)
    {
      if (((talk_mode == 1) && (conSerial[2] == 2)) || ((talk_mode == 2) && (conSerial[2] == 1)) || ((talk_mode == 3) && (conSerial[2] == 3)))
      {
        if (conSerial[1] == talk_scheibe)
        {
          scheiben[talk_scheibe] = 1;
          if (talk_scheibe < scheibe_bis) {
            talk_scheibe += 1; }
          else {
            talk_scheibe = scheibe_von;
            talk_mode = 0; }
        }
        else
        {
          if ((conSerial[1] >= scheibe_von) && (conSerial[1] <= scheibe_bis)) {
            scheiben[conSerial[1]] = 1; }
        }
        last_serial_check_time = millis();
        wait_serial = 0;
      }
      display_new = 1;
    }
  }
  
  // Wenn Scheibe nach 3 Sek. nicht reagiert nächste
  if (((last_serial_check_time + 3000) <= millis()) && (wait_serial == 1))
  {
    lcd.print(F("Hallo"));
    if (talk_scheibe == 24)
    {
      Serial << talk_scheibe << " " << talk_mode << " " << wait_serial << endl;
      a = 1;
    }
    if (talk_scheibe < scheibe_bis)
    {
      talk_scheibe += 1;
    }
    else
    {
      talk_scheibe = scheibe_von;
      talk_mode = 0;
    }
    wait_serial = 0;
    
    if (a == 1)
    {
      Serial << talk_scheibe << " " << talk_mode << " " << wait_serial << endl;
    }
  }
  
  // Vollständigkeit Scheiben prüfen (Start des Durchlaufs; Aufruf nächster Scheibe)
  if (((last_serial_check_time + (10 * 1000)) <= millis()) && (talk_mode == 0) && (wait_serial == 0))
  {
    talk_mode = 2;
    talk_scheibe = scheibe_von;
  }
  
  if ((talk_mode == 2) && (wait_serial == 0))
  {
    digitalWrite(2,HIGH);
      Serial << "#" << talk_scheibe << F(",3") << endl;
    digitalWrite(2,LOW);
    wait_serial = 1;
    last_serial_check_time = millis();
    //lcd.print(get_free_memory());
  }
  
  // LCDausgaben
  if (display_new == 1)
  {
    switch (in_menue)
    {
      case 0:
        lcd.setCursor(0,0);
        lcd.print(F("- Konfigurationen   "));
        lcd.setCursor(0,1);
        lcd.print(F("- Scheibennummern   "));
        lcd.setCursor(0,2);
        lcd.print(F("- Turnierbetrieb    "));
        lcd.setCursor(0,3);
        lcd.print(F("  Archery Results   "));
        //lcd.setCursor(0,3);
        //lcd.print(in_menue);
        //lcd.print(", ");
        //lcd.print(key);
        lcd.setCursor(0,0);
        lcd.blink();
        display_new = 0;
        break;
    }
  }
}

// Serialempfänger
bool readSerial()
{
  static byte index;
  
  if(Serial.available())
  {
    char c = Serial.read();

    if(c >= '0' && c <= '9' && index < MAX_NUMBERS)
    {
      conSerial[index] = conSerial[index] * 10 + c - '0';
    }
    else if (c == '#')
    {
      conSerial[0] = 0;
      conSerial[1] = 0;
      conSerial[2] = 0;
    }
    else if(c == ',' && index < MAX_NUMBERS)
    {
      index++;
      conSerial[index] = 0;
    }
    else if(c == '\n')
    {
      index = 0;
      return true;
    }
    //lcd.print("hallo");
  }

  return false;
}

Weniger geht nur, wenn ich den Code verändere^^.
Jedenfalls zum Bericht:

Lass ich den Code so durchlaufen, dann bekomm ich wieder die Serialausgaben “#20,3” bis “#24,3”. In dem Code hab ich mir jetzt jedes mal ein “Hallo” am LCD ausgeben lassen, wenn er in die 3 Sekunden rein läuft. Das Ergebnis: Es kommt nur 4x Hallo. Sprich, bei talk_scheibe == 24; läuft er nicht in den if-Teil:

  // Wenn Scheibe nach 3 Sek. nicht reagiert nächste
  if (((last_serial_check_time + 3000) <= millis()) && (wait_serial == 1))
  {
    lcd.print(F("Hallo"));
    if (talk_scheibe == 24)
    {
      Serial << talk_scheibe << " " << talk_mode << " " << wait_serial << endl;
      a = 1;
    }
    if (talk_scheibe < scheibe_bis)
    {
      talk_scheibe += 1;
    }
    else
    {
      talk_scheibe = scheibe_von;
      talk_mode = 0;
    }
    wait_serial = 0;
    
    if (a == 1)
    {
      Serial << talk_scheibe << " " << talk_mode << " " << wait_serial << endl;
    }
  }

Jetzt ist die Frage: Warum? Und auf die hab ich keinen blassen Schimmer.

pylon:

Den Code hab ich gekürzt getestet. Hab alles andere Auskommentiert. Jetzt allerdings hab ich grad alles in ne neue Datei geladen und komplett rausgeschmissen, was ich nicht brauch zum testen.

Diesen Freund hier hab ich. Und ja, 2 kB RAM. Hab gerade nochmal den Code drüber laufen lassen; Ergebnis: 2290 (im Testcode). Wenn ich den dann noch angegeben originalen Code verwende bekomm ich nen Wert von 1317. Klingt irgendwie schon besser^^.

LG

Fipsi

Dann lass dir talk_scheibe mal als Wert ausgeben.

Ich würde behaupten

if (talk_scheibe < scheibe_bis)

ist falsch und müsste <= heißen.

Darüber hab ich auch schon nachgedankt, aber dann müsste doch im Serialmonitor noch “#25,3” erscheinen.
Zudem soll er ja zuletzt erhöhen, wenn er auf 23 ist (in diesem beispiel jetzt), damit er bei talk_scheibe = 24 < scheibe_bis = 24 ist, um dann abzubrechen, weil er ja sonst, wie gesagt, auf 25 hochzählt.

Aber ich werds gern noch mal testen.

LG

Fipsi

Edit:

Wie vermutet: Bringt nichts. Er zählt nicht mal auf 25, was mich wundert (im Serial Monitor). Hab auch gerade mal scheibe_bis auf 22 geändert, ist das gleiche phänomen, nur eben bis 22.

Versuch mal

// Wenn Scheibe nach 3 Sek. nicht reagiert nächste
if (((last_serial_check_time + 3000) <= millis()) && (wait_serial == 1))
	{
	if(++talk_scheibe >= 24)
	{
		Serial << talk_scheibe << " " << talk_mode << " " << wait_serial << endl; // a == 1
		talk_scheibe = scheibe_von;
		talk_mode = 0; // was auch immer das ist    
	}
	
	// hier sollte last_serial_check_time mit millis() abgeglichen werden 
	// und was mit wait_serial machst weiß ich nicht
}

Ich vermute mal, du willst darauf raus, dass ich den if- und else-Teil vertausch?

Hab das jetzt mal so gemacht:

 // Wenn Scheibe nach 3 Sek. nicht reagiert nächste
  if (((last_serial_check_time + 3000) <= millis()) && (wait_serial == 1))
  {
    //lcd.print(F("Hallo"));
    if (talk_scheibe == 24)
    {
      Serial << talk_scheibe << " " << talk_mode << " " << wait_serial << endl;
      a = 1;
    }
    if (++talk_scheibe >= scheibe_bis)
    {
      talk_scheibe = scheibe_von;
      talk_mode = 0;
      
    }
    else
    {
      talk_scheibe += 1;
    }
    wait_serial = 0;
    
    if (a == 1)
    {
      Serial << talk_scheibe << " " << talk_mode << " " << wait_serial << endl;
    }
  }

Ergebnis: Es werden nur alle gerade Zahlen (20, 22, 24) ausgegeben und bei

    if (a == 1)
    {
      Serial << talk_scheibe << " " << talk_mode << " " << wait_serial << endl;
    }

bekomm ich auch die gewünschte Ausgabe.
Trotzdem läuft er dann nicht neu durch >.<

Was talk_mode sein soll:
ich hab verschiedene Befehle, die an die Terminals rausgehen. Damit ich nicht für jeden Befehl extra Variablen und Abfragen usw. schreiben muss, steht in talk_mode der aktuelle Befehl drin.

Und wait_serial:
Wenn ich einen Befehl losgeschickt hab, will ich eine Antwort erhalten, bevor der nächste Befehl geschickt wird. Deswegen wait_serial: Beim senden des Befehls auf 1, bei erhaltener Antwort (oder wenn die länger als 3 Sek. dauert), wird wait_Serial wieder auf 0 zurück gesetzt und ein Befehl kann nur geschickt werden, wenn wait_serial == 0 ist.

LG

Fipsi

Edit:

Ich verstehs einfach nicht… bei der letzten Scheibe läuft er nicht in den 3 Sek-Teil rein… aber warum? Ich verstehs nicht…

Das ist Müll und funktioniert auch nicht so wie du denkst. Schau dir bitte mal an, was ein Präfix-Operator macht. Das gehört wie in PHP auch zu Grundlagen. Dort wird das identisch gehandhabt.

    if (++talk_scheibe >= scheibe_bis)
    {
      talk_scheibe = scheibe_von;
      talk_mode = 0;
      
    }
    else
    {
      talk_scheibe += 1;
    }

Okay, hab schon verstanden, warum Müll :X

Aber dann muss das “=” raus, weil er sonst wieder nur bis scheibe_bis -1 zählt.

Hab das gerade mal getestet, so ändert er dann talk_mode wieder auf 0, talk_scheibe = scheibe_von und wait_serial = 0; aber nicht bei talk_scheibe = scheibe_bis. Da will er einfach nicht in die 3 Sek-Schleife.

LG

Fipsi

Edit:

Ich hab jetzt mittlerweile festgestellt, dass er bei der Bedingung “((last_serial_check_time + 3000) <= millis())” streikt. Ich versteh aber nicht warum, weil last_serial_check_time wird’s nirgends mehr überschrieben (hab ich nachgeprüft).

int last_serial_check_time = 0;

Damit kommst du ca 30 sec weit nach reset.

Du meinst sicher:

static unsigned long last_serial_check_time;
if ((millis() - last_serial_check_time > 3000)  && (wait_serial == 1))
{
  last_serial_check_time = millis();
    // ...
}

Ergebnis: Es werden nur alle gerade Zahlen (20, 22, 24) ausgegeben

Kein wunder bei

if (++talk_scheibe >= scheibe_bis)
    {
      talk_scheibe = scheibe_von;
      talk_mode = 0;
    }
    else
    {
      talk_scheibe += 1;  // hier wird talk_scheibe zum 2. Mal erhöht ;)
    }

Das glaub ich jetzt nicht... jetzt geht's und macht das, was ich will... ich glaubs nicht..

Kann mir jemand sagen, wie lang der jetzt mit macht?^^
So 12 bis 14 Stunden wenn er durchhält, wäre gut.. also 43.200.000 bis 50.400.000 sollten hoffentlich gehn? Oder muss ich mir ein reset oder Art Überfüllsicherung einbauen?

Ja, woran das liegt, hab ich auch schon begriffen^^ :wink:

Vielen Dank für eure Hilfe.. ihr seit echt unglaublich.. vielen, vielen Dank!!

LG

Fipsi

Edit: Okay, unsigned long reicht ja 49 Tage.. da komm ich damit gut aus^^.

Der Präfix Operator (++var) inkrementiert erst und gibt dann das Ergebnis zurück. Der Postfix Operator (var++) gibt erst die Variable zurück und inkrementiert danach. Die sind hier nicht austauschbar.

Gut, dann hab ich's richtig verstanden, vielen Dank :slight_smile:

Und ich habs im oberen Post zwar shcon editiert, aber:

Ja, unsigned long reicht ja 49 Tage, da sind meine 12 - 14 Stunden ja niedlich dagegen..^^

LG

Fipsi