Forum: Mikrocontroller und Digitale Elektronik interrupt während delay?


von Herbert (Gast)


Lesenswert?

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?

von Bernhard R. (bernhard_r874)


Lesenswert?

Wenn die Interrupts während des delay aktiviert sind, wird diese 
unterbrochen.
delay braucht dann ggf. länger als die angegebene Zeit.

von Oliver S. (oliverso)


Lesenswert?

Das kommt alleine auf die delay-Funktion an. Radio Eriwan sagt: Kann 
sein, muß aber nicht.

Oliver

von TR.0LL (Gast)


Lesenswert?

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/

von Charly B. (charly)


Lesenswert?

das haengt von deinem prg bzw delay ab, ob dieser die Interrupts sperrt
in was hasste das programmiert?

VlG
Charly

von Einer K. (Gast)


Lesenswert?

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.

von Andreas B. (bitverdreher)


Lesenswert?

Delay, Taster &Interrupt.
Geil, ich hol schon mal Popkorn. Irgendwie scheint das in der 
Coronakrise jetzt das Dauerthema zu sein.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

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.

von Einer K. (Gast)


Lesenswert?

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.

von Herbert (Gast)


Lesenswert?

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.

von Einer K. (Gast)


Lesenswert?

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? !

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

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!

von Andreas B. (bitverdreher)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Herbert (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Warum gehst du den Weg nicht konsequent weiter? !

aber wie kann ich
(PIND & (1<<PIND4))
im struct speichern?

von Einer K. (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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
von Peter D. (peda)


Lesenswert?

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
Noch kein Account? Hier anmelden.