Hallo Leute, hab nicht viel Erfahrung mit uC's, fang gerade klein an mit
einem Arduino Uno.
Arbeite mir die Funktionen nach der Reihe durch und lasse eigentlich
immer nur ne LED blinken. Hier bei der Millis Funktion will aber meine
LED nie aufleuchten, was ist an dem Code falsch?
Ich hoffe es kann mir wer einen Denkstoss geben.
Lg
Schau zunächst mal nach ob die LED überhaupt angeht, d.h. setze den
einaus ganz oben mal auf HIGH anstatt LOW. Wenn immer noch nicht geht,
versuch mal den Pin 13 mit der internen LED.
Und setze millis()-startwert in der if()-Abfrage zur Sicherheit mal in
Klammern...
Mike1996 schrieb:> Wenn ich den Code ändere so wie du es mir geschrieben hast dann leuchtet> die LED nur nochStefan S. schrieb:> Ein erster Anstoß wäre es ganz einfach den Code zu kopieren und hier -> korrekt formatiert - im Forum zu posten
Poste doch erst mal den Code! Und mach ein Foto lieber vom Aufbau der
Schaltung als vom Bildschirm
loop() wird immer wieder aufgerufen. Dort setzt du jedesmal den
startwert auf millis(). Die nachfolgende if() Bedingung kann daher
niemals erfüllt sein.
Wenn du den Quelltext gepostet hättest, hätte ich ihn für Dich
korrigiert. Aber alles von deinem Foto abzuschreiben, dazu bin ich zu
Faul.
Bei jedem Durchlauf wird Start auf den aktuellen millis Wert gesetzt.
Deine Bedingung wird nur war wenn zwischen dem setzten von Start und der
If Abfrage mehr als 6000 ms vergehen, und so langsam ist der Arduino
nicht.
Das kopieren des neuen Wertes darf nur innerhalb der If Bedinung
erfolgen.
Gruß JackFrost
Apollo Mond schrieb:
>... hier mal was zum nachdenken und benutzen!
So einfach kann es also sein -und so übersichtlich. Ich dachte wirklich
nicht, daß es mit so geringem Aufwand möglich ist, eine LED blinken zu
lassen. Erstaunlich.
ok!
also
static unsigned long startwert = millis();
UND
if (millis()-startwert >= interval) {
... //to do something
startwert = millis(); //reset startwert und los gehts wieder ...
}
Hallo Mike,
wie meine Vorposter bereits geschrieben haben setzt du mit jedem
Durchlauf des Hauptprogramms den Startwert mit den aktuellen millis().
dadurch wird aber die Bedingung nie wahr, dass mehr als die nanos()
(gibt es auch am Arduino) vergehen, die ein Programmdurchlauf braucht.
Versuche dir das ganze als Code aber selber herzuleiten!
- Initiere eine Variable millisAktuell und millisVorher mit "0" im
Setup.
- Im Hauptprogramm setzt du nun die millisAktuell mit den millis()
- vergleiche den Wert von millisAktuell mit den millisVorher per
arithmetischer Operation auf Differenz von deinem gewünschten
Blinkinterval
- sind die millisAktuell und millisVorher soweit wie dein gewünschter
Interval auseinander, soll deine Bedingung als wahr gelten und dein If
ausgeführt werden.
- setze im If deinen Ausgang (togglen mit einaus!=einaus), hiernach die
millisVorher mit den millis() setzen.
- If abgeschlossen, Hauptschleife durchlaufen bis Bedingung
(millisAktuell-millisVorher >= Intervall) wieder wahr.
Vorsicht, die Funktion millis() kann auch wieder bei lang genuger
Betriebsdauer des Arduinos von vorne anfangen. Daher immer die millis()
in einer eigenen Variable zwischenspeichern. Zusätzlich ist es von
Vorteil die Differenz zwischen aktuellen und vorherigen millis() als
Betrag zu rechnen, also ohne Vorzeichen.
MfG, EGS
Erstaunter schrieb:> So einfach kann es also sein -und so übersichtlich. Ich dachte wirklich> nicht, daß es mit so geringem Aufwand möglich ist, eine LED blinken zu> lassen. Erstaunlich.
... das sind doch nur ein paar geniale makros für ... äh - junge
nachdenker :/)
Mike1996 schrieb:> Hier noch einmal der Code und die "Supergroße" Schaltung.
Mike, das du ein Foto von deinem Code machst, anstatt die mit Copy&Past
hier zu posten ist schon eine Frechheit für sich!
Huh schrieb:> Harry schrieb:>> Mittlerweile gibt es aber gute Bücher, wie man seinen Stiel verbessern>> kann:>> Den Besenstiel? ;-)
Männer sind Frauen mit Stiel ;)
Forist schrieb:> Selbst so ein "smartes" Handy wird doch copy&paste irgendwie hin kriegen
Hmm: Per RDP auf den Windows-Rechner (alternativ SSH auf Linux) gehen,
dort den Bereich markieren, ausscheiden und anschließend im
(Handy-)Browser einfügen und versenden.
Ja, das sollte gehen.
Apollo M. schrieb:> if (millis()-startwert >= interval) {>> ... //to do something> startwert = millis(); //reset startwert und los gehts wieder ...>> }
Damit wirst du keine vernünftig definierten Intervalle produzieren
können.
Mit dem Code sammelst du dir bei jedem Durchlauf zusätzlich zu der durch
interval festgelegten Periode eine Zeitverschiebung in Höhe der
Laufzeit von "... //to do something" auf. Wenigstens sollte man den
neuen Startwert, so man ihn unbeding aus dem aktuellen Wert von millis()
ableiten will, direkt als erstes nach dem "if"-Statement festlegen.
Besser wäre, zumindest solange "to do something" sicher kürzer als
"interval" ist, ihn aus dem alten zu berechnen:
Wolfgang schrieb:> Mit dem Code sammelst du dir bei jedem Durchlauf zusätzlich zu der durch> interval festgelegten Periode eine Zeitverschiebung in Höhe der> Laufzeit von "... //to do something" auf.
Und?
Wen kümmerts?
Naja...
In Fällen wo es keinen "Schlupf" geben darf, ist dein Einwand schon ok.
Aber andersrum gibt es auch Fälle, wo eine Zeit nicht unterschritten
werden darf.
Und dann fällt dir dein Verfahren auf die Füße.
Also, wie immer:
Ohne konkrete Anforderungsliste, kann man diesen, oder jenen, Weg nicht
als die "richtige" oder "falsche" Lösung bezeichnen.
Noch nicht mal ein "Besser" ist zu benennen.
Arduino F. schrieb:> Aber andersrum gibt es auch Fälle, wo eine Zeit nicht unterschritten> werden darf.> Und dann fällt dir dein Verfahren auf die Füße.
Das Intervall ist genau das spezifizierte Vielfache vom
millis()-Timerinterruptintervall. Da wird nichts unterschritten,
jedenfalls wenn man von der Zeit zwischen zwei Aufrufen von "... //to do
something" spricht.
Wolfgang schrieb:> Da wird nichts unterschritten,
Das ist gelogen!
Oder du kannst einfach nur nicht rechnen.
Oder du denkst dir einfach nur Dinge aus, bist aber zu faul diese zu
prüfen.
Aber die Unwahrheit, die lasse ich dir nicht durch gehen.
Beweis:
Angenommen 5 ms Verspätung
> startwert = startwert + interval;
Dann
> if (millis()-startwert >= interval)
Wird der Zyklus 5 ms kürzer sein, als von interval vorgegeben.
Denn millis() ist schon 5ms weiter.
Und damit bist du widerlegt.
Arduino F. schrieb:> Und damit bist du widerlegt.
Wenn du die Aufgabe nicht in der zur Verfügung stehenden Zeit erledigt
kriegst, hast du natürlich ein Problem.
Dann hast du nur die Wahl, unkontrollierte Verschiebungen in Kauf zu
nehmen, (deine Methode) oder Aufrufe von "... //to do something"
ausfallen zu lassen, indem man z.B. prüft, wie es am Ende von "... //to
do something" mit der Restzeit aussieht. Es kommt drauf an, was
wichtiger ist - festes Intervall oder Mindest-Idle-Zeit.
Wolfgang schrieb:> Es kommt drauf an, was> wichtiger ist - festes Intervall oder Mindest-Idle-Zeit.
Damit hast du jetzt zugegeben, dass dein Verfahren die wirksame Interval
Zeit verkürzen kann!
Richtig?