Arduino mit mehreren Interrupts

Ist es möglich 4 Eingänge auf Pegelwechsel L-H & H-L per Interrupt zu überwachen?

Hab mal was gehört dass nur 2 Eingänge gleichzeitig überwacht werden können.

Speziell geht es mir um den MicroView.

Es gibt nur zwei externe Interrupts wo jeder Pin seinen eigenen Interrupt Vektor hat

Aber auf dem UNO kann man etwas aufwendiger auf jedem Pin einen Interrupt auslösen. Dabei teilen sich dann immer 8 Pins einen Vektor, weshalb man noch abfragen muss woher der Interrupt kommt. Außerdem wird bei jedem Flankenwechsel ein Interrupt ausgelöst und man kann nicht in Hardware schon steigend oder fallend wählen. Dadurch entsteht wieder etwas Overhead in Software. Nennt sich "Pin Change Interrupt"

Library: https://github.com/GreyGnome/EnableInterrupt (ist eine Weiterentwicklung der alten PinChangeInt Library)

Bei sehr schnellen Signalen kann das durch den Overhead zu langsam sein. Wobei man es auch wieder etwas beschleunigen wenn man es per Hand implementiert.

Die ARM Prozessoren haben vollständige Interrupts auf allen Pins

Soweit ich es verstanden habe können alle Pins Interrupt, nur daß die pins 2 und 3 spezielle Register haben die die Interruptquelle genau wiedergeben. Alle anderen Pins geben einen generellen Interrupt ab und es muß erst die Interruptquelle ausgelesen werden.

Genaueres kann ich Dir nicht sagen, ist aber im Datenblatt nachzulesen.

Grüße Uwe

Oha - wird also kompliziert... :o

Werde wohl doch nur den 1. Pin per Interrupt zum "aufwecken" nehmen und die anderen 3 per Software auf Flankenänderung prüfen.

Ist das richtig, dass der Mega2560 satte 6 Interrupts zur Verfügung stellt? siehe (weiter unten)

Der Mega wäre für meine Zwecke etwas übertrieben - gibt es noch einen Mini-Arduino mit 4 Interrupts?

Ne Frage noch am Rande:

Bekomme plötzlich Fehlermeldung beim Hochladen auf den MicroView:

"avrdude: no programmer has been specified on the command line or the config file Specify a programmer using the -c option and try again"

Hab eigentlich an der ProgrammerEinstellung nix geändert - immer noch AVRISP mkll. Geht aber auch bei anderer Einstellung nicht mehr. Was hab ich falsch gemacht?

Ist das richtig, dass der Mega2560 satte 6 Interrupts zur Verfügung stellt?

Mega Pinout anschauen: http://3.bp.blogspot.com/-5bIrGV8-TfE/VKSNL21TULI/AAAAAAAAAAk/UC4vz6oc-Wg/s1600/ARDUINO.Mega.Pinout.Diagram.png

Dann ja, hat tatsächlich 6 Interrupts. Sorry, das hatte ich übersehen. Zwei davon sind allerdings auf den I2C Pins.

Der Micro/Leonardo wäre noch eine Option. Die haben wohl 5 Interrupts. Der Micro ist klein. Durch das andere USB Interface aber auch etwas anders zu handhaben als die "normalen" Arduinos

Oha - wird also kompliziert

Nimm die Library. Probier aus ob es geht. Damit sieht es für dich als Anwender nicht anders aus. Die Library abstrahiert das alles. Dir sollte nur klar sein dass es vielleicht nicht ganz so schnell wie ein direkter Interrupt geht. Kommt auf die Anwendung an. Oft werden Interrupts auch für langsame Signale genommen.

Mit der Lib kannst du einfach wie normal attachInterrupt() machen und auf FALLING, RISING und CHANGE triggern

Für wirklich zeitkritische Anwendungen sind die externen Interrupts eher weniger geeignet, da die Handler wegen attach/detach erst mal über einen Pointer zur eigentlichen Verarbeitung springen müssen. Außerdem muß man noch beachten, daß rising/falling nur mit einer Verzögerung um ein paar Takte funktioniert. Bei den PinChange Interrupts scheint das anders (asynchron) zu sein, jedenfalls können die angeblich auch zum Aufwecken aus jedem Schlafzustand benutzt werden.

Wenn man die zu überwachenden Pins auf unterschiedliche Ports verteilt, bekommt man immerhin einen extra Interrupt für jeden Port zusätzlich, also 3 bei den kleinen AVR mit Ports B, C und D. Ein Mega hat zwar mehr Ports, anscheinend aber keine PCINT dafür? Aber immerhin hat er 8 externe Interrupts, statt nur 2 wie die kleineren Controller.

Zusätzlich sollte es möglich sein, die Timer Capture Interrupts einzeln zu nutzen. Ausprobiert habe ich die aber noch nicht.

Der Atmega2560 hat wie der 328 nur 3 Interrupt Vektoren (und die entsprechenden Register) für Pin Change Interrupts. Das wurde nicht aufgestockt. Macht 3 * 8 Pins. Entsprechend geht es nicht auf allen Pins

