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
Ein erster Anstoß wäre es ganz einfach den Code zu kopieren und hier - korrekt formatiert - im Forum zu posten. Ich kann da kaum etwas erkennen...
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...
Wenn ich den Code ändere so wie du es mir geschrieben hast dann leuchtet die LED nur noch :/ @stefan schmid: sry ich poste hier vom handy aus.
Mike1996 schrieb: > Wenn ich den Code ändere so wie du es mir geschrieben hast dann leuchtet > die LED nur noch Stefan 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
... hier mal was zum nachdenken und benutzen! // toggling led, 500ms on/off PERIODIC(500) //{ digitalWrite(LEDPIN, !digitalRead(LEDPIN)) }; #ifndef PERIODIC_H #define PERIODIC_H //TODO: // - excluded "{" // - variant: repeat parameter // - variant: timed window // - for (; (millis() - UNIQUE(timer)) >= ms; ) { \ //usage: // PERIODIC(100) //{ // digitalWrite(PIN, HIGH/LOW) // } //create an unique name from given parameter and line number #define UNIQUE(name) __CONCAT(name,__LINE__) //creates an unique timer for each instance, ms period in milli-seconds #define WAITBLOCK(ms) \ static uint32_t UNIQUE(timer) = millis(); \ if (millis() - UNIQUE(timer) >= ms) { //creates an unique timer for each instance, ms period in milli-seconds #define PERIODIC(ms) \ static uint32_t UNIQUE(timer) = millis(); \ if (millis() - UNIQUE(timer) >= ms) { \ UNIQUE(timer) = millis(); //XPERIODIC(ms,1) = WAITBLOCK but takes more program code space! //XPERIODIC(ms,0) = PERIODIC //creates an unique timer for each instance, x: repeats 0-255, 0=endless #define XPERIODIC(ms, x) \ static uint32_t UNIQUE(timer) = millis(); \ static uint8_t UNIQUE(xRepeats) = x; \ static uint8_t UNIQUE(lock); \ if (millis() - UNIQUE(timer) >= ms) { \ if (!UNIQUE(lock)) { \ if ((UNIQUE(xRepeats)==0) || (--UNIQUE(xRepeats))) \ UNIQUE(timer) = millis(); \ else UNIQUE(lock)=1; \ } #endif //PERIODIC_H
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 ... }
Stefan U. schrieb: > Damit verwirrst du den > TO nur. Stimmt. Der muss erstmal lernen, Code hier als Text in den Beitrag zu kopieren. czxfhz
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 :/)
Stefan U. schrieb: > aber das ist weit weg vom Arduino Style. Was ist schon "Arduino Style" ? Blink mit Pulsator
1 | // Wieder eine Variation des BlinkWithoutDelay
|
2 | |
3 | #include <CombieTimer.h> |
4 | |
5 | Combie::Timer::Pulsator puls(1000); // liefert alle 1000 ms einmal true sonst false |
6 | |
7 | void setup() |
8 | {
|
9 | pinMode(LED_BUILTIN,OUTPUT); |
10 | puls.start(); // dank des start(), beginnt puls mit Pause |
11 | }
|
12 | |
13 | void loop() |
14 | {
|
15 | if(puls) digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN)); |
16 | }
|
//---------------------- Blink mit SimpleTimer:
1 | // Wieder eine Variation des BlinkWithoutDelay
|
2 | |
3 | #include <CombieTimer.h> |
4 | |
5 | Combie::Timer::SimpleTimer timer; // timer Instanz anlegen |
6 | |
7 | void setup() |
8 | {
|
9 | pinMode(LED_BUILTIN,OUTPUT); |
10 | }
|
11 | |
12 | void loop() |
13 | {
|
14 | if(timer(1000)) // wenn abgelaufen |
15 | {
|
16 | digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN)); |
17 | timer.start(); |
18 | }
|
19 | }
|
Hallo Leute, Danke euch, ihr habt mir einen Denkstoss verpasst und ich habe es jetzt ? Lg und schönes WE
Erstaunter >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. Ja, mit dem Programmierstiel hätte gute Chancen, beim IOCCC mitmachen zu dürfen: https://de.wikipedia.org/wiki/International_Obfuscated_C_Code_Contest Mittlerweile gibt es aber gute Bücher, wie man seinen Stiel verbessern kann: https://www.oreilly.de/buecher/120174/9783897215672-weniger-schlecht-programmieren.html ( das Buch ist übrigens wirklich gut )
Harry schrieb: > Mittlerweile gibt es aber gute Bücher, wie man seinen Stiel verbessern > kann: Den Besenstiel? ;-)
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 ;)
Mike1996 schrieb: > @stefan schmid: sry ich poste hier vom handy aus. Selbst so ein "smartes" Handy wird doch copy&paste irgendwie hin kriegen ...
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:
1 | startwert = startwert + interval; |
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?
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.