Forum: Mikrocontroller und Digitale Elektronik Debounce und Filter per PChg-Isr


von Michael Schurr (Gast)


Lesenswert?

Hier nochmal die Routine dazu:

In der Pchg_isr werden alle Pegelwechsel innerhalb einer Timerperiode
gesammelt und das jeweilige Bit in "Changed_pins_sum" gesetzt. Eine 1
bedeutet hierbei, dass sich dieses Bit verändert hat, nicht jedoch, dass 
sein Pegel 1 ist...!


In der Timer_Isr wird der letze PINB-Status nach "Deb_pinb" 
transferiert,
wobei das Byte in "Changed_pins_sum" die Maske liefert, für jene Bits 
(die
gekippten) die beim Übertrag nach "Deb_pinb" ausgelassen werden.

Kurz: 'Wd_isr' ist eine Transferroutine von Byte A nach Byte C, wobei 
das
Bitmuster im Masken-Byte B (hier das "Changed_pins_sum") bestimmt,
welche Bits im Zielbyte unverändert bleiben sollen.

Die gesamte Routine sollte somit geeignet sein, abhängig vom
Timerintervall, eine reproduzierbare Grenzfrequenz zu realisieren, indem 
sie die präzise erfassten Flankenwechsel die in kürzerer Periode als 
Tim_int eintreffen, nicht weiterleitet.
Die Codelaufzeit in Zusammenhang mit dem Systemtakt muss dabei natürlich
mit einbezogen werden.


'******************************************

.
Last_pins_state = Pinb
.
.
Do
.
Loop
.
.


'*********************
 Pchg_isr:

   1 Changed_pins = Last_pins_state Xor Pinb
   2 Last_pins_state = Pinb
   3 Changed_pins_sum = Changed_pins_sum Or Changed_pins

 Return

 '********************

  Wd_isr:

    4 If Changed_pins_sum = 0 Then

    5  Deb_pinb = Last_pins_state

    6 Else

    7  Deb_pinb = Deb_pinb And Changed_pins_sum
    8  Changed_pins_sum = Changed_pins_sum Xor &HFF
    9  Changed_pins_sum = Changed_pins_sum And Last_pins_state
   10  Deb_pinb = Deb_pinb Or Changed_pins_sum

   11  Changed_pins_sum = 0

   12  End If

  Return


' bei 8,9 u.10 wird "Changed_pins_sum" nur noch als Temp-Variable
'mißbraucht' bzw. 'recycled', ohne inhaltlichen Bezug zu ihrem 
anfänglichen Namen.

Mike

von Michael Schurr (Gast)


Lesenswert?

Was mich noch interessieren würde:

Kann man diese Art der Maskierung (Protektion der Zielbits mittels 
Maske) mit anderen Operationen schneller, und/oder kürzer realisieren..?

von Karl H. (kbuchegg)


Lesenswert?

Michael Schurr schrieb:
> Was mich noch interessieren würde:
>
> Kann man diese Art der Maskierung (Protektion der Zielbits mittels
> Maske) mit anderen Operationen schneller, und/oder kürzer realisieren..?

Nein.


Ok. In BASCOM vielleicht nicht, aber ein C-Compiler macht aus deinem 
Code

2 Ladeinstruktionen
2 And
1 XOR
1 Or
1 Speicherinstruktion

alles in allem 7 Taktzyklen, wovon 3 nicht optimierbar sind (Laden und 
Speichern)
Was willst du da noch groß optimieren?

Du optimierst an der falschen Stelle. Ob der Timer Interrupt jetzt 0.5 
Promille oder 0.5001 Promille der Rechenzeit braucht, ist sowas von 
Wurscht. Wenn dieser Unterschied in deinem Progamm einen Unterschied 
macht, dann hast du ganz andere Probleme.

Sorg lieber dafür, dass deine Tastendruck-Auswertung ordentlich 
benutzbar wird. Da hast du mehr davon. Denn bis jetzt hast du ja nur 
einen Tastenzustand aber noch keine Erkennung eines einzelnen 
Tastendrucks.

von Peter D. (peda)


Lesenswert?

Man muß auch berücksichtigen, daß jeder Interrupt ein Prolog/Epilog 
Gedöns braucht. Beim AVR-GCC gehen dafür allein gerne mal 30..40 Zyklen 
drauf.

Wenn also der ICP-Interrupt keinen großen Vorteil bringt, kostet er 
trotzdem zusätzlich.

von Michael Schurr (Gast)


Lesenswert?

Hi Kh,

nein das ist jetzt nicht akut relevant. Wollte nur generell von der 
Profiseite her wissen, ob es da elegantere und schnellere Lösungen gibt.


Und generell will man schon immer Zeit und Platz von vornherein sparen.

Nachher ist es immer etwas mühselig, wenn es klemmt. Vor allem sind 
knappe und sporadische Timingprobleme nicht Debugger's Lieblingshobby... 
;-)

von Karl H. (kbuchegg)


Lesenswert?

Michael Schurr schrieb:

> Und generell will man schon immer Zeit und Platz von vornherein sparen.

Ja das kenn ich.
Ich sitz auch an so einem Programm an dem ein einzelner 15 Jahre lang 
jegliche softwaretechnische Sorgfalt hat missen lassen und gnadenlos 
optimiert hat - Funktionsaufrufe kosten ja auch so viiieel Zeit.

Das Ergebnis vom Lied:
Er ist nicht mehr in der Firma und 5 Mann arbeiten seit ca 2 Jahren 
daran, wenigstens die gröbsten Softwaresünden und schlimmsten Bugs 
auszumerzen. Während nebenbei auch noch die Weiterentwicklung laufen 
soll.
Aber Hauptsache das Programm ist schnell .... manchmal sind die 
Ergebnisse zwar, sagen wir mal, kreativ aber die sind dafür dann auch 
schnell da.


Das Hauptaugenmerk eines Profis liegt auf wartbarem Code! Und nicht auf 
der Optimierung des letzten Taktzykluses. "Schnell genug" ist völlig 
ausreichend. Mehr braucht es nicht.

von Michael Schurr (Gast)


Lesenswert?

Hab die Routine nochmal optimiert, so daß jetzt auch bei Mehrfachprellen 
innerhalb des aktuellen Timerintervalls nur ein einziger Pchg-Int pro 
Eingang auftritt.

Eine weitere Optimierung (Code in Klammern) ist noch dadurch möglich, 
daß bei statischen (ruhigen) Eingängen, auch noch der Timer_Int 
deaktiviert wird, falls dieser nicht auch von anderen Routinen genutzt 
wird.

Die ganze Debounce-Routine ist somit bei ruhigen Eingängen total inaktiv 
und verbraucht keinerlei Zeit durch Prüfroutinen und Ints mit 
Push/Pop-Sequenzen. Sie wird nur bei einem neuerlichen Pegelwechsel für 
einen(!) Durchlauf aktiviert.


Das bedeutet maximale Treffsicherheit bei Erkennung von Prell-, oder 
Störimpulsen, bei maximaler Zeiteffizienz.

