Ardino DUE Pin-Change Interrupts

Moin Zusammen,

Bastel derzeit an einem Logger welcher auf Änderungen an Digital und Analog Eingängen reagieren soll. Dazu benutze ich beim DUE den

attachInterrupt(pin, function, mode)

Nun wie mache ich es am besten das ich wenn function aufgerufen wird auch weiss welcher PIN es war?

Besten Dank für Eure Inputs lg MorgKrig

Eine separate Funktion per Pin, die danach den eigentlichen Handler mit der Pin-Nummer aufruft?

pylon: Eine separate Funktion per Pin, die danach den eigentlichen Handler mit der Pin-Nummer aufruft?

Hatte ich mir auch überlegt...das Problem ist aber das je nachdem was für ein Config-File per USB Stick geladen wird die PINS unterschiedliche Funktionen haben. Zudem wenn ich 100 Inputs 1 Funktion pro Pin?

Mit der PINCHANGE Library hier: https://code.google.com/p/arduino-pinchangeint/downloads/list Müsste es eigentlich auch funktionieren jedoch bekomm ich die examples nicht zum laufen....kommt immer new.h wurde nicht gefunden..

Irgendwie müsste dies doch anders machbar sein?

Mit der PINCHANGE Library hier: https://code.google.com/p/arduino-pinchangeint/downloads/list Müsste es eigentlich auch funktionieren jedoch bekomm ich die examples nicht zum laufen....kommt immer new.h wurde nicht gefunden..

Die ist nur für ATmega-Arduinos, für den Due kannst Du die nicht gebrauchen.

Hatte ich mir auch überlegt...das Problem ist aber das je nachdem was für ein Config-File per USB Stick geladen wird die PINS unterschiedliche Funktionen haben. Zudem wenn ich 100 Inputs 1 Funktion pro Pin?

Der Due hat 54 Eingänge und die Definition der Funktionen kannst Du ja per Makro machen, dann dürfte das halbwegs übersichtlich sein. Die Funktionsverteilung per Jump-Table geht dann auch gleich im selben Aufwasch und Du kannst bequem die Einträge der Jump-Table (Funktionspointer) aus Deiner Konfigurationsdatei machen.

PinChange Interrupts im wörtlichen Sinne gibt es auf dem Due nicht. Anders als auf den AVRs kann auf dem Due jeder Pin einen richtigen Hardware Interrupt auslösen.

pylon:
per Makro machen,
Die Funktionsverteilung per Jump-Table geht dann auch gleich im selben Aufwasch und Du kannst bequem die Einträge der Jump-Table (Funktionspointer) aus Deiner Konfigurationsdatei machen.

Könntest du mir dies genauer erläutern…per Makro machen?Jump Table?

Also zum Beispiel sollte PIN 2-5 , PIN 14-16, und PIN 31 konfiguriert werden. Diese so vom Config File einzulesen und zu konfigurieren funktioniert bis auf die Tatsache mit dem Interrupt.
Nach dem ich Startpin (PIN2) und Endpin(PIN5) sowie die Art des Interrupts eingelesen habe sieht das etwa so aus:

void setDigitalInputs(){
  for(int i = startPort; i<=endPort;i++){
     pinMode(i, INPUT);
     attachInterrupt(i, action, flanke); 
  }
}

Das schönste wäre natürlich wenn ich der Funktion action welche dem Interrupt angehängt wird den Port i mitgeben könnte aber leider geht dies ja nicht. Genau hier stecke ich nun fest…

Das ist der Code für die ersten 20 Pins (als Beispiel). Du hast dann die Jump-Table simple_handler, welche dann den complex_handler() mit der entsprechenden Pin-Nummer aufruft.

typedef void (*phandler)();
phandler simple_handler[20];
#define def_handler(num)  void handler##num() { complex_handler(num); }
#define add_handler(num)  simple_handler[num] = &handler##num;

def_handler(2)
def_handler(3)
def_handler(4)
def_handler(5)
def_handler(6)
def_handler(7)
def_handler(8)
def_handler(9)
def_handler(10)
def_handler(11)
def_handler(12)
def_handler(13)
def_handler(14)
def_handler(15)
def_handler(16)
def_handler(17)
def_handler(18)
def_handler(19)

void setup() {
  add_handler(2)
  add_handler(3)
  add_handler(4)
  add_handler(5)
  add_handler(6)
  add_handler(7)
  add_handler(8)
  add_handler(9)
  add_handler(10)
  add_handler(11)
  add_handler(12)
  add_handler(13)
  add_handler(14)
  add_handler(15)
  add_handler(16)
  add_handler(17)
  add_handler(18)
  add_handler(19)
}

void setDigitalInputs(){
  for(int i = startPort; i<=endPort;i++){
     pinMode(i, INPUT);
     attachInterrupt(i, simple_handler[i], flanke); 
  }
}

Der Code ist nicht getestet, kann also noch Fehler enthalten.

Der Code ist nicht getestet, kann also noch Fehler enthalten.

Auch wenn es funktioniert, sieht irgendwie häßlich nicht nach c++ aus, so ohne Semikolons :wink:

#define startPort 2
#define endPort 19

void complex_handler(int pin)
{
	//  Serial.print ("Interrupt Pin "); Serial.println(pin);  // in reality: no Serial.print in an ISR
}

typedef void (*phandler)();
phandler simple_handler[20];
#define def_handler(num)  void handler##num() { complex_handler(num); }
#define add_handler(num)  simple_handler[num] = &handler##num

def_handler(2);
def_handler(3);
def_handler(4);
def_handler(5);
def_handler(6);
def_handler(7);
def_handler(8);
def_handler(9);
def_handler(10);
def_handler(11);
def_handler(12);
def_handler(13);
def_handler(14);
def_handler(15);
def_handler(16);
def_handler(17);
def_handler(18);
def_handler(19);

void setup() {
  add_handler(2);
  add_handler(3);
  add_handler(4);
  add_handler(5);
  add_handler(6);
  add_handler(7);
  add_handler(8);
  add_handler(9);
  add_handler(10);
  add_handler(11);
  add_handler(12);
  add_handler(13);
  add_handler(14);
  add_handler(15);
  add_handler(16);
  add_handler(17);
  add_handler(18);
  add_handler(19);
}

void setDigitalInputs(){
  for(int i = startPort; i<=endPort;i++){
     pinMode(i, INPUT_PULLUP);
     attachInterrupt(i, simple_handler[i], FALLING); 
  }
}