Zunächst mal Hallo an das Forum, das ist mein erster Beitrag
Folgende Problematik:
Ich habe eine etwas umfangreiche Platine gelayert und bereits in Produktion gegeben und dabei einen "alten" Fehler gemacht, den ich schon mal begangen habe.
In dem Projekt gibt es einen Volumenzähler der wie ein Drehzalmesser am Lüfter funktioniert und per Interrupt ausgelesen wird. Idealerweise schließt man diesen an INT0 oder INT1 an. In einem anderen Projekt hab ich das mal über die Vektoren geregelt - da kam ein Lüfter später dazu - ohne Probleme.
Jetzt ist es so, dass konkret auf D8 eines Nanos der Volumenzähler hängt, ich dafür also einen Interrupt benötige (ohne Interrupt geht es gar nicht - 0,5ml entsprechen einem Impuls - also relativ schnell). Soweit kein Problem, geht ja mit dem PCINT. ABER: auf D11 und D13 hängt ein Digole SPI Display (mit SS auf Masse - 2 Draht). Das ist im gleichen Vektor.
Frage: Platine neu machen oder verfrickeln und den Volumenzähler auf INT1 oder INT0 hängen weils anders nicht geht - oder bekommt man es ohne Nachteile (was wären diese?) hin, alles so zu lassen und mit dem PCINT zu arbeiten ohne dass man mit dem Display Probleme bekommt? In meiner Vorstellung wird dann jedesmal wenn man etwas mit den Pins aus dem gleichen Vektor macht (z. B. das Display beschreibt) irgendwas ausgelöst was nicht gut ist.
Ja das stimmt, man kann es maskieren auf einen Pin - damit hätte man halt die Möglichkeit, pro Pin eine separate ISR zu binden. Nur finde ich nichts dazu, ob dann im Hintergund "mehr" passiert - sprich ohne dass mans mekrt ständig der Interrupt ausgelöst wird.
HW-Mäßig bindet man den Interrupt ja dann auf den Port. Der ist erstmal aus default. Damit man den Pin abfragen kann muss man so oder so den Interrupt auf Portbasis anschalten - so verstehe ich das zumindest. Somit bleibt die Frage was das bedeutet - bei jedem LOW/HIGH auf dem SPI irgendwas im Hintergund zu haben hört sich erstmal unsauber an - muss aber nicht.
Konkret müsste man wissen, ob die Maske bewirkt, dass der Prozessor die anderen Pins des Vektors ignoriert - und zwar vollständig ohne Nachteile oder halt nur noch einen "meldet" aber alle "bemerkt". Wirft auch wieder die Frage auf, wenn's genau so klappen würde, wofür dann dedizierte Interrupt Pinne existieren.
Bei den Pinchange-Interrupts gibt es pro Port eine ISR,
alle Pins des Ports können einzeln aktiviert werden, so wie der Interrupt für den einzelnen Port.
Maskierte Bits erzeugen keine Pinchange-Interrupts.
Bei den externen Interrupts hast du eine Auswahl zwischen CHANGE, RISING, FALLING, HIGH und LOW,
bei den Pinchange-Interrupts gibt es nur CHANGE.
Sollte in deinem Setup (mit nur einem Interessenten für PCINTs) problemlos funktionieren.
Du musst sich halt mit der Kantenerkennung auseinandersetzen,
also den alten Zustand zur Hand haben, wenn der Interrupt eintrifft,
dann erkennst du ob es die Flanke ist die dich interessiert (falls das eine Rolle spielt),
den neuen Wert merkst du dir.
Ja das CHANGE zu FALLING "wandeln" musste ich auch in dem Projekt, bei dem der Lüfter später dazu kam - da hab ich es exakt so gemacht. Da war im Prinzip auch nur der eine Pin interessant und da passiert auch eine Menge, weil der Lüfter pro Umdrehung 4 Impulse gibt bei ca. 3000u/m. Einziger Unterschied ist da halt, dass alle anderen Pinne des Vektors genau nichts machen in der Zeit wo der Lüfter läuft, also der Interrupt nur vom Lüfter benutzt wird.
Das erleichtert mich jetzt, in der Platine steckt viel Arbeit und natürlich auch die Fertigungskosten - und verfummeln ist übel - wenn einem das Aussehen wichtig ist bzw. möchte man es ja auch technisch korrekt lösen. Ich hätte den "Fehler" sonst korrigiert und wohl oder übel neu fertigen lassen.
Wobei die Internas ja trotzdem mal interessant wären - theoretisch müsste trotzdem bei jedem Pinchange des Vektors eine Überprüfung gegen die Maske passieren - wahrscheinlich nix Großes, aber anders gehts bei der Architektur (mehrere Pinne ein Port - Interrupt per Port) wahrscheinlich nicht - es wird insg. mehr Rechenleistung kosten denke ich. Parallel zum Volumenmesser laufen noch zwei PID-Algos und das Display wird über SPI aktualisiert. Im gleichen Vektor sitzt sogar noch ein Ultraschallsensor der "hin und wieder" abgefragt wird - da wird schon gut Traffic sein.
Am besten wäre ja jemand, der sowas schon mal gemacht hat. Im Netz gibts natürlich nur Leute die es "richtig" gemacht haben und die INT0 oder INT1 Pinne für sowas nehmen
Ich bastele gerade an einem PCINT getriebenen Rotary-Encoder Treiber,
der das Encoding und den integrierten Button darüber abwickelt.
Für diesen sehr allgemeinen Fall (die Pins sollen beliebig sein) betreibe ich auf allen drei PCINTs die gleiche ISR.
Das scheint bisher recht gut zu funktionieren, habe aber noch keine Konfigurationen getested in denen mehrere Ports beteiligt sind.
Der Code ist auch noch nicht ganz fertig (im Sinne von AVR-perfect definiert)...
Einen Test auf mehreren beteiligten Ports habe ich gerade kurz durchgeführt, geht einwandfrei.
RotEnc Rotary(A2, 5, 12);
Natürlich habe ich (bisher?) noch nicht alle Bits auf allen Ports,
geschweige denn alle verschieden Kombinationsmöglichkeiten, getested.
Da es aber nur um ein einmaliges Maskensetzen geht, der Rest des Codes einfach 'seine' Bits liest,
und alle PCINTs in einer Routine gipfeln, sehe ich keine echte Interferenzmöglichkeit.
Aber das ist natürlich für dich nur interessant,
wenn du noch andere Events mit einer Methode fangen willst.