Die hier oft credomässig postulierte Behauptung, daß Pchg-Int bei der 
Tastenentprellung nichts zu suchen hat, ist so gesehen nicht 
überzeugend. Die Vorteile überwiegen bei Weitem, wenn es richtig 
umgesetzt ist. Selbst die Int-Aufrufe und die beanspruchte Gesamtzeit, 
liegen mit der jetzigen Implementierung hinter denen, die bei einer 
ununterbrochenen, zyklischen Pollingaktivität auch ohne jegliche 
Tastenaktivität verbraten werden.


....

'Init:
.
.
Pcmsk=&b00010111  'Pchg_Int_Maske
Pcmsk_copy = Pcmsk
Last_pins_state = Pinb

'Main:
.
do
...
loop
.

'ISRs:
'*********************
 Pchg_isr:

  (Set WDIE  => WDTimer_Int enablen)
  Changed_pins = Last_pins_state XOR Pinb
  Last_pins_state = Pinb
  Changed_pins_sum = Changed_pins_sum OR Changed_pins

  Stable_pins = Changed_pins_sum XOR &HFF
  Pcmsk = Pcmsk AND Stable_pins

 Return

 '*****************

  Wd_isr:

    If Changed_pins_sum = 0 Then
      Deb_pinb = Last_pins_state
      (Reset WDIE  => WDTimer_Int disablen)
    Else
      Deb_pinb = Deb_pinb AND Changed_pins_sum
      Stable_pins = Stable_pins AND Last_pins_state
      Deb_pinb = Deb_pinb OR Stable_pins
      Changed_pins_sum = 0
    End If

     Pcmsk = Pcmsk_copy

  Return

von Peter D. (peda)


Lesenswert?

Michael Schurr schrieb:
> bei maximaler Zeiteffizienz.

Ich glaube nicht, daß jemand das als wirklichen Vorteil sieht, wenn beim 
nicht Drücken die CPU-Last um 0,01% geringer ist, gegenüber der 
Timermethode.
Auf jeden Fall ist es nicht merkbar.

Auch braucht fast jede Anwendung einen Timer, um zeitliche Abläufe (RTC, 
Multiplex, Blinken usw.) zu realisieren.
Der Timerinterrupt läuft also eh immer und kann nicht gestoppt werden.

Effizienz ist nicht das Maximum eines Parameters, sondern das Optimum 
aller Parameter.

von Michael Schurr (Gast)


Lesenswert?

Moin moin...

Peter Dannegger schrieb:
> Ich glaube nicht, daß jemand das als wirklichen Vorteil sieht, wenn beim
> nicht Drücken die CPU-Last um 0,01% geringer ist, gegenüber der
> Timermethode.


Es geht doch hier ja gar nicht um den Kontrast zur Timermethode, sondern 
um die Gegenüberstellung der Int_getriggerten Eventmethode einerseits, 
zur stichprobenartig arbeitenden Pollingmethode andererseits. Letztere 
muss auch im eventlosen Zustand ständige Abfragen und 
Vergleichsoperationen ausführen, um überhaupt weiteren Handlungbedarf zu 
erkennen. Ausserdem kann das zyklische Polling generell, wie z.B. auch 
die Audiodigitalisierung, nur solche Dynamiken sicher detektieren, die 
unterhalb der halben Pollingfrequenz liegen.


Eine Routine, die zufällig x-mal denselben Pegel detektieren und als 
"statisch" erklären kann, während das Signal ausserhalb der Stichproben 
quasi Narrenfreiheit besitzt, ist ja nicht als mathematisch/logisch 
eindeutige Methode und damit als verlässlich zu bezeichnen. Aber genau 
das will man doch bei jeder Art der sauberen Programmierung erreichen, 
daß das Prozedurverhalten eindeutige und vor allem reproduzierbare(...) 
Ergebnisse generiert.
Das ist auch im Hinblick auf Wartbarkeit und Verwendbarkeit als Modul, 
ein starkes Argument. Ich sehe Zuverlässigkeit und Reproduzierbarkeit 
eines detektierten Zustandes, als eines der prioritären Prinzipien an 
und damit auch als Code-Effizienz im übergeordneten Sinne.
Vor allem kann Code der reproduzierbar verlässlichen Output liefert, auf 
andere Einsatzgebiete portiert werden, gerade wenn es dort auch auf 
kompromisslose Zuverlässigkeit ankommt.



Der wirklich effizienzgewinnende Teil der letzten Änderung, ist ja die 
Begrenzung des Pchg_int auf das erste Ereignis. Das bewirkt, daß z.B. 
auch stark prellende Kontakte nur einen  einzigen Int samt 
push/pop-Overhead pro Timerzyklus erzeugen. Die 'ruhigen', stabilen 
Eingangskonstellationen verbrauchen, wie gehabt, nach dem zweiten 
Timerzyklus ohnehin gar keine Prozesszeit mehr.

Ob nun der Timerinterrupt mit seinen 0,01% dazu auch noch wegfällt oder 
nicht, habe ich ja auch nur als Option in Klammern dargestellt, die man 
noch reinnehmen kann um damit eine 'puristisch reine', eventgetriggerte 
Prozedur zu erreichen, die ohne akuten Event garnicht mehr in 
Erscheinung tritt.

von Hagen R. (hagen)


Lesenswert?

Michael Schurr schrieb:
> Eine Routine, die zufällig x-mal denselben Pegel detektieren und als
> "statisch" erklären kann, während das Signal ausserhalb der Stichproben
> quasi Narrenfreiheit besitzt, ist ja nicht als mathematisch/logisch
> eindeutige Methode und damit als verlässlich zu bezeichnen.

Doch kann man denn das hängt ausschließlich von den Rahmenbedingungen 
ab. Indirekt ewähntest du schon das Nyquist Theorem das exakt diese 
Grenze mathematisch formuliert. Alle externen Eregnisse die unterhalb 
dieser Grenze ablaufen können auch mit einem Sampling das oberhalb 
dieser Grenze liegt eindeutig sauber erfasst werden. Die Notwendigkeit 
für ein Ereignisbasiertes System entfällt bzw. es stellen sich die 
gleichen Verhältnisse dazu bei einem Sampling ein.

So bleibt also nur das Argument des Aufwandes, des Resourcenverbrauches. 
Und da sieht es eben so aus das für Tasterabfragen wirklich nur eine 
Verbesserung von Subprozentpunkten den Unterschied machen.

von Hagen R. (hagen)


Lesenswert?

Michael Schurr schrieb:
> Der wirklich effizienzgewinnende Teil der letzten Änderung, ist ja die
> Begrenzung des Pchg_int auf das erste Ereignis. Das bewirkt, daß z.B.
> auch stark prellende Kontakte nur einen  einzigen Int samt
> push/pop-Overhead pro Timerzyklus erzeugen. Die 'ruhigen', stabilen
> Eingangskonstellationen verbrauchen, wie gehabt, nach dem zweiten
> Timerzyklus ohnehin gar keine Prozesszeit mehr.

