Wunderschönes Interrupt Problem

Es treibt mich seit 6 Stunden um…ohne Lösungsfortschritt…

Also:
Arduino Uno 328PU

Angeschlossen ist ein encoder mit encoder.h an Pin 2 und 3

Außerdem mehrere Taster von D4 bis D12

Der Prozessor wird, wenn nichts gedrückt wird, in den Sleep Modus geschickt.
Er wird dann mit Interrupts wieder geweckt.

Damit auch die Taster ihn wecken können, habe ich ein paar PinChangeInterrupts gesetzt.

Besonderheit dabei: diese werden in drei Hauptgruppen unterschiedlicher Priorität eingeteilt.
Die Taster an PCINT2 wecken den Prozessor immer und zuverlässig.
Die Taster an PCINT0 tun dies fast immer. Nur manchmal nicht. Dann muss ich einen der anderen PCINT2 Taster drücken, um PCINT0 “wirksam” zu machen.

Ich kann absolut keine Regel feststellen wann er vom D12 / also 0er Register nicht aufwacht. mal sinds die ersten drei, mal eine halbe Stunde gar kein Problem…völlig zufällig.

Übersehe ich da etwas hardwaretechnisch?

Das Problem scheint folgendes zu sein: Er reagiert nicht immer auf ein LOW Level, manchmal braucht er HIGH- LOW und wieder HIGH um die ISR auszuführen, manchmal jedoch nicht. Dies ist unabhängig vom Pin, der Fehler tritt an allen Eingängen auf..

Vielleicht das beachten (siehe Datenblatt)

Note that if a level triggered interrupt is used for wake-up from Power-down, the required level
must be held long enough for the MCU to complete the wake-up to trigger the level interrupt. If
the level disappears before the end of the Start-up Time, the MCU will still wake up, but no interrupt will be generated. The start-up time is defined by the SUT and CKSEL Fuses as described
in ”System Clock and Clock Options” on page 26.

Leider nicht.. das Problem ist da wenn ich den Eingang auf LOW liegen lasse. Sobald ich ihn von LOW trenne führt er den Interrupt aus..leider nur zu spät und zu kurz..

Er führt ihn auch aus wenn der Eingang auf LOW liegt und ich einen anderen Eingang kurz von HIGH auf LOW und wieder auf HIGH schalte.

Iregndwie scheint er nicht klar definiert zu haben auf welche Flanke bzw. Signalart er reagieren soll. Ich finde aber auch nirgends eine Anleitung wie ich das bei Pinchanges definiere.

Ich habe die ISR:
ISR (PCINT2_vect){ // 2 für D0 - D7

//analogWrite (A5,200);

if (digitalRead (4)==LOW){
d4 = 1 ;
}
}

Im Setup den Pinchange

PCMSK2 |=bit (PCINT16); //D0
PCMSK2 |=bit (PCINT20); //D4
PCMSK2 |=bit (PCINT21); //D5
PCMSK2 |=bit (PCINT22); //D6
PCMSK2 |=bit (PCINT23); //D7

PCIFR |=bit (PCIF2); //alle anderen Interrupts löschen
PCICR |=bit (PCIE2); //den PinChangeInterrupt enablen

Und nutze dann im LOOP eine switchcase Abfrage

switch (d4){
case 1:

etc.

Wo definiere ich denn RISING, FALLING, etc?

PinChange Interrupts reagieren auf beide Flanken. Das ist ein Grund weshalb sie so kompliziert sind. Die Flanken-Erkennung muss man per Hand machen:
http://www.kriwanek.de/arduino/grundlagen/182-pin-change-interrupts-grundlagen.html
http://www.kriwanek.de/arduino/grundlagen/183-mehrere-pin-change-interrupts-verwenden.html

Für den UNO und Mega gibt es auch die fertige PinChangeInt Library. Allerdings scheint GitHub im Moment nicht zu funktionieren

Wenn er das nur täte.. Manchmal reagiert er eben nicht auf beide Flanken.

Ein sehr schönes Tutorial! Danke