Hallo, den Zustand von Tastern frage ich in der hauptschleife immer ab. Wenn der Pegel eines Tasters auf high ist, habe ich ein delay von 20 ms. Ist der Zustand danach immer noch auf high, ist der taster gedrückt. Jetzt habe ich aber auch einen timer laufen, der regelmäßig die ISR aufruft. Wenn ich jetzt in einem delay bin, wird die ISR aufgerufen? Bei einem ATMega?
Wenn die Interrupts während des delay aktiviert sind, wird diese unterbrochen. delay braucht dann ggf. länger als die angegebene Zeit.
Das kommt alleine auf die delay-Funktion an. Radio Eriwan sagt: Kann sein, muß aber nicht. Oliver
Herbert schrieb: > Wenn ich jetzt in einem delay bin, wird die ISR aufgerufen? Bei einem > ATMega? Nein, laut der Arduino-Webseite. https://www.arduino.cc/reference/de/language/functions/external-interrupts/attachinterrupt/
das haengt von deinem prg bzw delay ab, ob dieser die Interrupts sperrt in was hasste das programmiert? VlG Charly
TR.0LL schrieb: > Herbert schrieb: > >> Wenn ich jetzt in einem delay bin, wird die ISR aufgerufen? Bei einem >> ATMega? > > Nein, laut der Arduino-Webseite. > > https://www.arduino.cc/reference/de/language/functions/external-interrupts/attachinterrupt/ Da hast du irgendwas gründlich missverstanden.
Delay, Taster &Interrupt. Geil, ich hol schon mal Popkorn. Irgendwie scheint das in der Coronakrise jetzt das Dauerthema zu sein.
TR.0LL schrieb: > Nein, laut der Arduino-Webseite. Da steht lediglich, dass die Arduino-Funktion delay() innerhalb einer ISR nicht funktionieren wird, da es selber auf ISR angewiesen ist. Es kommt auf die Implementation an, ob die Funktion unterbrochen werden kann. Herbert schrieb: > habe ich ein delay Der TO schreibt aber nichts von Arduino, könnte also jedes beliebiete Delay meinen. Also auch _delay_ms(), welches nicht mit Interrupts arbeitet.
Christian H. schrieb: > Da steht lediglich, dass die Arduino-Funktion delay() innerhalb einer > ISR nicht funktionieren wird, da es selber auf ISR angewiesen ist. So ist es. Christian H. schrieb: > Der TO schreibt aber nichts von Arduino, könnte also jedes beliebiete > Delay meinen. Also auch _delay_ms(), welches nicht mit Interrupts > arbeitet. Auch dem stimme ich zu. Was dafür sorgt, dass Interrupts nicht unbedingt ein Arduino delay() verlängern. (nur wenn es recht exakt am Ende des delay() passiert) Und dass sich ISR Zeiten bei den _delay_ms() akkumulieren.
Ich habe das jetzt auch ohne ein _delay_ms hinbekommen im button-header
1 | #define BUTTON_DEBOUNCETIME 3
|
2 | |
3 | typedef struct |
4 | {
|
5 | uint8_t state; |
6 | uint8_t active; |
7 | uint8_t changed; |
8 | volatile uint8_t debounce; |
9 | }IO; |
10 | |
11 | IO button[2]; |
In der while-schleife
1 | /* Taster abfragen */
|
2 | if((PIND & (1<<PIND4)) && (button[0].state==0) && (!button[0].debounce) ) /* rising edge */ |
3 | {
|
4 | button[0].debounce = BUTTON_DEBOUNCETIME; |
5 | button[0].state = 1; |
6 | }
|
7 | else if((PIND & (1<<PIND4)) && (button[0].state==1)) /* on */ |
8 | {
|
9 | button[0].changed = 1; |
10 | button[0].active = 1; |
11 | }
|
12 | else if((!(PIND & (1<<PIND4))) && (button[0].state==1) && (!button[0].debounce) ) /* falling edge */ |
13 | {
|
14 | button[0].debounce = BUTTON_DEBOUNCETIME; |
15 | button[0].state = 0; |
16 | }
|
17 | else if((!(PIND & (1<<PIND4))) && (button[0].state==0) && (button[0].active==1)) /* off */ |
18 | {
|
19 | button[0].changed = 1; |
20 | button[0].active = 0; |
21 | }
|
im timer ISR
1 | if(button[0].debounce) button[0].debounce--; /* debounce button */ |
2 | if(button[1].debounce) button[1].debounce--; /* debounce button */ |
Jetzt wäre die Frage, wie ich es für weiter buttons hinbekomme, ohne alles zu kopieren (also den ablauf in der while-schleife. Momentan ist ja nur Button1 implementiert. für Button2 und weitere müsste ja alles nochmal kopiert werden und nur der pin und button angepasst werden (PIND & (1<<PIND4) -> (PIND & (1<<PIND4) button[0] -> button[1] es werden letztendlich 5 buttons. Das bringt ja ewig viel code, wo aber letztendlich immer das selbe drinn steht.
Herbert schrieb: > Das bringt ja ewig viel code, wo aber > letztendlich immer das selbe drinn steht. Du weißt, wie man Strukturen baut. Du kannst diese in Arrays stopfen. Selbst Schleifen sind dir bekannt. Warum gehst du den Weg nicht konsequent weiter? !
Andreas B. schrieb: > Delay, Taster &Interrupt. > Geil, ich hol schon mal Popkorn. Irgendwie scheint das in der > Coronakrise jetzt das Dauerthema zu sein. Ich bin schon gespannt was W.S. diesmal für nen Stuss schreiben wird!
Mw E. schrieb: > Ich bin schon gespannt was W.S. diesmal für nen Stuss schreiben wird! Bitte nicht zu viel. Ich hab schon genug Popkorn die letzten Tage gefressen.
Herbert schrieb: > es werden letztendlich 5 buttons. Das bringt ja ewig viel code Warum schaust Du nicht einfach unter Projekte & Code nach? Kurz und knackiger Code für 8 Tasten mit Repeat bzw. lang/kurz.
Arduino Fanboy D. schrieb: > Warum gehst du den Weg nicht konsequent weiter? ! aber wie kann ich (PIND & (1<<PIND4)) im struct speichern?
Herbert schrieb: > aber wie kann ich > (PIND & (1<<PIND4)) > im struct speichern? PIND ist im Kern auch nur ein Zeiger/Adresse Und (1<<PIND4) eine Konstante
Herbert schrieb: > aber wie kann ich > (PIND & (1<<PIND4)) > im struct speichern? Nur ganz von hinten durch die Brust ins Auge. C kennt keine Bits. Du kannst Dir Pin-Macros anlegen, die werden dann im Code zu SBIS/SBIC expandiert. Oder Du legst eben alle Tasten auf den selben 8Bit-Port und wertest sie per Maskenbyte aus. Wenn die Tasten unbedingt über alle Ports verstreut sein müssen, kann man sie aber auch einmalig am Anfang der Entprellfunktion in einem virtuellen Byte zusammen fassen.
:
Bearbeitet durch User
Herbert schrieb: > In der while-schleife Herbert schrieb: > im timer ISR Was soll diese unglückliche Zweiteilung bewirken? Du erkaufst Dir damit nur den Nachteil, daß Tastendrücke verloren gehen, sobald die Mainloop mal etwas mehr zu tun hat. Besser ist es, den Timerinterrupt alles machen zu lassen und dem Main fertige Ereignisflags zur Verfügung zu stellen. Die können dann ausgewertet werden, auch wenn die Taste schon wieder losgelassen wurde.
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.