Exkat dieser Teil deiner Argumentation kann man auch als negativ 
bewerten. Wir wissen das ein gültiges Tasterereignis im Frequenzbereich 
< 100Hz liegt. Wir wissen auch das Störungen teilweise im 
Frequenzbereich weit oberhalb von x kHz liegen können. Zudem wissen wir 
das der PinChange mit Clock_CPU/4 maximaler Frequenz arbeiten kann. Das 
hochfrequente Prellen des Tasters wird also dazu führen das 
überproportional viele Resourcen in der PinChange ISR verschwendet 
werden die keinerlei zielführende Resultate bringen werden. Benutzt man 
einen Timer mit einer Frequenz von zB. 200Hz dann reduziert man also auf 
Grund des Nyquist Theorems diese hochfrequenten Störungen und damit den 
unnützen Verbrauch von Rechenzeit. Gleichzeitigt bleiben aber die 
erreichbare Genauigkeit beider Verfahren erhalten, beide Verfahren sind 
also zur Erreichung des Zieles identisch exakt.

von Hagen R. (hagen)


Lesenswert?

Denoch gibt es Anwendungsfälle bei denen deine PinChange Methode 
überlegen ist. Wenn man zb. einen Timestamp mit viel höherer Auflösung 
als die 100Hz Auslöserate des Tasters diesem Event zuordnen muß. Dann 
müsste man mit der Timer Methode diesen Timer mit wensentlich höherer 
Frequenz laufen lassen. Und ab einem gewissen BreakEven Point wird die 
PinChange Methode die Timer Polling/Sampling Methode outperformen.

von Michael Schurr (Gast)


Lesenswert?

Hagen Re schrieb:
> Das
> hochfrequente Prellen des Tasters wird also dazu führen das
> überproportional viele Resourcen in der PinChange ISR verschwendet
> werden

Nein, wird es nicht, wie sich aus meinem Text (und auch aus dem Code) 
ersehen lässt.

Da du meine Texte und die Funktion des Codes offensichtlich nicht zur 
Grundlage deiner Überlegungen nimmst, können wir auf weitere 
Spekulationen dieser Art und unfundierte Behauptungen verzichten...

Wenn ich statt neue Wege und Tatsachen zu analysieren, lieber 
Glaubensdinge und Dogmen erörtern möchte, gehe ich in einschlägige 
Foren... ;-)

von Hagen R. (hagen)


Lesenswert?

Um es nochmal anders zu betrachten:

Die Timer Methode impliziert einen digitalen Filter auf Grund des 
Abtasttheorems (Nyquist). Diesen Filter hat man inklusive ohne 
zusätzliche Resourcen.

Die PinChange Methode benötigt die Resource PinChange ISR und ebenso 
einen Timer oder zus. softwarebasierte Filter um die gleiche 
Effektivität zu erreichen.

Der Rsourcenverbrauch ist also höher da man nicht nur die CPU Zeit als 
Resource betrachten darf sondern auch die benutzten Features der CPU. 
Dazu kommt als Resource noch der Hirnschmalz den man investieren muß und 
die erreichbare Stabilität aus Sicht des Zieles und der Vermeidung von 
Störungen.

Im Falle einer einfachen Tasterabfrage meine ich das die Timermethode 
die simpelste und gleichermaßen effektivste Methode ist, weil sie nach 
folgenden Regeln arbeitet:

- keep it simple
- programmiere das Nötige mit dem minimalsten Aufwand
- benutzte aus zwei Methoden diejenige die die geringste Komplexität hat

von Thomas E. (thomase)


Lesenswert?

Michael Schurr schrieb:
> Wenn ich statt neue Wege und Tatsachen zu analysieren,
Glaubst du wirklich, einen neuen Ansatz gefunden zu haben, der die 
Tastenabfrage jetzt revolutionär besser macht?
Das Thema Tastenabfrage, auf den ersten Blick logischerweise, über 
Interrupts zu machen, taucht hier wöchentlich auf.
Einfach nur langweilig.

mfg.

von Hagen R. (hagen)


Lesenswert?

Michael Schurr schrieb:
> Nein, wird es nicht, wie sich aus meinem Text (und auch aus dem Code)
> ersehen lässt.
>
> Da du meine Texte und die Funktion des Codes offensichtlich nicht zur
> Grundlage deiner Überlegungen nimmst, können wir auf weitere
> Spekulationen dieser Art und unfundierte Behauptungen verzichten...

Ich habe deine Argumentation sehr genau gelesen und möchte hier auf 
deinen Hinweis auch eingehen.

Wenn das Prellen so schnell ist das es die Ausführungszeit der PinChange 
ISR überholt, also die Hardware Grenze von CPU_Clock/4 überschreitet 
(was immerhin auf AVRs ca. 2Mhz sind) dann filtert quasi die Hardware 
für dich. Wenn das Prellen langsammer ist aber immer noch schneller als 
die Ausführungszeiten deiner PinChange ISR dann führt dies dazu das 
sofort nach Abarbeitung dieser ISR diese ISR wiederum aufgerufen wird. 
Denn das Interruptflag wird erneut gesetzt. Angenommen deine PinChange 
ISR kann nur mit maximal 100KHz arbeiten und der Taster prellt für 10ms 
mit 500kHz, dann würde deine PinChange ISR die komplette CPU Zeit für 
diese 10ms verbrauchen. Das kann mit einer Timer ISR nicht passieren da 
diese eben nur mit 5ms Interval arbeitet.

Und dieses Verhalten wird durch den Entwickler provoziert ohne jeglichen 
Gewinn, denn das Ziel lautete: ein Taster der max. mit 100Hz betätigt 
werden kann soll so ausgelesen werden das man keine der 100Hz 
Betätigungen vermisst. Und da besagt das Nyquist Theorem ganz klar: 
lasse den Timer mit 200Hz laufen um dieses Ziel mathmeatisch beweisbar 
erreichen zu können.

Das Problem mit der PinChange ISR ist es also das sie gerade auf jedes 
Ereignis des Tasters sofort reagiert obwohl dies kontraproduktiv sein 
muß.

Wir wissen das mit 100Hz ein Tasterevent kommt und davor aber x'male 
mit >> 100Hz ein Prellen. Wir sind am Tasterevent interessiert und nicht 
am Prellen. Wir möchten die Resourcen schonen und nur auf das reagieren 
was relevant ist. Die PinChange Methode kann also nicht das leisten was 
die Timer Methode in diesem Fall leistet.

Timer Methode benötigt einen langsammen Timer der oft sowieso schon 
benutzt wird. PinChange benötigt den PinChange und entweder einen Timer 
zusätzlich oder eine aufwnedigere Softwarefilterung. Beide leisten am 
Ende das gleiche. Der Verbrauch an vorhandenen Resourcen ist also bei 
der PinChange Methode höher. Gleiches gilt für die Komplexität der 
Verfahren.

von Peter D. (peda)


Lesenswert?

Michael Schurr schrieb:
> Da du meine Texte und die Funktion des Codes offensichtlich nicht zur
> Grundlage deiner Überlegungen nimmst