Für wirklich zeitkritische Anwendungen sind die externen Interrupts eher weniger geeignet, da die Handler wegen attach/detach erst mal über einen Pointer zur eigentlichen Verarbeitung springen müssen.

Stimmt. Eine Ebene Indirektion ist auch da dabei. Aber das lässt sich immerhin per Hand komplett entfernen

Ich denke so kritisch wird es vielleicht auch nicht sein. Wie gesagt, muss man ausprobieren. Die Chancen sind gut dass es geht. Ich wollte nur vollständig sein und erklären was der Unterschied ist.

Zusätzlich sollte es möglich sein, die Timer Capture Interrupts einzeln zu nutzen.

Timer Input Capture geht nur auf 16 Bit Timern. Auf dem Mega kommt dann leider hinzu dass der Pin nur für Timer5 herausgeführt wurde. T1, T3 und T4 ist nicht zugänglich :/

stoni99: Ist es möglich 4 Eingänge auf Pegelwechsel L-H & H-L per Interrupt zu überwachen?

stoni99: Oha - wird also kompliziert... :o

Nur so eine Idee als Alternative: Vier normale Eingänge zusätzlich mit vier Dioden als Oderverknüpfung an den Interrupteingang anschließen. Wird ein Interrupt ausgelöst, wurde einer der Eingänge verändert. Hängt dann von der restlichen Anwendung ab, ob und wie das sinnvoll und schnell verarbeitet werden kann.

EDIT: Diese Idee hat sich leider als nicht praktikabel erwiesen :(

Ja, ist eine Überlegung wert. :wink:

ODER Verknüpfung mit Dioden? - muß ich mal Googeln…

Nennt sich "Diode Logic" oder "Diode Resistor Logic". Wurde in den 50ern und Anfangs der 60er weit verwendet, weil Transistoren noch nicht so zuverlässig waren

Ich würde aber einfach mal Pin Change Interrupts probieren. Da du den Microview erwähnt hast: Hier sieht man dass die auf allen Pins gehen: https://cdn.sparkfun.com/assets/learn_tutorials/3/2/8/pinout.png Ist ja auch nur ein Atmega328

Müsste doch eigentlich auch mit LED`s gehen? Hab momentan keine anderen...

Mit roten LEDs vielleicht als Hack. Aber ansonsten ist der Spannungsabfall über die LEDs zu hoch. An einer normalen Siliziumdiode fallen nur ca. 0,7V ab

Wie gesagt Pin Change Interrupts. Die EnableInterrupts Library sollte auch auf dem MicroView gehen da es ein Atmega328 ist

stoni99: ODER Verknüpfung mit Dioden? - muß ich mal Googeln...

Wenn A oder B gegen Masse geschaltet wird, geht auch Z logisch gegen Masse.

Gerade das ist mit LEDs sehr problematisch die da "Input Low Voltage" 0,3 * Vcc ist. Eher die andere Version mit Pulldown. Aber da LEDs zu verwenden macht das ganz zu anfällig...

Lass dich nicht von dem Abschrecken was ich oben geschrieben habe

agmue: Nur so eine Idee als Alternative: Vier normale Eingänge zusätzlich mit vier Dioden als Oderverknüpfung an den Interrupteingang anschließen. Wird ein Interrupt ausgelöst, wurde einer der Eingänge verändert. Hängt dann von der restlichen Anwendung ab, ob und wie das sinnvoll und schnell verarbeitet werden kann.

Genau das geht doch schon ohne Dioden, mit einem PinChange Interrupt!

Und der hat noch den Vorteil, daß beliebige Wechsel überwacht werden können, während bei dem wired-and mit Dioden schon ein einziges LOW Signal reicht, damit man keine weiteren Änderungen mehr mitbekommt. Also eher eine unbrauchbare Konstruktion :-(

DrDiettrich: ... während bei dem wired-and mit Dioden schon ein einziges LOW Signal reicht, damit man keine weiteren Änderungen mehr mitbekommt. Also eher eine unbrauchbare Konstruktion :-(

Autsch, das stimmt. Ich hatte an Tasten gedacht, der Klassiker ist die Tastenmatrix, aber allgemein ist das richtig.

Sorry stoni, laß die LEDs (mit roten funktioniert es bei 1,1 V mit meinem UNO) in der Schublade, nimm die Bibliothek :-[

Meint ihr sowas und/oder sowas? Oder der hier?

Das sollte gehen, aber ich habe dir doch schon einen Link gegeben. Gleich am Anfang. Diese Library ist neuer:

Hat einen größeren Funktionsumfang und ist insgesamt besser geschrieben

Hat nur statt attachInterrupt() → enableInterrupt() und statt detachInterrupt() → disableInterrupt(). Und man kann direkt die Pin-Nummer übergeben! (statt einer Interrupt Nummer). Ansonsten ist die grundlegende Verwendung nicht anders

Die Lib unterstützt sogar die externen Interrupts mit der gleichen Syntax

Ja, danke. Muss ich mal testen...

Habe ich mir runtergeladen, werde ich mal testen, auch wenn ich versuche, Interrupts eher zu vermeiden.