-         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: Pause mit millis wenn geschaltet wird.

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    27.02.2012
    Ort
    50KM über Hamburg
    Beiträge
    94

    Pause mit millis wenn geschaltet wird.

    Anzeige

    Hallo,
    ich weiß, es gibt etliche Anweisungen.
    Aber alle sind mit "Blink".
    Das verstehe ich so.
    Die 1. Zeit ist Null. Dann wird gewartet bis z.B. 1000Millis verstrichen sind. Dann schaltet die Led ein, bis wieder 1000 Millis um sind. Wieder 1000 Millis warten usw.

    Wenn jetzt aber mitten im Sketch millis abgewartet werden sollen, habe ich ja kein Blink vorher, von dem aus losgezählt werden könnte. Keine ständige Schleife.

    Sondern ein Ereignis, welches zum Beispiel eine Tätigkeit, für eine feste Zeit nach sich ziehen soll. Diese war dann auch nicht klar am Beginn der Inbetriebnahme zeitlich zu bestimmen, sondern der Statpunkt obliegt dem Zufall.

    Ich versuche schon länger(und länger und länger) in dem Beispiel Sketch "Button" millis einzufügen.
    Aber ich blicke das einfach nicht.
    Es wäre schön, wenn mir das da reingeschrieben würde. Vielleicht kapiere ich das dann endlich mal.

    Wenn der Schalter gedrückt wird. Eine Pause statt delay.

    Code:
    /*
      Button
    
    
     */
    
    // constants won't change. They're used here to
    // set pin numbers:
    const int buttonPin = 6;     // the number of the pushbutton pin
    const int ledPin =  13;      // the number of the LED pin
    unsigned long previousMillis = 0;
    #define        laufzeit   1000UL
    
    // variables will change:
    int buttonState = 0;         // variable for reading the pushbutton status
    
    void setup() {
      // initialize the LED pin as an output:
      pinMode(ledPin, OUTPUT);
      // initialize the pushbutton pin as an input:
      pinMode(buttonPin, INPUT);
    }
    
    void loop() {
    unsigned long currentMillis = millis();
      
      // read the state of the pushbutton value:
      buttonState = digitalRead(buttonPin);
    
      // check if the pushbutton is pressed.
      // if it is, the buttonState is HIGH:
      if (buttonState == HIGH)
     
      {
        // turn LED on:
        
        digitalWrite(ledPin, HIGH);
    
        
    
         delay(500);
    
         
         
      }
      else
      {
        // turn LED off:
        digitalWrite(ledPin, LOW);
      }
    }
    Dankeschön
    Achim

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    3.039
    Zitat Zitat von achso Beitrag anzeigen
    Hallo,
    ich weiß, es gibt etliche Anweisungen.
    Aber alle sind mit "Blink".
    Das verstehe ich so.
    Die 1. Zeit ist Null. Dann wird gewartet bis z.B. 1000Millis verstrichen sind. Dann schaltet die Led ein, bis wieder 1000 Millis um sind. Wieder 1000 Millis warten usw.

    Wenn jetzt aber mitten im Sketch millis abgewartet werden sollen, habe ich ja kein Blink vorher, von dem aus losgezählt werden könnte. Keine ständige Schleife.

    Sondern ein Ereignis, welches zum Beispiel eine Tätigkeit, für eine feste Zeit nach sich ziehen soll. Diese war dann auch nicht klar am Beginn der Inbetriebnahme zeitlich zu bestimmen, sondern der Statpunkt obliegt dem Zufall.

    Ich versuche schon länger(und länger und länger) in dem Beispiel Sketch "Button" millis einzufügen.
    Aber ich blicke das einfach nicht.
    Es wäre schön, wenn mir das da reingeschrieben würde. Vielleicht kapiere ich das dann endlich mal.

    Wenn der Schalter gedrückt wird. Eine Pause statt delay.

    Code:
    /*
      Button
    
    
     */
    
    // constants won't change. They're used here to
    // set pin numbers:
    const int buttonPin = 6;     // the number of the pushbutton pin
    const int ledPin =  13;      // the number of the LED pin
    unsigned long previousMillis = 0;
    #define        laufzeit   1000UL
    
    // variables will change:
    int buttonState = 0;         // variable for reading the pushbutton status
    
    void setup() {
      // initialize the LED pin as an output:
      pinMode(ledPin, OUTPUT);
      // initialize the pushbutton pin as an input:
      pinMode(buttonPin, INPUT);
    }
    
    void loop() {
    unsigned long currentMillis = millis();
      
      // read the state of the pushbutton value:
      buttonState = digitalRead(buttonPin);
    
      // check if the pushbutton is pressed.
      // if it is, the buttonState is HIGH:
      if (buttonState == HIGH)
     
      {
        // turn LED on:
        
        digitalWrite(ledPin, HIGH);
    
        
    
         delay(500);
    
         
         
      }
      else
      {
        // turn LED off:
        digitalWrite(ledPin, LOW);
      }
    }
    Dankeschön
    Achim

    dann probieren wirs doch mal, aus dem Stand aus dem Blauen ins Blaue hinein...


    Code:
    // variables will change:
    int buttonState = 0;         // variable for reading the pushbutton status
    
    void setup() {
      // initialize the LED pin as an output:
      pinMode(ledPin, OUTPUT);
      // initialize the pushbutton pin as an input:
      pinMode(buttonPin, INPUT);
    }
    
    void loop() {
    unsigned long currentMillis ; // brauchen hier noch nicht initialisiert werden
      
      // read the state of the pushbutton value:
      buttonState = digitalRead(buttonPin);
    
      // check if the pushbutton is pressed.
      // if it is, the buttonState is HIGH:
      if (buttonState == HIGH)
     
      {
        currentMillis = millis();
        while(millis()-currentMillis <1000); // 1000ms warten
        // turn LED on:    
        digitalWrite(ledPin, HIGH);           // dann die LED an-schalten
        currentMillis = millis();
        while(millis()-currentMillis <1000);  // wieder 1000ms warten
        digitalWrite(ledPin, LOW);            // dann die LED aus-schalten
    
         delay(500);
        //... was der Rest bedeuten oder machen soll, verstehe ich jetzt noch nicht, insb. auch mit dem delay hier...
    }
    millis() liefert die aktuelle Zeit, und currentMillis nimmt eine Stopuhr-Zeit, die dann konstant bleibt, während bei jedem Aufruf von millis() dieses wieder weitergezählt hat.
    nach 1000ms ist also millis() um 1000 höher als currentMillis , d.h.: dann sind 1000ms um.

    wie gesagt,
    was der Rest bedeuten oder machen soll, verstehe ich jetzt noch nicht, insb. auch mit dem delay.
    Aber vlt hilf ja schon mal dieser Teil mit dem 1000ms warten per millis()...
    Geändert von HaWe (27.06.2017 um 00:21 Uhr)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von i_make_it
    Registriert seit
    29.07.2008
    Ort
    Raum DA
    Alter
    50
    Beiträge
    2.816
    Es fällt mir etwas schwer zu verstehen auf was genau Du raus willst.

    Zitat Zitat von achso Beitrag anzeigen
    Pause mit millis wenn geschaltet wird.
    Der Befehl zum Pausieren/Anhalten eines arduino Programms ist schon delay.

    Zitat Zitat von achso Beitrag anzeigen
    Hallo,
    ich weiß, es gibt etliche Anweisungen.
    Aber alle sind mit "Blink".
    Falls Du mit anweisung C++ befehle meinst, "Blink" ist nicht Teil der Arduino C++ Sprache.
    "Blink" ist ein Code Beispiel so wie am PC oft "Hello world".

    Wie Hawe schon geschrieben hat, fragt millis nur einen Timer ab, genauer den freilaufenden Timer der seit dem Einschalten des µC läuft.
    Bei jedem Aufruf erhält man also die "Uptime" des µC in ms.
    Ein übliches vorgehen ist, eine variable mit dem wert von milis zu befüllen, dann zu verhindern, das die Variable ständig überschrieben wird und vom Millis aufruf den Wert der Variabel abzuziehen. Das Ergebniss ist eine bei jedem Programmdurchlauf größer werdende Zahl.
    Diese kann man mit einem dritten Wert vergleiche und z.B. etwas machen lassen solange der Wert der Variablen kleiner dem Grenzwert ist oder oder etwas machen lassen sobald der Grenzwert überschritten wird.
    Etwas machen zu lassen wenn beider Werte genau gleich sind, geht nur mal zufällig gut, Da die Laufzeit des Programms ja je nach Verzweigung sich ändern kann und deshalb nicht sichergestellt ist das man in der Programmzeiler der millis Abfrage genau dann ankommt wenn exakt die entsprechende Zeit verstrichen ist.
    Soll es also ganz Genau gleich sein, dann nimmt man Timer-Interrupts.

    In dem untenstehenden Beispiel nutze ich millis auf einem nano um zwei Ultraschallsensoren gleichzeitig (50% zeitversetzt) zu betreiben und gleichzeitig noch drei Reflexlichtschranken auswerten zu können.
    (Da die US Echos zetilich nicht vorhersehbar sind, werden dafür dann noch Interrupteingänge und ISRs genutzt)

    Code:
    const int us1_echo = 2;
    const int us2_echo = 3;
    const int us1_trig = 4;
    const int us2_trig = 5;
    const int lf_le = 8;
    const int lf_ce = 9;
    const int lf_ri = 10;
    int lf_le_state = LOW;
    int lf_ce_state = LOW;
    int lf_ri_state = LOW;
    unsigned long us1_echo_st;
    unsigned long us2_echo_st;
    unsigned long us1_echo_et;
    unsigned long us2_echo_et;
    unsigned long us1_srt;
    unsigned long us2_srt;
    unsigned long us1_dist;
    unsigned long us2_dist;
    unsigned long prev1micros = 0;
    const long toggleinterval = 1000;
    int togglestate = LOW;
    int us1_flag = 0;
    int us2_flag = 0;
    char* string_[]={"Linefollow:", "US-Echo1:", "US-Echo2:", "Cycletime:"};
    unsigned long prev2micros = 0;
    
    void setup() {
      Serial.begin(9600);
      pinMode(us1_echo, INPUT);
      pinMode(us2_echo, INPUT);
      pinMode(us1_trig, OUTPUT);
      pinMode(us2_trig, OUTPUT);
      pinMode(lf_le, INPUT);
      pinMode(lf_ce, INPUT);
      pinMode(lf_ri, INPUT);
      attachInterrupt(0, US1_ISR, CHANGE);
      attachInterrupt(1, US2_ISR, CHANGE);
    }
    
    void loop() {
      lf_le_state = digitalRead(lf_le);
      lf_ce_state = digitalRead(lf_ce);
      lf_ri_state = digitalRead(lf_ri);
      unsigned long cur1micros = millis();
      if (cur1micros - prev1micros >= toggleinterval) { //alle 10ms umschalten
        prev1micros = cur1micros;
        if (togglestate == LOW){
          togglestate = HIGH;
          digitalWrite(us1_trig, HIGH);
          digitalWrite(us2_trig, LOW);
          us1_echo_st = 0;
          us1_flag = 0;
        }else{
          togglestate = LOW;
          digitalWrite(us1_trig, LOW);
          digitalWrite(us2_trig, HIGH);
          us2_echo_st = 0;
          us2_flag = 0;    
        }
      }
       us1_dist = (us1_srt / 58); // Umrechnung des Sensorwerts, ungefähr in  cm (für 343m/s bei trockner Luft und 20° wäre 58,3 der genaue Wert)
      us2_dist = (us2_srt / 58);
      Serial.print(string_[1]);
      Serial.println(us1_dist);
      Serial.print(string_[2]);
      Serial.println(us2_dist);
      Serial.print(string_[0]);
      Serial.print(lf_le_state);
      Serial.print(lf_ce_state);
      Serial.println(lf_ri_state);
      unsigned long cur2micros = micros();
      Serial.print(string_[3]);
      Serial.println(cur2micros - prev2micros);
      prev2micros = cur2micros;
    }
    
    void US1_ISR(){
      if (us1_echo_st == 0) {
        us1_echo_st = micros();
      } else {
        us1_echo_et = micros();
        ++us1_flag;
      }
      if (us1_flag == 1) {
        us1_srt = (us1_echo_et - us1_echo_st);
      }
    }
    
    void US2_ISR(){
      if (us2_echo_st == 0) {
        us2_echo_st = micros();
      } else {
        us2_echo_et = micros();
        ++us2_flag;
      }
      if (us2_flag == 1) {
        us2_srt = (us2_echo_et - us2_echo_st);
      }
    }

    Für Dich von Interesse dürfte davon vermutlich das untenstehende sein:
    Code:
    unsigned long prev1micros = 0;
    const long toggleinterval = 1000;
    int togglestate = LOW;
    
    void setup() {
    }
    
    void loop() {
    <<<<< hier passiert was das nichts mit der Zeit zu tun hat
      unsigned long cur1micros = millis();
      if (cur1micros - prev1micros >= toggleinterval) { //alle 10ms umschalten
        prev1micros = cur1micros;
        if (togglestate == LOW){
          togglestate = HIGH;
    <<<<< hier passiert was das Abhängig von der Zeit ist
        }else{
          togglestate = LOW;
    <<<<< hier passiert was das Abhängig von der Zeit ist
        }
      }
    <<<<< hier passiert was das nichts mit der Zeit zu tun hat
    }
    hier schalte ich alle 1000ms (oder mehr) zwichen zwei Zuständen um.

    Was noch zu berücksichtigen ist, ist das millis natürlich irgendwann überläuft und dann einmal der aktuelle Wert kleiner sein kann als der in der Variablen gespeicherte.
    Diesen Fehlerfall sollte man noch abfangen, denn sonst funktioniert das Programm sollange bis millis das erste mal den Maximalwert erreicht und danach nicht mehr, da millis ja nie mehr um den Grenzwert größer werden kann als der gespeicherte Wert.
    Also:
    Code:
    if (cur1micros > prev1micros) prev1micros = 0;
    müsste noch zum Code dazu.
    Geändert von i_make_it (27.06.2017 um 10:02 Uhr)

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    617
    Zitat Zitat von i_make_it Beitrag anzeigen
    Was noch zu berücksichtigen ist, ist das millis natürlich irgendwann überläuft und dann einmal der aktuelle Wert kleiner sein kann als der in der Variablen gespeicherte.
    Diesen Fehlerfall sollte man noch abfangen, denn sonst funktioniert das Programm sollange bis millis das erste mal den Maximalwert erreicht und danach nicht mehr, da millis ja nie mehr um den Grenzwert größer werden kann als der gespeicherte Wert.
    Also:
    Code:
    if (cur1micros > prev1micros) prev1micros = 0;
    müsste noch zum Code dazu.
    Wenn man nur mit Zeitdifferenzen rechnet, braucht man das nicht.

    Das
    Code:
    if (cur1micros - prev1micros >= toggleinterval) { //alle 10ms umschalten
    rechnet auch bei einem Überlauf richtig.

    Ich klau einfach mal hier die Zahlen, da hat es schon einer vorgerechnet
    http://forum.arduino.cc/index.php/topic,85706.0.html
    4294967290 - 4294967280 = 10
    4294967291 - 4294967280 = 11
    4294967292 - 4294967280 = 12
    4294967293 - 4294967280 = 13
    4294967294 - 4294967280 = 14
    4294967295 - 4294967280 = 15 (jetzt kommt der Überlauf)
    0 - 4294967280 = 16
    1 - 4294967280 = 17
    2 - 4294967280 = 18
    3 - 4294967280 = 19

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von i_make_it
    Registriert seit
    29.07.2008
    Ort
    Raum DA
    Alter
    50
    Beiträge
    2.816
    Ups, ja stimmt.

    Ich hab das halt standardmäßig zur Absicherung drin, hatte beim Posten nicht dran gedacht das ich ja auch selbst unsigned genommen habe.

    Sagen wir mal so, schaden tut es nicht. nur bei unsigned braucht man es halt auch nicht.

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    27.02.2012
    Ort
    50KM über Hamburg
    Beiträge
    94
    Danke HaWe!
    jetzt habe ich das endlich soweit kapiert, das ich das delay ersetzen kann.

    Habe ich auch gleich umgesetzt und bin begeistert.

    Das delay habe ich nur an die Stelle gesetzt, an der ich gerne die millis Pause hätte. Tut mir Leid, verwirrend zu schreiben.

    Danke i_make_ it,

    Deine Ausführungen habe ich auch schon oft gelesen und dabei viel gelernt. Dich werde ich nie mehr einholen.
    Verspreche aber, deinen Text mehrfach zu lesen.

    Das 2 gleiche Zeiten nicht möglich sind, wenn zusätzliche Funktionen den Loop Durchlauf verzögern, leuchtet mir ein.

    if (cur1micros - prev1micros >= toggleinterval) { //alle 10ms umschalten
    Warum Mikrosekunden, nicht Milli?
    Wo kommen die 10 ms her?

    Bei mir ist das alles viel einfacher. Ich baue nur aus Quatsch und ohne ernsten Sinn einen kleinen Solarroboter, der auf der Terasse rumfährt und bei einem Hindernis oder Verschattung, ein Rad kurz Rückwärts laufen lassen soll. (Zum Ausweichen) Und diese Rückwärtszeit mache ich mit millis(Danke das kann ich ja dank Euch jetzt).

    Ich wollte endlich mal hinkriegen, Pausen ohne delay zu machen.

    Dankeschön.
    Achim

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    617
    Zitat Zitat von achso Beitrag anzeigen
    Warum Mikrosekunden, nicht Milli?
    Wo kommen die 10 ms her?
    Wie heißt es doch so schön ?
    Only the code tells the truth.
    Code:
    unsigned long cur1micros = millis();
    Auch wenn die Variable micros heißt, können millis drin sein.

    Code:
    const long toggleinterval = 1000;
    Auch wenn der Kommentar sagt es wären 10, können es 1000 sein.

    Hat aber mit der Grundproblematik nichts zu tun. Sowas passiert beim Programmieren, deshalb habe ich gar nichts gesagt.

    micros() statt millis() gibt es bei Arduino aber auch, machen insbesondere bei den schnellen 32 Bittern manchmal Sinn.

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    27.02.2012
    Ort
    50KM über Hamburg
    Beiträge
    94
    cur1micros
    Ist dieses dann nur der Name?
    Es könnte auch anders heißen?

    Sonst verstehe ich das nicht. Ist es eine Abkürzung für:
    "current eine Mikrosekunde" nur so zum Spaß geschrieben?

    Das Arduino Kochbuch habe ich schon rauf und runter. Es sind immer mindestens 2 Funktionen in einem Sketch. Das macht mich ganz verrückt.
    Der Unterschied zwischen Millis und Micros ist da schon beschrieben.
    Ich muß mich da noch mehr mit beschäftigen. Aber jetzt ist doch Sommer und das war jetzt nur :"Seid Tagen regnet es deshalb muß ich irgendeinen Quatsch machen"
    Nun scheint wieder die Sonne und weder ist der Quatsch fertig noch habe ich so viel Kraft mich dem draussen Sein zu entziehen.
    Aber dass mit den millis habe ich jetzt glaube ich drauf.

    Fetten Dank
    Achim

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    3.039
    Zitat Zitat von achso Beitrag anzeigen
    cur1micros
    Ist dieses dann nur der Name?
    Es könnte auch anders heißen?

    Sonst verstehe ich das nicht. Ist es eine Abkürzung für:
    "current eine Mikrosekunde" nur so zum Spaß geschrieben?

    Achim
    kurze Antwort: Ja, es ist nur ein beliebiger Name, es könnte auch (fast) beliebig anders heißen.

    lange Antwort:
    C hat nur rund 20 "reservierte Wörter", alles andere sind frei gewählte Bezeichner-Namen.
    Die frei gewählten Namen können natürlich mehr oder weniger gut gewählt sein, und manche können auch etwas verwirren...
    Wenn allerdings einmal ein Name verwendet und deklariert oder definiert wurde (z.B. in bestimmten eingebundenen (#include) Libraries), dann ist dieser Name ab diesem Moment ebenfalls "reserviert". (ok, ja, in C++ kann man ihn auch "überladen"). Bei Arduinisch gibt es sehr viele davon, und man erkennt sie nicht auf den ersten Blick, weil viele Libs, in denen sie stehen, quasi durch die IDE versteckt sind.
    loop() ist so ein Ding, und setup(), und Serial().
    cur1micros gehört nicht dazu.
    Du erkennst es, wo und wie er im Code definiert wird:
    Schema:
    Code:
        Datentyp    Bezeichner-Name  Initialisierung
    unsigned long   cur1micros          = millis();
    also ist der Name cur1micros frei gewählt, er könnte genausogut Alf, FordPrefect, Lichtjahre oder Mondfinsternis heißen: alles mehr - oder auch weniger - sinnvoll.
    Geändert von HaWe (27.06.2017 um 21:37 Uhr)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    27.02.2012
    Ort
    50KM über Hamburg
    Beiträge
    94
    Hallo HaWe,
    danke für deine ausführliche Antwort.

    Das begreif ja selbst ich!!

    In Zukunft achte ich da drauf.

    Mit C++ habe ich noch nichts gemacht, obwohl mir hier schon einige dazu rieten.

    Ich tüdel so`n bisschen mit Tiny und Pro Mini rum und gestehe ein, dass ich sehr sehr schlecht lernen kann.
    Das war zwar nicht immer so, aber nun freue ich mich umso mehr, wenn mir etwas so toll erklärt wird!!!

    Dankeschön bis zu meinem nächsten > ? <.

    Achim

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Lovotics: Wenn der Roboter eifersüchtig wird
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 30.06.2011, 16:50
  2. Spannungsregler wird heiß, wenn ISP angesteckt wird
    Von loukumas im Forum AVR Hardwarethemen
    Antworten: 5
    Letzter Beitrag: 11.02.2008, 16:53
  3. Was Passiert wenn die Last zu groß wird.
    Von Süße Hexe im Forum Motoren
    Antworten: 7
    Letzter Beitrag: 13.09.2007, 21:20
  4. Led leuchtet, wenn Strom entnommen wird
    Von Christoph2 im Forum Elektronik
    Antworten: 19
    Letzter Beitrag: 23.09.2006, 19:38
  5. Simulator wird langsam wenn beim ATtiny2313 PB0=1 ist
    Von felack im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 10.10.2005, 14:52

Berechtigungen

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