Vielleicht ging es ihm nur so wie mir, ich verstehe nicht, wie Dein Code 
entprellen soll. Er enthält ja auch keinerlei Kommentare.

Wie ich das verstehe, wird beim ersten Pin-Change Interrupt der 
Pin-Zustand eingelesen und weitere Interrupts für diesen Pin gesperrt.

Und nach einer Wartezeit wird dann der gespeicherte Zustand übernommen 
und Pin-Change wieder freigegeben. Der Pin kann zwischenzeitlich wieder 
eine völlig anderen Zustand haben, es kann auch nur ne Störnadel gewesen 
sein.

Das entspricht also in der Funktion dem Klassiker:
Externer Interrupt + Delay.

P.S.:
Den PinB im Pin-Change-Interrupt zweimal einzulesen, heißt nicht, daß 
diese Werte auch identisch sind. Externe Ereignisse sind asynchron.
Da sollte man also eine Zwischenvariable benutzen.

von Hagen R. (hagen)


Lesenswert?

Peter Dannegger schrieb:
> Michael Schurr schrieb:
>> Da du meine Texte und die Funktion des Codes offensichtlich nicht zur
>> Grundlage deiner Überlegungen nimmst
>
> Vielleicht ging es ihm nur so wie mir, ich verstehe nicht, wie Dein Code
> entprellen soll. Er enthält ja auch keinerlei Kommentare.

Nein so ging es mir eigentlich nicht. Ich braucht nicht seinen Code zu 
verstehen um zu meinen Schlußfolgerungen zu kommen.

Es gibt mehrere Wege:

1. er benutzt nur den PinChange:

Vorteil: nur eine Resource benutzt, identisch zur Timer Methode.
Nachteil: bekommt dann Probleme mit dem Prellen und muß per Sofwtare 
aufwendig filtern.

2. er benutzt den PinChange als Intialzünder, deaktiviert diese ISR und 
benutzt dazu einen Timer:

Vorteil: statt nun mit 200Hz Abtastrate arbeiten zu müssen wie bei der 
Timer Methode hat er diese Abtastfrequenz auf 100Hz reduziert. Die 
Timermethode muß also minimal doppelt so häufig nachschauen wie seine 
Methode. Da aber Software für seine PinChange ISR + Timer ISR 
programmiert werden muß verbraucht er doppelt soviele Resourcen in 
diesem Bereich.

Nachteil: er benutzt 2 Hardware Resourcen statt eine wie bei der Timer 
Methode.

Egal wie man es also dreht und wendet: die PinChange Methode ist 
ineffektiver, sowohl beim Resourcenverbrauch wie auch bei der 
Komplexität, wenn man die selbe Zielsetzung annimmt.

Ich sehe da nur einen Denkfehler: das Unverständis zum Abtasttheorem.

von Hagen R. (hagen)


Lesenswert?

Peter Dannegger schrieb:
> P.S.:
> Den PinB im Pin-Change-Interrupt zweimal einzulesen, heißt nicht, daß
> diese Werte auch identisch sind. Externe Ereignisse sind asynchron.
> Da sollte man also eine Zwischenvariable benutzen.

Und das sind dann die versteckten Probleme die die Sache eben komplexer 
machen im Vergleich zur simplen Sampling Methode nach Nyquist = Timer 
Methode.

von Hagen R. (hagen)


Lesenswert?

Wenn es um die Probleme deim Abtasten von anaolgen Werten per ADC geht 
(Nyquist) ist das Verständnis der Entwickler vorhanden. Die Frage die 
sich nun stellt ist warum manche Entwickler dieses Wissen nicht anwenden 
können auf andere Probleme. Und eine Tasterabfrage ist so ein Problem.

Oder ist es wirklich sinnvoll einen analogen Wert am ADC so abzutasten 
das wenn sich dieser Wert ändert sofort eine ansynchrone Abarbeitung per 
"ADC_Change-ISR" anzustoßen und das dann auf den Zeitbereich per 
zusätzlichen Filterungen (Timer, Delays etc.pp) wieder zu linearisieren 
?

von Michael Schurr (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Glaubst du wirklich, einen neuen Ansatz gefunden zu haben, der die
> Tastenabfrage jetzt revolutionär besser macht?
> Das Thema Tastenabfrage, auf den ersten Blick logischerweise, über
> Interrupts zu machen, taucht hier wöchentlich auf.
> Einfach nur langweilig.

...tsts... auf Beiträge die mich langweilen gehe ich in der Regel erst 
gar nicht ein... von daher: Danke, für die Mühe... ;-)

Ich habe das Thema "Tastenabfrage mit Interrupts" eben nicht nur mit dem 
ersten Blick euphorisiert, sondern seine Nachteile, die auftreten wenn 
man den Pchg-Int unreflektiert benutzt, gesehen und dann ausgeschaltet. 
Daß es mich "revolutionär" dünkt, hast du stichelig ins Feld geworfen... 
wirst wohl emotionalen Grund dazu haben...

'***************


@ Hagen...

Alles Argumente, die nicht wirklich greifen im vorliegenden Fall. 
Während das Polling ständig am werkeln ist, wacht meine Routine nur bei 
einem realen PChg-Event auf und benötigt genau max. 1 PChg-Int pro 
Zeitfenster und instabilem Eingang. Und die Pchg-Routine ist nun 
wirklich minimalistisch und präzise zugleich.

Ich brauche keine 100Hz Abtastfrequenz, welche die ganze Zeit pollt, 
testet und prüft... ich brauche den 100Hz Takt Pchg-getriggert genau 2 
mal um einen Change abzuarbeiten, danach ist Ruhe. Auch dann, wenn der 
unruhige Pin innerhalb dieser Periode noch x-mal weiterbounct!


Es scheint hier mehr um das Dogma:

"Entprellung und Interrupt ist Resourcenverschwendung und generell 
tabu..!!"

zu gehen, ohne sich damit zu befassen, dass es mit der richtigen 
Implementierung nur Vorteile bringt. Und zwar in sachen Präzision, wie 
auch Timing. Nur verstehn muss halt, was hier gemacht wurde und wie der 
Code arbeitet. Sonst bleiben die meisten 'Kritiken' einfach nur 
Unkenrufe.

Auch Peter D.s Image als Board-Koryphäe und seine unbestritten enormen 
Fach-Fähigkeiten, werden durch eine Alternativlösung keineswegs in Frage 
gestellt. Aber es bedeutet auch nicht zwingend, dass von solcher Seite 
deswegen stets nur die ultimativen Non-plus-Ultra-Lösungen kommen, die 
als unantastbar, unverbesserbar, oder gar alternativlos zu respektieren 
sind. Hier scheint es mir diesbezüglich viele "eifrige Jünger" zu geben, 
die meinen, ihren Guru beschützen zu müssen, statt unvoreingenommen und 
offen fü anderes zu sein.


