ich bin relativ neu beim programmieren. Habe bis jetzt nur einen ganzen Schwung Versuchsaufbauten gemacht und dazu kleine Programme geschrieben. Nun habe ich aber ein Problem was ich nicht weiß wie ich es an gehen soll, da ich „Zeit“ mit ins Spiel bringen muss.
Ich möchte einen Ablauf steuern.
Ich habe einen Taster, wenn ich diesen betätige, soll für eine exakte Zeit, ein Motor angesteuert werden. Wichtig dabei, das ist auch mein Problem was ich nicht gelöst bekomme, der Schalter soll einen Impuls geben und direkt danach muss er ausgeschaltet werden, da sonst der Motor dauerhaft dreht, wenn ich den Taster gedrückt halte. Das bekomme ich in meinen Varianten nicht hin. Delay blockiert mir mein Programm.
Weil:
gleichzeitig habe ich zwei Lichtschranken. Wenn hier ein Impuls kommt, sollen für jede weitere Lichtschranke ein weiterer Motor für eine exakte Zeit anlaufen.
(Ja das soll Zeitabhängig laufen und nicht über einen Kontakt oder ähnliches)
Der totale Kracher wäre, wenn alle drei „Schalter“ also, der Taster1, Lichtschranke1 und Lichtschranke2, unabhängig voneinander schalten würden.
Also nicht unbedingt in Reihenfolge T1 – L1 – L2 sondern auch gemischt.
Dazu wäre es, aber das würde ich selbst noch hin bekommen, schön die Schaltzeiten über Variablen zu verteilen, damit ich sie evtl. über die Serielleschnitstelle ändern könnte.
Kann mir jemand weiter helfen, da ich das mit der Zeitsteuerung nicht verstehe?
Danke für die schnelle Antwort, aber das sind die Funktionen die so leider nicht funktionieren. Ich wollte das irghendwie über "millis" machena auch in den Beispielen delay das Programm stoppt.
Ablaufsteuerung
Meine Standardantwort zu Ablaufsteuerungen:
Eine Stichworte Sammlung für Google Suchen:
Endlicher Automat,
State Machine,
Multitasking,
Coroutinen,
Ablaufsteuerung,
Schrittkette,
BlinkWithoutDelay,
millis() ist der richtige Ansatz, wenn Du auf mehrere Sachen reagieren willst. Schau Dir BlinkWithoutDelay an und suche mal nach der Nachtwächtererklärung.
Dafür verwendet man einen endlichen Automaten = finite state machine = Schrittkette.
klugitheultima:
... der Schalter soll einen Impuls geben und direkt danach muss er ausgeschaltet werden, ...
Statt "ausgeschaltet" eher "wirkungslos".
Dazu verwendet man eine Flankenerkennung: Wenn sich der Zustand des Schalters von HIGH nach LOW oder umgekehrt ändert, dann soll etwas passieren. Das kann man gut mit dem Entprellen eines machanischen Schalters verbinden.
klugitheultima:
Delay blockiert mir mein Programm.
Gut erkannt, weg damit!
klugitheultima:
Der totale Kracher wäre, wenn alle drei „Schalter“ also, der Taster1, Lichtschranke1 und Lichtschranke2, unabhängig voneinander schalten würden.
Das ist prinzipiell kein Problem, also machbar.
klugitheultima:
Kann mir jemand weiter helfen, da ich das mit der Zeitsteuerung nicht verstehe?
Mein Tipp: Beginne mit dem IDE-Beispiel blinkWithOutDelay, erweitere es auf zwei mit unterschiedlicher Frequenz blinkende LEDs. Wenn Du das verstanden hast, ist die größte Hürde für Dich überwunden.
Eine Herzschlag-LED baue ich gerne in meine Programme ein, um ungewollte Blockaden erkennen zu können.
Weiterer Lesestoff: Suche im Forum nach "agmue anleitung"
Entschuldigt bitte, natürlich habe ich mich mit dem Thema schon auseindnaer gesetzt. Um genau zu sein sehr viel Zeit. Bis ich auf diese Programierung gekommen bin.
// LED Zeitschaltung bei betätigung des Tasters Pin 12 oder Pin 10
// leuchtet die LED, bis die vorgegebene Zeit abgelaufen ist
// bsp. delay(2000); = 2 sec Leuchtdauer
/****************************************************************/
int ledPin1=12;
int inputPin2=3;
int ledPin2=13;
int inputPin1=2;
int val3 = LOW;
int val2 = HIGH;
unsigned long led1Millis = 0;
unsigned long led2Millis = 0;
void setup() // Initialisierung
{
pinMode(ledPin1,OUTPUT); // LED-Pin als Ausgang
pinMode(inputPin1,INPUT); // Schalter-Pin als Eingang
pinMode(ledPin2,OUTPUT); // LED-Pin als Ausgang
pinMode(inputPin2,INPUT); // Schalter-Pin als Eingang
}
void loop() // Endlosschleife
{
val3=digitalRead(inputPin1); // Taster einlesen
val2=digitalRead(inputPin2); // Taster einlesen
if (val3 == HIGH && led1Millis == 0) // Testen ob der Taster auf High steht und ob die led nicht schon leuchtet
{
digitalWrite(ledPin1, HIGH); // LED einschalten
led1Millis = millis(); //einschaltzeit merken
} else if (led1Millis + 18 < millis()) //led leuchtet bereits seit 2 sec
{
digitalWrite(ledPin1, LOW); // LED ausschalten
led1Millis = 0; //einschaltzeit zurücksetzen
}
if (val2 == LOW && led2Millis == 0) // Testen ob der Taster auf High steht und ob die led nicht schon leuchtet
{
digitalWrite(ledPin2, HIGH); // LED einschalten
led2Millis = millis(); //einschaltzeit merken
} else if (led2Millis + 2000 < millis()) //led leuchtet bereits seit 2 sec
{
digitalWrite(ledPin2, LOW); // LED ausschalten
led2Millis = 0; //einschaltzeit zurücksetzen
}
}
Aber leider wenn ich den Taster gedrückt halte Leuchtet die LED dauerhaft und bei der Lichtschranke auch. Ich möchte aber das das so nicht ist. Habt ihr da einen Lösungsansatz?
Setze Deinen Sketch bitte in Codetags (</> oben links im Forumseditor). Das kannst Du auch noch nachträglich machen. Dadurch ist er auf allen Geräten besser lesbar und Du erreichst mehr potentielle Helfer.
Hi
[quote author=klugitheultima link=msg=3602768 date=1518357640]
} else if (led1Millis + 18 < millis()) //led leuchtet bereits seit 2 sec
[/quote]
Hier könnte sein, daß Dir das Aufleuchten dieser LED fehlt - statt der im Kommentar genannten zwei Sekunden leuchtet die LED nämlich nur 18ms (0,018 Sekunden lang).
Schönes Beispiel für 'Kommentar passt nicht zum Programm'.
Wenn Du in den Kommentaren auf feste Zahlenwerte verzichtest, passen die Kommentare auch beim Testen - hier also statt '2' ein 'x' oder was in der Art 'angegebene Zeit in ms'.
Und was soll mir das bringen? Das verstehe ich nicht!
Du vergleichst den alten Zustand mit dem neuen Zustand und wirst aktiv, wenn es eine Veränderung gegeben hat, also alter Zustand ungleich neuer Zustand.
Ich habe jetzt viele Tage gelesen und rum probiert. Ich habe meine Codes vermischt und versucht. Ich bekomme es nicht hin.
Ich verstehe den Kram mit aktKlappe und aktTuer nicht. Ok die Sachen zu vergleichen macht Sinn, aber ich bekomme es nicht umgesetzt.
Auch die Antzworten mit BlinkWithoutDelay habe ich mir natürlich angesehen. Alleine zum Blinken bekomme ich das hin, aber in Kombination nicht. Ich bin so glaube ich langsam, zu dämlich um das zu verstehen. Ich habe mitlerweile ein zum Thema gelesen. Wenn der Code da steht, verstehe ich was er macht. Selber die Probleme zu lösen, keine Chance. Habt ihr ne Buchempfehlung?
Anbei mein Code. Wenn ich den anwende, leucht nur eine LED. Mehr ändert oder tut sich nicht. Warum?
@klugitheultima
Dein Problem ist, du willst mit dem Kopf durch die Wand, oder anders gesagt, viele Dinge auf einmal lösen.
Das wird mit deinem Wissensstand nichts.
Du solltest mit kleinen Dinge anfangen und nach und nach die Projekte wachsen lassen.
Nur so verstehst du es und lernst auch daraus.
Fange mit BlinkWithoutDelay an und baue Funktionen (zusätzliche Led ein und ausschalten) hinzu.
So lernst du es, langsam aber sicher.
Was deinen Taster angeht:
Schließe ihn als Pulldown an einem Interrupt fähigen Pin an und setze einen Interrupt auf die fallende Flanke. Wie man Interrupt macht findest du in der Reference.
In der Methode machst du dann eine Codeseitige Entprellung (merken wann der Interrupt zuletzt kam und mit der aktuellen Zeit vergleichen und nur dann reagieren, wenn mindestens X Millisekunden vergangen sind). Für die Entprellzeit sollten normalerweise 50ms genügen, wenn du aber den Taster nicht 20x in der Sekunde betätigen willst, dann kannst du auch einen deutlich höheren Wert nehmen, das bringt mehr Sicherheit. Ich würde da ca. 200ms ansetzen.
In der Interruptmethode setzt du dann ein Flag, das du in deinem Loop auswerten kannst, um den Motor zu starten.
Wenn du das auf die Weise mit mehreren Gebern (Taster und 2 Lichtschranken) machen willst, dann kommt es drauf an, welche Hardware du hast. Du bräuchtest dann genügend Interruptfähige Pins, der ursprüngliche Arduino Uno hat z.B. nur 2.
Wenn deine Hardware nicht genug Interrupt Pins hat, dann kannst du entweder Multiplexen oder musst es über zyklisches Pinauslesen machen. Aber erstmal mit einem Pin hinbekommen, der Rest kommt dann.
PCINT gibt es auch noch, allerdings muß man selber prüfen, welcher Pin gerade zugeschlagen hat, wenn man Mehrere auf einem Port als Interrupt benutzt.
Siehe dazu
@TelosNox und postmaster-ino: So sehr ich die gute Absicht unterstellen möchte, so halte ich es für problematisch, einem Anfänger Interrupts vorzuschlagen, wenn es auch mit millis() geht. Die Interrupts erscheinen mir doch komplizierter und fehleranfälliger zu lernen als millis(). Nur so meine Meinung.