Hallo liebe Mikrocontroller Gemeinde, ich habe mir einen Arduino gekauft und einiges darüber gelesen und auch ausprobiert. Ich möchte gerne ein Blinklicht bauen mit einem Taster, das wenn ich diesen Drücke das Bliniklicht im 750ms Takt leuchtet und wenn ich nochmnal drücke es ausgeht. Ganz klassisch hatte ich ein Blinklicht mit "delay(375)" programmiert. Dazu habe ich jetzt gelesen, dass delay im Falle eines Tasters nicht optimal ist, da in dem Fall wenn das Loop gerade im Delay ist der Taster nicht registriert wird. Daher habe ich mittels "Mills" die Blinklichter umprogrammiert, mit dem weiteren Vorteil dass ich nur eine Parameter habe wo ich die Zeit ändern muss und nicht bei jedem Delay bzw. Ausgang. Wirklich verstanden habe ich den Code für Mills aber nicht. Das fängt schon bei "unsigned long previousMillis an, ich verstehe einfach nicht was dieser Befehl an dieser Stelle macht. Im Prinzip hab ich das ganze mit CurrentMills und previoius Mills und den Abgleich unten nicht verstanden. Aber ist auch nicht ganz so wichtig. Wichtig wäre mir wie ich jetzt den Schalter darin bekomme. Ich hatte mal was drin mit einem Schalter, da reagierte das System dann aber so, dass wenn ich den Schalter gedrückt hielt alles blinkte wie es sollte, sobaldich loßließ das das Loop aber in dem gerade Zustand verblieben ist, also entweder aus blieb oder an blieb. Das liegt sicher auch an meinem Millis Konstrukt. Ich möchte nämlich als "Fernziel" ein LED Leiste bauen wo man per Taster die Modi wechseln kann, sprich, vom ausgeschaltete Zustand --> Drücken --> An --> Drücken --> blinken--> Drücken --> Lauflicht --> Drücken --> Pulsieren--> Drücken-- aus Hier mal mein Code. Ich wäre sehr dankbar wenn mir jemand ein klein wenig auf die Sprünge helfen könnte. const int led1 = 2; const int led2 = 3; const int led3 = 4; const int Piep = 5; int ledState = LOW; unsigned long previousMillis = 0; const long interval = 375; void setup() { pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); } void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWrite(led1, ledState); digitalWrite(led2, ledState); digitalWrite(led3, ledState); digitalWrite(Piep, ledState); } }
Alexander H. schrieb: > Das fängt schon bei "unsigned long previousMillis an, ich verstehe > einfach nicht was dieser Befehl an dieser Stelle macht. Im Prinzip hab > ich das ganze mit CurrentMills und previoius Mills und den Abgleich > unten nicht verstanden. Das ist ja auch kein Befehl, sondern eine Variable. Hast du schon mal Eier gekocht? Du setzt irgendwann die Eier auf: previousUhrzeit Du guckst laufend auf die Uhr: currentUhrzeit Wann sind die Eier fertig? Wenn currentUhrzeit - previousUhrzeit = 5min. Genauso macht der Controller das auch. Nur eben mit Millisekunden. Zum Taster: Ein Taster prellt. Guck dir den Artikel an, da steht alles Wissenswerte drin: https://www.mikrocontroller.net/articles/Entprellung Wenn du das durch hast, suchst mal nach Arduino und Entprellung bzw. englisch nach Debounce. Da wirst du bestimmt was finden. Die Arduino-Gemeinde benutzt ja schliesslich auch Taster.
Vielen Dank Thomas für deine Hilfe nun bin ich etwas weiter gekommen. Um das vielleicht etwas zusammenzufassen ob ich das richtig verstanden habe. Ich fing an mit "unsigned long previousMillis = 0;" das heißt dann fange beim 0 Uhr an im Prinzip. Warum da jetzut unsigned steht und was long bedeutet zumal bei manchen "Anleitungen" mit unsigned gearbeitet wird und bei manchen nicht. Dann kommt mit "long" das Interval. dann kommt unsigned long currentMillis = millis(); also die aktuelle Zeit wird dann nur noch Zeit? Prüfe ob der jetzige Augenblick größer ist als das Intervall, wenn ja dann wenn die Lampe an ist auschalten wenn nein dann aus lassen bzw, an lassen. und dann wieder previousMillis = currentMillis; Alte Zeit wird neue? Das Schalter "bouncen" habe ich schon mal gehört, aber ich wage mich da noch nicht ran wenn ich noch nicht einmal millis richtig verstanden habe. Tut mir Leid, dass ist sicher gar nicht so schwer nur werde ich mit den Abstrakten Erklärungen nicht schlau. Das mit den Eiern das war schon sehr anschaulich und praxisnah. Besten Dank schonmal.
Alexander H. schrieb: > if (ledState == LOW) > { > ledState = HIGH; > } else > { > ledState = LOW; > } Anstatt if-else kann man auch den Istzustand der LED lesen und invertiert (umgedreht) wieder ausgeben: digitalWrite (LED1, !digitalRead(LED1)); -------- Für den Taster würde ich eine weitere Variable erzeugen, z.B. LED_ein = 0 Taster abfragen, wenn Taster gedrückt, dann LED_ein = !LED_ein - also die Variable umdrehen. Um Deine Blinkschleife legst Du ein If herum: If LED_ein==0 dann return (direkt raus) else Blinken ausführen. Jetzt bleibt noch zu klären, in welchem Zustand die LEDs verbleiben, wenn umgeschaltet wird - sie sind zufällig entweder an oder aus. Ich spreche das nicht so fließend, dass ich Dir hier frei aus dem Kopf spielfähigen Code schreiben kann, von daher nur die prinzipielle Erläuterung, wie ich es angehen würde. Real auf dem Tisch habe ich schon komplexere Dinge gelöst.
Alexander H. schrieb: > Warum da jetzt unsigned steht und was long bedeutet Variablentypen wurden erfunden, um den Bastler zu ärgern! Nimm einfach mal das "long" und "unsigned" raus und wundere Dich, dass Deine LEDs nach 32 Sekunden dummes Zeug machen. Dann nur "unsigned" hinzu, müsste nach 65 Sekunden Dummfug passieren. Eine Variable ist 16 Bit lang, das ergibt 65535 (Millisekunden). Man möchte aber auch gerne mit negativen Zahlen rechnen, also definiert man das höchste Bit als Vorzeichen - damit geht die 16bit-Variable von -32768 bis +32768. Die Bezeichnung ist "sign", also sagt "unsigned", dass man das Vorzeichen nicht will und der Wert nur positiv von 0 bis 65535 gehen soll. Da 65535 Millisekunden nicht wirklich viel sind, wäre es nett, mehr zu haben - also "long", dann wird das ein Wert mit 32 Bit entsprechend maximal 4294967296 - das sind 49,7 Tage, bis der dann überläuft, also von 4294967296 nach 0 wechselt. 49,7 Tage, grins, schonmal gehört? Das war die maximale Zeit Dauerbetrieb, bevor Windows98 auf die Fresse gefallen ist.
>also definiert man das höchste Bit als Vorzeichen Nein, auch wenn es auf den ersten Blick so aussehen mag. - damit geht die >16bit-Variable von -32768 bis +32768. Die geht von -32768 bis +32767. https://de.wikipedia.org/wiki/Zweierkomplement
Manfred schrieb: > dann wird das ein Wert mit 32 Bit entsprechend > maximal 4294967296 [Korinthenkacker]der mit 32 Bit maximal darstellbare Wert ist aber nur 4294967295[/Korinthenkacker] Mit etwas Geschick kann man aber auch den Fehler nach 49,7 Tagen vermeiden und braucht obendrein dafür nur 16 Bit Variablen, und bei < 128 ms Zeitintervallen würden sogar durchgängig 8 Bit reichen (obwohl millis() mehr Bits zurückgibt). Um bei dem Beispiel zum Eierkochen zu bleiben: was interessiert mich da der Stundenzeiger, und wenn man die Eier um 23:59 aufsetzt wird auch kein Mensch durch die Zeitablesung die Eier plötzlich 23 Stunden und 55 Minuten kochen.
:
Bearbeitet durch User
Vielen Dank an alle Beteiligten. Ich habe mich zunächst weiter mit dem Blinklicht ohne Delay beschäftigt und habe jetzt endlich verstanden was der Code da genau macht. Ich musste Gedanklich erstmal über den Punkt hinaus kommen das das Loop ja mehrfach pro Sekunden durchläuft und der Code sogesehen erst ausgeführt wird wenn die erst Millisekunde des Intervalls anliegt. Soweit also das Blinklicht mit Millis verstanden. Bezüglich unsigned und long, heißt das überall wo ich Zeiten messe mit millis sollte ich unsigned long davor verwenden? Ich habe mit Tastern weiter gemacht die ich als Pull Up Widerstand verbaut habe. Folgenden Code habe ich dann dazu geschrieben: //LEDS beschreiben: int rot = 2; int gelb = 3; int gruen = 4; //Taster beschreiben: int tasterrot = 8; int tastergelb = 9; int tastergruen = 10; //LED Anfangsstatus beschreiben: int rotState = LOW; int gelbState = LOW; int gruenState = LOW; //Taster Anfangsstatus beschreiben: int readingtasterrot; int readingtastergelb; int readingtastergruen; //vorherigen Tasterstatus beschreiben: int previoustasterrot = LOW; int previoustastergelb = LOW; int previoustastergruen = LOW; unsigned long timerot = 0; unsigned long timegelb = 0; unsigned long timegruen = 0; unsigned long debounce = 200; void setup() { pinMode(tasterrot, INPUT); pinMode(tastergelb, INPUT); pinMode(tastergruen, INPUT); pinMode(rot, OUTPUT); pinMode(gelb, OUTPUT); pinMode(gruen, OUTPUT); } void loop() { readingtasterrot = digitalRead(tasterrot); readingtastergelb = digitalRead(tastergelb); readingtastergruen = digitalRead(tastergruen); if (readingtasterrot == HIGH && previoustasterrot == LOW && millis() - timerot > debounce) { if (rotState == HIGH) rotState = LOW; else rotState = HIGH; timerot = millis(); } if (readingtastergelb == HIGH && previoustastergelb == LOW && millis() - timegelb > debounce) { if (gelbState == HIGH) gelbState = LOW; else gelbState = HIGH; timegelb = millis(); } if (readingtastergruen == HIGH && previoustastergruen == LOW && millis() - timegelb > debounce) { if (gruenState == HIGH) gruenState = LOW; else gruenState = HIGH; timegruen = millis(); } digitalWrite(rot, rotState); digitalWrite(gelb, gelbState); digitalWrite(gruen, gruenState); previoustasterrot = readingtasterrot; previoustastergelb = readingtastergelb; previoustastergruen = readingtastergruen; } Hier jetzt die Frage wo sollte bezüglich Millis noch ein unsigned long hin? Ich habe noch das Problem dass man manchmal nicht wirklich richtig gut schalten kann die LED geht aus aber direkt wieder an oder umgekehrt, das liegt wohlam Bouncen oder?
Alexander H. schrieb: > Ich habe mit Tastern weiter gemacht die ich als Pull Up Widerstand > verbaut habe. PullDown Widerstände auch dazu verbaut?
Sorry ich hab mich verschrieben. Ich habe den Taster als Pulldown gebaut. Sprich 5v --> Taster ------> Pinkontakt am Arduino ---> Wiederstand 1k Ohm --> GND Strom fließt also beim drücken zum Pin und ansonsten von + über den Widerstand nach Ground. So hab ichs gebaut: http://rn-wissen.de/wiki/images/7/79/Pulldown.gif Oder heißt das, dass ich den Taster mit der Methode gar nicht entprellt habe?
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.