Stichhaltige Gegenargumente, die das codetechnische Verhalten obiger 
Routine richtig erfassen, habe ich hier jedenfalls noch keine gesehen. 
Von den Bugs im Anfangsstadium und der diesbezüglich berechtigten, 
konstruktiven Kritik mal abgesehen.

Nein, ich halte mich weder für einen Revoluzzer, noch für einen 
Entdecker einer "grossen" Sache. Einen gewissen Perfektionismus mit 
einfachen Mitteln zu Realisieren, macht mir einfach Spass... wenn's dann 
endlich funzt. Das bedeutet für mich dann Effizienz.

Mike

von Hagen R. (hagen)


Lesenswert?

Michael Schurr schrieb:
> @ Hagen...
>
> Alles Argumente, die nicht wirklich greifen im vorliegenden Fall.

Ok dann liefere ich dir eines:

Implementiere deine Methode mit 4 Tastern + 4 andere Signalleitung die 
den PinChange zwingend benötigen.

1. du wirst Probleme bekommen einen AVR so mit PinChange zu 
programmieren das du innerhalb der PinChange ISR, die ja für den ganzen 
Port gilt, zu erkennen welcher Pin nun einen PinChange ausgelösst hat.

2. du wirst Probleme bekommen bei 4 Tastern das nachfolgende Timer 
Timing einzuhalten, der Aufwand steigt proportional da du ja nun für 
jedes Event einen eigenen Timerwert pflegen musst. Du hast dann zwei 
Möglichkeiten: defakto 4 Timer zu benutzten oder einen Timer mit festem 
aber nun viel höherem Interval als 100Hz um 4 Zähler für die Events 
programmieren zu können. Gerade letzteres führt zur Frage: warum dann 
nicht gleich mit nur einem Timer sampeln ? der dann sogar wieder 
langsammer laufen kann = 200Hz.

Bei der Timer Methode tastet man alle 4 Taster im gleichen Interval ab, 
also synchron zueinander innerhalb einer einzigen Routine und sogar 
Variablen.

Ich habe da so eine Design-Regel in meiner Arbeit als Entwickler: wenn 
eine gewählte Methode ohne Probleme höherwertige Probleme genauso gut 
erschlagen kann dann ist diese Methode besser als eine andere Methode 
die dann erst richtig Probleme verursacht. Und ausgehend von einem 
Taster auf zB. 4 Taster ist es eben so das die Timer Sampling Methode 
enorm einfach anzupassen ist und mit gleicher Effektivität nun ein 
komplexeres Problem lösen kann.

Über das Abtasttheorem und dessen Konsequenzen müssen wir ja nicht mehr 
diskutieren. Wir wissen ja das die Sampling Methode nur doppelt so oft 
aufgerufen werden muß wie das zu erwartende Ereignis auftreten kann. 
Wenn dieses Theorem nicht verletzt wurde dann unterscheiden sich beide 
Methoden von der Zielsetzung nicht mehr. Dh. die Exaktheit und 
Genauigkeit ist die gleiche bei beiden Verfahren. Du musst also uns 
beweisen das deine Methode einen entscheidenden Vorteil gegenüber der 
Timer Methode hat. Und da sehe ich eben keine logisch vernünftigen 
Argumente deinerseits.

Ich entwickele mein Wissen also nicht nur ausgehend von einem konkreten 
gegenwätigen Problem sondern immer in Hinblick darauf das sich ähnliche 
Probleme auch in Zukunft stellen werden. Somit verfolge ich immer auch 
das Ziel eine Problemlösung wiederverwenden zu können.

Mike, ich diskutiere hier mit dir nur aus einem Grund heraus: nicht weil 
ich deine Sichtweise diskreditieren möchte noch deine Ideen herabsetzen 
möchte, sondern um dir meine Sichtweise und die logischen Gründe dafür 
näher zu bringen. Letzendlich sehe ich in deinen Argumenten exakt die 
Denkfehler die ich damals als Anfänger gemacht habe.

PS: ich rede hier immer von Effektivität und nicht Effizienz und das aus 
gutem Grund. Denn es geht hier nicht nur um die Betrachtung welche 
Resourcen wir im AVR haben und verbrauchen sondern auch um den Effekt 
den die eigenen Entwicklungsarbeit für uns hat. Und da meine ich eben 
das die Sampling Methode per Timer die höhere Effektivität hat.

von Hagen R. (hagen)


Lesenswert?

Michael Schurr schrieb:
> Stichhaltige Gegenargumente, die das codetechnische Verhalten obiger
> Routine richtig erfassen, habe ich hier jedenfalls noch keine gesehen.
> Von den Bugs im Anfangsstadium und der diesbezüglich berechtigten,
> konstruktiven Kritik mal abgesehen.

Ich habe keine, wie du so schön schreibst, stichhaltigen Gegenargumente 
zu deinem Sourcecode. Es gibt auch keine da du sauber entwickelt hast. 
Man kann es so machen.

Mein Gegenargument ist das du am Thema der Zielstzung vorbei entwickelt 
hast und es einfacher geht bei gleicher Exaktheit der Resultate und 
annähernd vergleichbarer CPU Auslastung. Die anderen Resourcen die deine 
Methode benötigt disqualifiziert sie aber zur Sampling Methode. Die 
Einsetzbarkeit auf nur ein spezielles Problem im Vergleich zur 
Erweiterbarkeit der Sampling Methode disqualifiziert sie ebenfalls.

Ich weiß das du das anders siehst ;)

von M. N. (Gast)


Lesenswert?

Wie man es macht, hängt doch davon ab, wieviele Taster/Schalter zu 
verarbeiten sind und wie schnell reagiert werden muß.
Bei einer Tastenmatrix reichen zum einen die Eingänge des Controllers 
nicht aus, und zum anderen ist für die Dekodierung sowieso einige Zeit 
nötig, während der aber keine Interrupts blockiert werden müssen. Da 
gibt es keine Alternative zur zyklischen Abfrage in einer Timer-ISR.
Hier ist PCINT auf verlorenem Posten.

PCINT bietet sich bei einem oder nur wenigen Tastern an, oder wenn auf 
Impulse von z. B. Reedrelais' schnell reagiert werden soll. Dabei ist 
eine Filterung mit ext. RC-Glied einem 'Software-Filter' vorzuziehen, da 
der integrierte Impuls nicht mehr zwischen GND und VCC wackelt, sondern 
um ein Maß, was deutlich unter der Hysterese eines Eingangs (beim AVR) 
liegt.
Eine RC-Filterung schützt den Eingang zudem vor zu schneller 
Interruptfolge und in gewissen Rahmen auch vor ext. Überspannung, wenn 
der Taster räumlich entfernt angeordnet ist.
Anfang der Woche hatte ich dazu etwas in der Codesammlung geschrieben 
und auch den Kurvenverlauf für einen typischen Eingabetaster (Digitast) 
gezeigt.
"EIN-AUS mit Taster per Interrupt"

von Hagen R. (hagen)


Lesenswert?

