- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 7 von 7

Thema: __ Zeitschleife ohne Programmunterbrechung (Aller NeuAnfang ist schwer)

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.06.2019
    Beiträge
    140

    __ Zeitschleife ohne Programmunterbrechung (Aller NeuAnfang ist schwer)

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo zusammen.

    Nach 3 Jahren Programmierabstinenz beschäftige ich mich wieder der Arduino-Programierung. Mein Neueinstieg ist doch "zäher" als gedacht...

    Folgend möchte ich einen kurzen Summerton (Tasten-Rückmeldung) als Funktion programmieren, ohne das der Programmfluss unterbrochen wird.
    Die Funktion wird vom beliebigen Prg.ort aufgerufen und läuft 500ms.
    Folgender code funktioniert nicht richtig;

    Code:
    void loop() {
      LEDumschalt();
      SummerKurzON();
      delay(1000);                    //Prog.ablauf unterbrochen [ms]
    }
    
    void SummerKurzON() {                             //Tasten-Quitierungston
      digitalWrite(Summer, 1);                          //Summer einschalten
      static unsigned long StartZeit = millis();
     
      __TESTmarker__(millis());                       //Anzeige nach erstem Durchlauf= 2451 // 2.Durchlauf= 3451
      __TESTmarker__(StartZeit);                   //Anzeige nach erstem Durchlauf= 0      // 2.Durchlauf= 2451
      
      if (millis() >= StartZeit + SummerZeitKurz) {  //nach erreichen der Zeit, 500ms, Summer ausschalten
        digitalWrite(Summer, 0);
        StartZeit = millis();
        __TESTmarker__(StartZeit);               //Anzeige nach erstem Durchlauf= 2451  //2.Durchlauf= 3451
      }
    }
    + Warum speichert die Var. StartZeit die falsche Zeit "0"?
    + Läuft millis() ab Programmstart oder erstem Funktionsaufruf?
    + Hat das mit dem static-Befehl zu tun?
    + Was mache ich hier grundlegend falsch?
    Geändert von frabe (15.05.2024 um 09:21 Uhr)
    __________________________________________________ _
    | Sprache: C | Teensy 3.2 | Arduino 2.x | Status: EwigerAnfaenger |

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.07.2004
    Beiträge
    585
    Hi,

    ohne das Programm jetzt testen zu können:
    Du setzte Startzeit bei jedem Aufruf der Funktion SummerKurzOn neu.
    Dann kommen die Testmarker Aufrufe von denen ich nicht weiß was sie machen und wie lange die Ausführung dauert.
    Wenn sie aber kombiniert nicht über 500ms dauern wird eine if Bedingung nie true werden. Ich vermute der Summer ist dauerhaft an?
    Dann wird dein delay in loop ausgeführt.

    Wenn du in der Funktion keinen delay verwenden willst jedoch alle 500ms den Summer ein/aus schalten möchtest solltest Du den delay in der Loop überdenken. Dieser dauert ja schon eine Sekunde, somit bleibt dein Summer immer diese Zeit an, wenn er nicht vor Erreichen des delay abgeschaltet wurde, was er nicht wird da ja kein delay verwendet werden soll usw usf.

    Ich nehme an, deine Funktion LEDumschalt soll mit der alle eine Sekunde aufgerufen werden?
    ich bin mir nicht ganz sicher was DU erreichen willst.
    Ich versuche mal etwas zu schreiben ohne es zu testen, und es ist eher Pseudocode, habe auch lange keinen Arduino mehr programmiert:
    Code:
    
    unsigned long startzeit_led = 0;
    unsigned long startzeit_summer = 0;
    unsinged long dauer_led = 1000;
    unsigned long dauer_summer = 500;
    bool summer_an = false;
    
    loop(){
    
    if (startzeit_led + dauer_led<= millis()){
    LEDumschalt();
    startzeit_led = millis();
    }
    
    if (startzeit_summer + dauer_summer <= millis()){
    if (summer_an)
    summer_aus();
    else summer_an();
    startzeit_summer = millis();
    }
    
    }
    gegebenenfalls musst Du die Bedingungen erweitern, jenachdem was beim ersten Durchlauf mit startzeit = 0 passieren soll, sonst startet der Summer vor den LEDs.
    Die variable summer_an muss entsprechend in den Funktionen die den Summer an/aus machen gesetzt werden.

    Ich hab nochmal kurz gegoogled: diese Seite erläutert es gut.
    https://starthardware.org/timer-mit-...ive-zu-delays/

    Crypi

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.06.2019
    Beiträge
    140
    Hi Crypi .
    Vieln Dank für deine Mühe

    Mein oben genannter Code ist ledigtlich eine Testumgebung, um wieder in die Programmier-Feeling zu kommen.
    Tatsächlich klappt das mit den LED-Umschaltung, der Summer springt dann für ~1ms an.

    Die TestMarker dienen ledigtlich der Visualisierung am Monitor wie die Variablen gerade aus sehen.

    Hierbei sollen alle 1Sek 2 LEDs togglen. Bei jeder Umschaltung soll ein Ton (SummerKurzON()) erfolgen.
    Später wird diese Unschaltroutine jedesmal bei Tasteneingabe erfolgen - also ohne 1Sek-Interval.
    Alles ohne den loop()-Verlauf zu unterbrechen - auch nicht durch ein delay() in einer Funktion.

    2 grundlegende Sachen ich nicht verstanden;
    + Was passiert mit einer static-Variable in einer Funktion, wenn er diese Funktion verlässt?
    + Wann genau wird millis() gestartet? Erst wenn millis() das erst mal in irgend einer Funktion abgefragt wird - Bsp: StartZeit=millis()?

    Und in meinem Bsp-Code;
    + Warum ist beim aller ersten Aufruf folgender Funktion
    Code:
    void SummerKurzON() {
      static unsigned long StartZeit = millis();
     
      __TESTmarker__(millis()); 
      __TESTmarker__(StartZeit);
    StartZeit-Inhalt nicht 100% gleich wie millis() ?
    millis() wird hier auch das erste mal verwendet.
    __________________________________________________ _
    | Sprache: C | Teensy 3.2 | Arduino 2.x | Status: EwigerAnfaenger |

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.07.2004
    Beiträge
    585
    Hi,

    https://www.arduino.cc/reference/en/...ifiers/static/
    sie ist nur in der Funktion sichtbar bleibt aber über mehrere Funktionsaufrufe erhalten.

    https://www.arduino.cc/reference/de/...s/time/millis/
    seit Beginn des Sketches, hier ist auch ein Beispielprogramm das du ja mal ausprobieren kannst genannt.
    Millis() läuft direkt ab Start, StartZeit wird später im Programm gesetzt, daher die Abweichung.

    Crypi

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.06.2019
    Beiträge
    140
    DANKE für deine Klarheit Crypi

    Millis() läuft direkt ab Prg.Start, "StartZeit" wird später im Programm gesetzt, daher die Abweichung.
    Das millis() direkt ab Prg.Start läuft, habe ich verstanden!
    Warum aber "StartZeit" eine "0" ausgibt obwohl 1 Zeile darüber "StartZeit" die akt. millis() einliest (=2451ms) ist mir immer noch schleierhaft.

    - - - Aktualisiert - - -

    Ich habe "static" einmal gelöscht, seitdem ist millis() und "StartZeit" gleich.
    Sieht so aus, als wenn die static-Variable bei Programmstart die millis() einliest...
    __________________________________________________ _
    | Sprache: C | Teensy 3.2 | Arduino 2.x | Status: EwigerAnfaenger |

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Rabenauge
    Registriert seit
    13.10.2007
    Ort
    Osterzgebirge
    Alter
    55
    Beiträge
    2.207
    Wenn du zeitgesteuerte Abläufe haben willst, ohne den Controller durch delay()'s zu blockieren, schau dir einfach mal das mitgelieferte Beispiel "BlinkWithoutDelay" ganz genau an.
    Wenn man das ein bisschen umstrickt, kann man damit prima Timer bauen, die ohne jegliches delay() funktionieren.
    Ich packe da regelmässig nen Sekundentick (oder auch kürzer, je nach Intervall, dass ich benötige) rein, den ich dann für alles Mögliche benutzen kann. Damit kann man problemlos auch mehrere unterschiedliche Zeitintervalle realisieren.
    Da der Aufruf der Timer-Funktion nur einige Mikrosekunden dauert, merkt man den im normalen Programmablauf gar nicht.
    Grüssle, Sly
    ..dem Inschenör ist nix zu schwör..

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Ich würde auch das Konzept von Rabenauge anwenden.
    Ich lass da immer im Timer Interrupt einen oder mehrere Variablen herunterzählen.
    Wenn dann eine auf 0 ist wird ein Flag gesetzt das dann in der Hauptschleife abgefragt wird.
    Im Hauptprogramm wird dann die Aktion ausgelöst und bei Bedarf das Flag wieder gelöscht und, für erneutes Ausführen, die Variable wieder neu gesetzt.
    Dadurch wird das Hauptprogamm nur für die Timer Interupts unterbrochen und man kann in die Interrupt Routine mehrere Zeitintervalle einbauen.
    Bei 100ms Timer Intervall ein Counter mit 10 ergibt eine Sekunde bei 100 wären es 10 Sekunden.

Ähnliche Themen

  1. Aller Anfang ist schwer :-)
    Von rauf81 im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 24.11.2011, 07:10
  2. Aller Anfang ist schwer
    Von Jägermeister im Forum Suche bestimmtes Bauteil bzw. Empfehlung
    Antworten: 3
    Letzter Beitrag: 29.08.2009, 23:28
  3. Aller Anfang ist schwer
    Von priescen im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 27.08.2007, 18:52
  4. Aller anfang ist schwer...
    Von Gregor1984 im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 02.09.2006, 13:50
  5. Aller Anfang ist schwer
    Von BIG Muzzy im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 17
    Letzter Beitrag: 04.05.2005, 08:33

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen