Zum Glück garnicht, soweit ich weiß. Schreibe deinen Code nicht
blockierend, dann musst du auch nicht die ISRoutine missbrauchen!
Einfach ein flag setzen, und in der loop auswerten.
Stefan S. schrieb:> Einfach ein flag setzen, und in der loop auswerten.
Danke für deine Antwort!
Bin Neuling bei den Timern... hast du mir einen Link zu einer Quelle?
Oder eine Erklärung wie ich das am besten mit einem Flag und einer
Schleife löse?
Gruss
Daniel
Danke für deine Antwort!
versuche es gerade mit dem flexitimer...werde berichten
Blinken ist ja leicht aber eine LED 100ms leuchten lassen dann 200ms
pause und dann wieder von vorne ist nicht so leicht...
Ich bin der Überzeugung: Wer delay() verwendet hat offensichtlich nicht
besseres zu tun.
Wird diese Aussage wörtlich genommen, so ergeben sich zwei sehr einfache
Schlussfolgerungen:
1. Trifft diese Aussage ohne Einschränkung zu, so kann man problemlos
auch mal 12 Sekunden in einer Interrupt-Routine rumlungern.
2. Trifft dies aber nicht zu, so hilft nur noch "Üben".
Ob die Patentantwort - "dann verlagere das Problem doch in die
Hauptschleife" - wirklich hilft, ist eine andere Sache.
Daniel R. schrieb:> Danke für deine Antwort!>> versuche es gerade mit dem flexitimer...werde berichten> Blinken ist ja leicht aber eine LED 100ms leuchten lassen dann 200ms> pause und dann wieder von vorne ist nicht so leicht...
Auch dass ist lösbar über eine Library:
https://github.com/robertgallup/BobaBlox
Daniel R. schrieb:> versuche es gerade mit dem flexitimer...werde berichten> Blinken ist ja leicht aber eine LED 100ms leuchten lassen dann 200ms> pause und dann wieder von vorne ist nicht so leicht...
doch ist es.
selbes Prinzip. Du hast eine Uhr in Form von millis(). Du bestimmst,
wann ein Vorgang beendet sein soll, in dem du zum Zeitpunkt an dem der
Vorgang beginnt die Zeit nimmtst, die geplante Dauer dazuaddierst und
laufend (bei jedem durchlauf durch loop) überprüfst, ob dieser zeitpunkt
schon vorbei ist.
Aus praktischen Gründen macht man es technisch ein klein wenig anders.
Man nimmt die Zeitdifferenz zwischen 'jetzt' (repräsentiert durch
millis()) und dem Beginn der Aktion und sieht nach ob diese
zeitdifferenz schon größer ist als die geplante Zeitdifferenz.
Jede Hausfrau kann das. Stellt sie das Gulasch auf den Ofen, schaut sie
auf die Küchenuhr. ZUr abgelesenen Zeit kommen 2 Stunden dazu und ab zu
wird auf die Uhr geschaut, ob dieser Zeitpunkt erreicht ist. Wenn sie
wissen will, wie lange das Gulasch schon kocht, dann liest sie die
aktuelle Zeit von der Küchenuhr ab, zieht davon die Startzeit ab und
findet so raus, dass das Gulasch schon seit anderthalb Stunden kocht.
Das ist weniger als die geplanten 2 Stunden, daher darf es noch weiter
kochen.
Ganz simpel.
1
unsignedlongblinkStart;
2
3
voidsetup()
4
{
5
blinkStart=millis();
6
}
7
8
voidloop()
9
{
10
unsignedlongnow=millis();
11
12
if(now-blinkStart<100)
13
ledeinschalten
14
15
elseif(now-blinkStart<300)// 100 + 200; ein kompletter Blinkzyklus dauert daher 300 ms
16
// in der ersten Hälfte des Zyklus war die LED ein
17
// jetzt geht es darum, das sie bis zum Ende
18
// des Blinkzyklus aus sein muss
19
ledausschalten
20
21
else// ein kompletter Blinkzyklus ist abgelaufen
22
// neuen starten indem man sich merkt
23
// wann das der Fall war.
24
blinkStart=now;
25
}
und damit gelingt es dann auch ganz problemlos, 2 LED mit völlig
unterschiedlichen Zeiten blinken zu lassen. Zb die eine mit 100+200 ms
und die andere mit 400+700ms
Wer delay's benutzt kann nicht programmieren. Und das kommt von dem
absolut untauglichen Einsteigerbeispiel eine LED mit einem delay blinken
zu lassen. Ein vernünftiges Einsteigerbeispiel wäre es einmal zwei oder
drei LED's gleichzeitig blinken zu lassen und alle mit einer anderen
Frequenz und ohne delay's. Dann wäre eine ganze Menge für die Zukunft
geschient. Und zwar richtig.
Was bisher bei delay() im Interrupt (Arduino Sketch) übersehen wurde:
Funktioniert wohl sowieso nicht, Zitat aus Arduino Reference:
"Since delay() requires interrupts to work, it will not work if called
inside an ISR"
Daher ist der letzte Ansatz von Karl Heinz schon passend.
Thomas H. schrieb:> Und das kommt von dem> absolut untauglichen Einsteigerbeispiel eine LED mit einem delay blinken> zu lassen. Ein vernünftiges Einsteigerbeispiel wäre es einmal zwei oder> drei LED's gleichzeitig blinken zu lassen und alle mit einer anderen> Frequenz und ohne delay's.
Genau und wer als Baby anfängt zu Krabbeln hat sich schon das ganze
Leben versaut, man hat sofort aufzustehen und über Kopfsteinpflaster zu
laufen.
Ist das jetzt die Aroganz der Ingenieure oder das Kastendenken der Elite
die untersich bleiben will und allen den Einstieg möglichst schwer
machen will?
Natürlich ist das einfachste Blinken mit Delay der beste Anfang um nicht
gleich gleich abgeschreckt oder als Anfänger mit seinen Fragen in diesem
Forum vor den Kopf gestossen zu werden.
bekomme ich am Terminal nicht 0 1 2 3 4,.... sondern, 0 0 0 1 1 1 2 2 3
3 3
möchte jetzt nach ende einer Periode den Pin wechseln.
zuerst pin 3 dann 4 dann 5 usw...
so funktioniert es ja nicht:
1
2
inta=3;
3
intende=40;
4
5
if(valuemillis==0)
6
a++;
7
8
if(valuemillis==ende)
9
a=3
10
11
//das a setze ich dann beim timer für die Einzelne LED wie oben genannt ein
so würde er ja bei einer Periode gleich 4 5 6 zählen.
Gruss
Daniel
@Ulrich Du Fuchs ! Daran hab ich noch gar nicht gedacht ^^
@Daniel
Du hast glaube ich nicht verstanden was millis() sowie % bedeutet, oder?
Modulo (%) gibt den Rest einer Division zurück. D.h. deine Variable
valuemillis zählt immer von 0 ms bis 999 ms hoch, je nachdem wie
schnell/oft du deine Berechnung aufrufst.
millis() % 1000 =Periodendauer von 1000ms richtig?
wenn ich die Periodendauer abrufe bekomme ich nicht 0 1 2 3 4 5 6,.
sondern
0 0 0 1 1 2 2 2 3 3 3 4 4,... hätte ich nur 1 2 3,... wär das Problem
mit nem einfachen IF lösbar.
Guest schrieb:> Natürlich ist das einfachste Blinken mit Delay der beste Anfang um nicht> gleich gleich abgeschreckt oder als Anfänger mit seinen Fragen in diesem> Forum vor den Kopf gestossen zu werden.
Das Einfachste ist noch lange nicht das didaktisch sinnvollste.
Guest schrieb:> Genau und wer als Baby anfängt zu Krabbeln hat sich schon das ganze> Leben versaut, man hat sofort aufzustehen und über Kopfsteinpflaster zu> laufen.
Die biologische Entwicklung des ZNS, sowie die psychomotorische
Entwicklung von Lebewesen haben nichts mit der Didaktik in der
Erwachsenenbildung zu tun!
Tja, ich sehe da zwei Variablen: 1000 und 500. Nur weil du nicht z.B.
int myVar = 1000; geschrieben hast heißt das nicht, dass die 1000 nicht
doch eine Variable sind. ;)
Michael K. schrieb:> Tja, ich sehe da zwei Variablen: 1000 und 500
Ich weiß ja nicht welche Sprache du sprichst, aber in meiner nennt sich
sowas Konstante, nicht Variable.
Ziegenpeter schrieb:> Ich weiß ja nicht welche Sprache du sprichst, aber in meiner nennt sich> sowas Konstante, nicht Variable.
Ja, aber ob das eine (veränderbare Variable) ist oder Konstante ist dem
Compiler und dem AVR relativ egal, beides wird SRAM benötigen. Es ist
also raltiv wurscht ob man schreibt myVar1 = myVar2 + myVar3 oder myVar
= 100 + 400. Der "Vorteil" bei letzterem ist nur, sofern der Compiler
klug genug ist, dass es ggf. weniger SRAM belegt als ersteres (je
nachdem wie man myVar2 und myVar3 definiert hat).
Bastler schrieb:> Was bisher bei delay() im Interrupt (Arduino Sketch) übersehen wurde:> Funktioniert wohl sowieso nicht, Zitat aus Arduino Reference:>> "Since delay() requires interrupts to work, it will not work if called> inside an ISR"
Diese Schlussfolgerung ist doch wohl Unfug. Warum soll in einer ISR kein
weiterer Interrupt abgearbeitet werden können?
Was hindert einen nach anfänglichen Aktionen innerhalb der ISR, die
Abarbeitung von ISR wieder frei zu geben.
Michael K. schrieb:> Ja
In c/C++ ist relativ klar definiert, was eine Konstante, und was eine
Variable ist.
Und wenn du einer Sprachverwirrung unterliegst, dann ist das dein
Problem.
Daran kannst du arbeiten, oder es bleiben lassen...
Wolfgang schrieb:> Diese Schlussfolgerung ist doch wohl Unfug. Warum soll in einer ISR kein> weiterer Interrupt abgearbeitet werden können?> Was hindert einen nach anfänglichen Aktionen innerhalb der ISR, die> Abarbeitung von ISR wieder frei zu geben.
Einfach mal nachschaun wie delay() innerhalb der Arduino-Umgebung
definiert ist. Ganz offenbar so, dass es innerhalb einer ISR nicht
benutzt werden kann/darf ;)
Wolfgang schrieb:> Was hindert einen nach anfänglichen Aktionen innerhalb der ISR, die> Abarbeitung von ISR wieder frei zu geben.
Einen klugen Menschen wird nichts daran hindern....
Aber er wird sich dann über die Eintrittsinvarianz seines eigenen
Interrupts ebenfalls Gedanken machen dürfen...
Nein!
Delay() in Interrupts ist keine gute Idee.
Ulrich F. schrieb:> Michael K. schrieb:>> Ja> In c/C++ ist relativ klar definiert, was eine Konstante, und was eine> Variable ist.> Und wenn du einer Sprachverwirrung unterliegst, dann ist das dein> Problem.> Daran kannst du arbeiten, oder es bleiben lassen...
Ja, deshalb heißt es in C/C++ ja auch "Konstante Variable", also eine
Variable die nach ihrer Initialisierung nicht mehr verändert werden
kann. Das ändert aber auch nichts daran, dass sie genauso viel RAM
benötig wie eine Variable, die nach ihrer Initialisierung verändert
werden kann.
Oben war nur die Rede davon, dass der Code ganz ohne Variable gehen
würde und dass nur, weil man der "Variablen" keinen Namen verpasst hat.
Wer das aber glaubt weiß schlicht nicht wie der Compiler arbeitet. Man
muss sich immer bewusst machen wenn man z.B. irgendwo im Code eine 100
hin schreibt der Compiler daraus sehr wohl eine "Variable" macht. Und
die liegt dann im RAM.
Am besten sieht man das IMO bei Strings. Es gibt bei den AVRs ja das
Makro PSTR(string). Hinter PSTR verbirgt sich aber nur eine Anweisung
für den Compiler den String nicht ins RAM zu kopieren, was er sonst
machen würde, sondern ihn im Flash zu lassen.
Michael K. schrieb:> Wer das aber glaubt weiß schlicht nicht wie der Compiler arbeitet.
Auf die Gefahr hin, dass mich mein Kompiler belügt:
int test = 3 + 5;
Beansprucht 2 Byte Ram auf meinem Arduino getriebenen AVR.
Wenn 3 und 5 konstante Variablen im Ram wären, würde ich 6 Byte
erwarten.
Vielleicht liebt mich mein Kompiler?
Vielleicht möchte er dir auch einen Stock zwischen die Beine werfen?
Wer kann es wissen...