hm gerade auch bei Reedrelais würde ich eher das Sampling benutzen. Es 
gillt in jedem fall das das Prellen höherfrequenter ist als das 
eigentliche Eregnis. Ergo muß man nur die Samplingfrequenz korrekt 
anpassen und filtert so ohne externen Aufwand und ohne weiteren internen 
Aufwand automatisch.

Nur wenn wir einen Timestamp dem Event zuordnen müssen der selber eine 
viel größere Auflösung hat als die Auslösegeschwindigkeit des Ereignises 
muß man ereignisbasiert arbeiten.
Nur wenn wie in Echtzeit, auch eine Definitionssache, darauf reagieren 
müssen lohnt sich ereignisbasiert zu arbeiten.
Nur wenn die Synchronität bei der Auswertung mehrer Ereignisse 
kontraproduktiv wird, also die Asynchronität zwischen den Ereignissen 
für uns wichtig ist, müssen wir ereignisbasiert arbeiten.

Und wenn wir mal konsequent zu Ende denken dann gilt: wir arbeiten in 
einer CPU immer nach dem Sampling Verfahren denn auch die CPU arbeitet 
nur Taktbasiert, ergo beträgt die maximale Samplingfrequenz aller 
Ereignisse auf die die CPU reagieren kann auch nur die der Taktfrequenz 
der CPU.

von Michael Schurr (Gast)


Lesenswert?

Hagen Re schrieb:
> 1. du wirst Probleme bekommen einen AVR so mit PinChange zu
> programmieren das du innerhalb der PinChange ISR, die ja für den ganzen
> Port gilt, zu erkennen welcher Pin nun einen PinChange ausgelösst hat.

Nein, werde ich nicht, weil genau diese differenzierte Erkennung in der 
PChg-Isr ohnehin gemacht wird und zudem nur jene Eingange als Auslöser 
in Frage kommen, die im PMSK aktiviert sind..
Ich brauch nur das Changed_Pins Byte auswerten... das enthält genau 
jenen Eingang als eine "1", der den Int getriggert hat. Alle andern sind 
Zero.



Hagen Re schrieb:
> 2. du wirst Probleme bekommen bei 4 Tastern das nachfolgende Timer
> Timing einzuhalten, der Aufwand steigt proportional da du ja nun für
> jedes Event einen eigenen Timerwert pflegen musst.

Auch das ist grottenfalsch... :-)

In der PChg_Isr werden alle (per PCMSK aktivierten) Bits in der Breite 
des gesamten Ports per Ver-ODER-ung gesammelt und dann mit dem Timer_Int 
als Bytewert in einem Rutsch und mit Hilfe von Bitmanipulationen, 
gemeinsam ausgewertet und prozessiert. Nix "4 Timerwerte pflegen" und 
son Zeug...!

Alle Change-Events parallel 'sammeln', byteweise verarbeiten, das 
Ausgangsbyte mit den "ruhigen" Bits updaten und jene Bits die sich 
verändert haben, beobachten, bis sie innerhalb einer Timerperiode 
unverändert waren... dann auch diese im Ausgangsbyte updaten... fertig.


Hagen Re schrieb:
> nicht weil
> ich deine Sichtweise diskreditieren möchte noch deine Ideen herabsetzen
> möchte, sondern um dir meine Sichtweise und die logischen Gründe dafür
> näher zu bringen.


Sorry, aber sowohl deine Sichtweise, als auch deine "logischen Gründe" 
sind in Bezug auf meine Routine total unlogisch und unzutreffend...

Wenn du nun bitte eine argumentative Denkpause anfügen könntest, anstatt 
ohne wirkliche Kenntnis des Codeablaufen munter weiter ins Blaue zu 
spekulieren, wäre ich dir sehr verbunden... ohne sich wirklich Mühe zu 
machen etwas zu verstehen, geht es nämlich vom sachlichen Kritikanspruch 
schnell in Richtung Diskreditierung. Und das steht dir ja ferne... ;-)

Mike

von Hagen R. (hagen)


Lesenswert?

Michael Schurr schrieb:
> In der PChg_Isr werden alle (per PCMSK aktivierten) Bits in der Breite
> des gesamten Ports per Ver-ODER-ung gesammelt und dann mit dem Timer_Int
> als Bytewert in einem Rutsch und mit Hilfe von Bitmanipulationen,
> gemeinsam ausgewertet und prozessiert. Nix "4 Timerwerte pflegen" und
> son Zeug...!
>
> Alle Change-Events parallel 'sammeln', byteweise verarbeiten, das
> Ausgangsbyte mit den "ruhigen" Bits updaten und jene Bits die sich
> verändert haben, beobachten, bis sie innerhalb einer Timerperiode
> unverändert waren... dann auch diese im Ausgangsbyte updaten... fertig.

Na da haben wirs doch !

1. du wertest mit dem gleichen Timer Interval alle PinChange's aus. Das 
Argument das du gezielt auf einen Taster umgehend reagieren kannst gilt 
also nicht mehr da du nur noch in einem festen Interval auf mehrere 
Changes reagieren kannst. Somit ist dies identisch zum Abtasten.

2. du kannst nicht innerhalb der PinChange ISR herausfinden welcher 
maskierte Pin die ISR ausgelöst hat. Das geht nicht weil der AVR dafür 
keine Hardware Unterstützung anbietet. Die einzige Möglichkeit ist es 
den Pinzustand auszulesen und mit einem zwischengespeicherten zu 
vergleichen. Dies muß in Relation zur nachfolgenden Timer Auswertung in 
einer separaten Variablen erfolgen. Beim Sampling entfällt diese 
Variable.

3. du verbrauchst zwei Resourcen: PinChange und Timer.

Der einzige Vorteil aus Sicht der CPU Zeit den ich sehe ist das deine 
Methode nur dann aktiv wird wenn Taster gedrückt/losgelassen werden. 
Dies ist unbestritten ein Vorteil aus Sicht der CPU Zeitauslastung wenn 
man es in absoluten Zahlen fast. Aber, lohnt sich diese Komplexität, 
dieser Resourcenverbrauch an 2 HW-Resourcen + FLASH Speicher für den 
komplexeren Code in Relation zu den ca. 20 Opcodes die alle 200Hz in 
einer Timer Routine beim Sampling benötigt werden ? Ich denke nicht.

Alle anderen propagierten Vorteile: wie Exaktheit, Komplexität usw. habe 
ich oben schon widerlegt.

von M. N. (Gast)


Lesenswert?

Hagen Re schrieb:
> Ergo muß man nur die Samplingfrequenz korrekt
> anpassen und filtert so ohne externen Aufwand und ohne weiteren internen
> Aufwand automatisch.

Na da spendiere ich meiner Schaltung doch lieber 10k + 10nF als Filter, 
als mit 1-10kHz Dauerlauf auf Verdacht abzutasten.
Je kleiner das Reedrelais, umso schneller kann es schalten.

von Michael Schurr (Gast)


Lesenswert?

Michael Schurr schrieb:
> beobachten, bis sie innerhalb einer Timerperiode
> unverändert waren...

Ooops...das ist natürlich selbstgemachter Humbug... die Changed_Pins 
brauchen natürlich nicht "beobachtet" zu werden, sondern werden 
automatisch upgedatet, sobald sie eine Timerperiode lang stabil waren...

von Hagen R. (hagen)


Lesenswert?

Michael Schurr schrieb:
> sobald sie eine Timerperiode lang stabil waren...

Dies ist die entscheidende Passage: das Abtasttheorem besagt exakt das 
Gleiche wenn man mit doppelter Frequenz zur Eventfrequenz abtastet.

Du machst also im Extremfall folgendes:
Alle 100Hz kommt ein PinChange und mit einem 200Hz Timer tastest du 
nochmal ein zweites mal ab.

Die Sampling Mehtode macht folgendes:
Alle 200Hz taste ab und vergleiche mit dem vorherigen Zustand = 100Hz.

In beiden Fällen kommt exakt das Gleiche heraus.

Nur wenn der Taster nicht mehr alle 100Hz gedrückt wird ändert sich 
zugunsten deiner Methode der Verauch an CPU Zeit.
Wird der Taster schneller als 100Hz gedrückt machen beide Methoden einen 
Fehler.

Stellt sich nun die Frage: welche Mehtode ist insgesamt effektiver ?

Die Timer Methode:
- simpel
- ausbaufähig
- weniger HW-Resourcen
- geringere Komplexität
- dadurch weniger fehlerträchtig

Die PCINT Methode:
- weniger Rechenleistung wenn sich nichts am Taster verändert

Alle 200Hz werden 20 OpCodes beim Sampling benötigt. Bei 8MHz Takt sind 
dies 0,05% der Rechenleistung.

Das wars mit den Vorteilen.

von Hagen R. (hagen)


Lesenswert?

Mike, du musst es doch mal so betrachten. Dein Ziel hier deine Methode 
vorzustellen, und damit der Nutzwert für die Leute die ihn anwenden 
wollen, besteht doch darin sie in ein weiterführendes Projekt 
einzubauen. Damit muß letzendlich die Betrachtungsweise der Effizienz zu 
einer Betrachtungsweise der Effektivität werden. Denn nur deinen 
Sourcecode als einzigem Bestandteil eines Programmes zu betrachten ist 
widersinnig. Denn erstens erledigt sich dann das Thema Effizenz da man 
ausreichend Resourcen zur Verfügung hat. Zweitens ist eine solche 
Effizienzbewertung im Vergleich zu anderen Methoden hinfällig. Ergo: 
stellt sich die Frage mit welchen Minimal-Mitteln kann das Ziel erreicht 
werden da man ja annehmen muß das die Resourcen in einer größeren 
Anwendung immer knapper werden, oder eben bestimmte Resourcen eh schon 
vorhanden und benutzt werden (wie eben ein Timer). Gleichermaßen muß man 
dann hinterfragen welche Seiteneffekte wird es haben wenn ich bestimmt 
Resourcen blockiere für die spätere Anwendung.

So jedenfalls ist meine Sicht auf diesen Thread und daraus resultiert 
auch meine Wertung.

Gruß Hagen

von M. N. (Gast)


Angehängte Dateien:

Lesenswert?

Hagen Re schrieb:
> Wird der Taster schneller als 100Hz gedrückt machen beide Methoden einen
> Fehler.

Das muß nicht so sein. Durch schnelles Anschlagen eines Tasters wird ein 
kurzer Impuls erzeugt, der per PCINT schnell und zuverlässig erkannt 
wird: siehe Bild.
Nach ca. 2ms ist der Kontakt erkannt und nach ca. 4ms wieder auf 
Ruhepegel. Soll sich jeder selber sein Urteil bilden.

von Michael Schurr (Gast)


Lesenswert?

Hagen Re schrieb:
> Du machst also im Extremfall folgendes:
> Alle 100Hz kommt ein PinChange und mit einem 200Hz Timer tastest du
> nochmal ein zweites mal ab.

Hallo "Mr. Abtasttheorem", ...selten sowas von lernresistent und daneben 
bei einer "Analyse" gelesen.. Daß der PChg_int nur auslöst, wenn auch 
ein solcher Event auftritt, ist dir aber schon klar? Daß er nur 1mal 
gebraucht wird und daher der entsprechende Eingangspin für den Rest des 
laufenden Timerintervalls aus dem PChg ausmaskiert wird, ist dir auch 
klar?
Nein, sicher nicht... war nur rhetorisch.

Da kommt eben nicht dasselbe raus, schon alleine dewegen, weil der 
PChg-Int jeden(!) kurzen Flankenwechsel erfasst, während das Pollen nur 
zufällig im Nebel stochert, um einen Pegelwert zu erfassen. Wenn da 
wenige µs voerher oder nachher ein Flankenwechsel war, merkt die 
Pollingroutine nix davon und gibt stattdessen ein falsches "stabil" 
Argument weiter.

Dein (uni??)theoretischer Firlefanz liefert nur dann korrekte Schlüsse, 
wenn er richtig eingesetzt wird... und das wird er von dir ganz 
offensichtlich nicht!


Hagen Re schrieb:
> Nur wenn der Taster nicht mehr alle 100Hz gedrückt wird ändert sich
> zugunsten deiner Methode der Verauch an CPU Zeit.

Ah ja... du meinst wohl, nur wenn man Taster langsamer als mit 100Hz 
betätigt, hat meine Methode Vorteile... oh DAS ist aber ein gaaanz 
schlimmes Manko...!!! Wo doch jeder Old Dadderhand locker mit 150Hz auf 
den Tasten was reinhackt. Haha, klasse!

Im Übrigen ist 100Hz eine Frequenzangabe und keine Zeitangabe. Man kann 
einen Taster evtl. mit Hz bezittern, oder man kann kann alle 10ms einen 
Taster drücken. Aber nicht alle 100Hz einen Taster drücken...

Und zu deinem letzten Post:
Da wird garnix blockiert an Resourcen. Die schon vorhandene Auswertung, 
welche Taste den Interrupt generiert hat, ist sogar nützlich für andere 
Rotinen, die diese Info ebenfalls benötigen! Das Argument 
"Resourcenblockierung" ist auch nur Hot_Air!

Bist du jetzt eigentlich bald fertig mit deiner nichtdiskreditierenden 
Diskreditierungsorgie...? Das hat ja schon was Fanatisches an sich, Dein 
missionarischer Eifer des Madigmachens... ;-)

******

Hagen Re schrieb:
> Denn erstens erledigt sich dann das Thema Effizenz da man
> ausreichend Resourcen zur Verfügung hat.

Ach, und wozu überhaupt noch was Effizientes proggen, wenn es doch 
Resourcen im Überfluss gibt...?

Hagen Re schrieb:
> Gleichermaßen muß man
> dann hinterfragen welche Seiteneffekte wird es haben wenn ich bestimmt
> Resourcen blockiere für die spätere Anwendung.

Hauptsache gekontert, auch wenn er sich selbst diametral widerspricht in 
einem einzigen Absatz...
...schizo..? Oder merkst du einfach nix mehr, auf deinem 
Mießmuscheltrip?

Ich wünsche dir gute Besserung... dieser, wenigstens psychologisch 
interessante, Disput bringt mir keine neuen Erkenntnisse mehr, ausser 
daß ich da subjektiv eine subtile Art von Neid bei dir und deinen 
endlosen, hohlen Kontra-Argumenten erspüre.

Mach doch mal was Kreatives, statt hier so verbissen erfolglos den 
Marcel Reich-Ranicki der µC-Progger zu imitieren... :-))

Ich jedenfalls geh jetzt raus an die Sonne...

von Thomas E. (thomase)


Lesenswert?

Michael Schurr schrieb:
> Ich jedenfalls geh jetzt raus an die Sonne...
Na endlich mal was Vernünftiges.
Da kannst du dann über Vorwiderstände ohne Leuchtdioden nachdenken. Auch 
so ein beliebtes Vollpfostenthema, daß niemanden wirklich interessiert.

mfg.

von Hagen R. (hagen)


Lesenswert?

M. N. schrieb:
> Hagen Re schrieb:
>> Wird der Taster schneller als 100Hz gedrückt machen beide Methoden einen
>> Fehler.
>
> Das muß nicht so sein. Durch schnelles Anschlagen eines Tasters wird ein
> kurzer Impuls erzeugt, der per PCINT schnell und zuverlässig erkannt
> wird: siehe Bild.
> Nach ca. 2ms ist der Kontakt erkannt und nach ca. 4ms wieder auf
> Ruhepegel. Soll sich jeder selber sein Urteil bilden.

Und was bringt das ? So hast du nämlich einen Störimpuls zuverlässig 
detektiert und nicht das Betätigen wie gewünscht zuverlässig erkannt.

Also kommt der Timer nach dem PCINT ins Spiel der dann 50ms später 
erneut den Taster abfragt und nur wenn dann der Taster immer noch 
betätigt ist wird ein Tasterevent erzeugt. In deinem Falle also kein 
Tasterereignis aber ein unnötiger PCINT.

von Hagen R. (hagen)


Lesenswert?

Michael Schurr schrieb:
> Hallo "Mr. Abtasttheorem", ...selten sowas von lernresistent und daneben
> bei einer "Analyse" gelesen.. Daß der PChg_int nur auslöst, wenn auch
> ein solcher Event auftritt, ist dir aber schon klar? Daß er nur 1mal
> gebraucht wird und daher der entsprechende Eingangspin für den Rest des
> laufenden Timerintervalls aus dem PChg ausmaskiert wird, ist dir auch
> klar?
> Nein, sicher nicht... war nur rhetorisch.

Doch das ist mir klar und habe ich auch so schon in den vorherigen 
Positing analysiert für dich.

Egal, letztendlich habe ich nur noch eine Bemerkung zu machen: ist dir 
mal aufgefallen welche Rethorik du an den Tag legst ?

von M. N. (Gast)


Lesenswert?

Hagen Re schrieb:
> Und was bringt das ? So hast du nämlich einen Störimpuls zuverlässig
> detektiert und nicht das Betätigen wie gewünscht zuverlässig erkannt.
>
> Also kommt der Timer nach dem PCINT ins Spiel der dann 50ms später
> erneut den Taster abfragt und nur wenn dann der Taster immer noch
> betätigt ist wird ein Tasterevent erzeugt. In deinem Falle also kein
> Tasterereignis aber ein unnötiger PCINT.

Das ist kein Störimpuls und einen Timer verwende ich auch nicht. Bei 
genauer Lektüre hätte es Dir klar sein sollen.
Aber was soll ich hier gegen Windmühlen antreten?

von Hagen R. (hagen)


Lesenswert?

M. N. schrieb:
> Hagen Re schrieb:
>> Und was bringt das ? So hast du nämlich einen Störimpuls zuverlässig
>> detektiert und nicht das Betätigen wie gewünscht zuverlässig erkannt.
>>
>> Also kommt der Timer nach dem PCINT ins Spiel der dann 50ms später
>> erneut den Taster abfragt und nur wenn dann der Taster immer noch
>> betätigt ist wird ein Tasterevent erzeugt. In deinem Falle also kein
>> Tasterereignis aber ein unnötiger PCINT.
>
> Das ist kein Störimpuls und einen Timer verwende ich auch nicht. Bei
> genauer Lektüre hätte es Dir klar sein sollen.
> Aber was soll ich hier gegen Windmühlen antreten?

Mit anderen Worten möchtest du einen 2ms langen Tastendruck detektieren 
?

Nachfolgend deine Lektüre:
>Hagen Re schrieb:
>> Wird der Taster schneller als 100Hz gedrückt machen beide Methoden einen
>> Fehler.

>Das muß nicht so sein. Durch schnelles Anschlagen eines Tasters wird ein
>kurzer Impuls erzeugt, der per PCINT schnell und zuverlässig erkannt
>wird: siehe Bild.
>Nach ca. 2ms ist der Kontakt erkannt und nach ca. 4ms wieder auf
>Ruhepegel. Soll sich jeder selber sein Urteil bilden.

Ich bezog mich darauf das der Taster minimal 10ms gedrückt sein muß, und 
alles was drunter ist ist ein Störimpuls. Vielleicht wird dir jetzt 
meine Aussage klarer.

von Michael Schurr (Gast)


Lesenswert?

Peter Dannegger schrieb:

> Vielleicht ging es ihm nur so wie mir, ich verstehe nicht, wie Dein Code
> entprellen soll. Er enthält ja auch keinerlei Kommentare.
>
> Wie ich das verstehe, wird beim ersten Pin-Change Interrupt der
> Pin-Zustand eingelesen und weitere Interrupts für diesen Pin gesperrt.
>
> Und nach einer Wartezeit wird dann der gespeicherte Zustand übernommen
> und Pin-Change wieder freigegeben. Der Pin kann zwischenzeitlich wieder
> eine völlig anderen Zustand haben, es kann auch nur ne Störnadel gewesen
> sein.


Peter, Du hast recht.


In der Wd_isr muss natürlich stehen:


    If Changed_pins_sum = 0 Then

     Deb_pinb = PINB       anstatt: Deb_pinb = Last_Pins_state

    Else
.
.

Hab ich in der obigen Aktualisierung falsch übernommen und ist mir nicht 
aufgefallen.
Das wirkt sich sonst genau in diesem besonderen Fall aus, wenn es ein 
einzelner Spike bzw. ein Burst war, der den ersten Flankenwechsel im 
Endeffekt wieder annuliert UND wenn gleichzeitig im darauffolgenden 
Timerinterval kein aktualisierender PChg-Event auftritt.

Bei einem Changed_pin_sum = 0 im Timer-Int ist jedoch garantiert, daß es 
innerhalb des gesamten vorangegangenen Timerzeitfensters, keinen 
Change-Event am Eingangsport gegeben hat. Somit ist in diesem Fall das 
gesamte PINB stabil und gültig und kann ins Ausgangsbyte kopiert 
werden..

Brilliant beobachtet, danke !

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.