=>[[helvepic32:|HelvePic32]] ==== Interrupt nutzen ==== Interrupts ermöglichen es, direkt auf ein Ereignis zu reagieren und einen entsprechenden Code auszuführen. Dabei wird die normale Programmausführung unterbrochen. Bei Interrupts gibt es zwei wichtige Dinge zu beachten: * Die Interruptroutine blockiert die normale Programmausführung. Dies wird weder synchronisiert noch kommt man aus einer fehlerhaften Routine (Endlosschleife) wieder zurück * Die Variablen, mit denen ich auch im Hauptprogramm arbeiten will, müssen besonders deklariert werden, damit beide Programmteile darauf zugreifen können Der Arduino hat zwei Interrupt-Pins, der Mega hat 4 Interrupt-Pins. Sobald sich der Zustand dieser Pins ändert wird eine entsprechende Routine aufgerufen, die man mit attachInterrupt an den Pin gebunden hat. Beim HelvePic32 ist das genauso, nur dass man hier 5 Interrupts zur Verfügung hat. Diese sind mit folgenden Pins verbunden: ^ Interrupt ^ Pin ^ Kommentar ^ | int_0 | RIGHT - 2 | fest verdrahtet | | int_1 | RIGHT - 4 | PPS Voreinstellung | | int_2 | LEFT - 6 | PPS Voreinstellung| | int_3 | RIGHT - 3 | PPS Voreinstellung| | int_4 | RIGHT - 1 | PPS Voreinstellung| Der Interrupt 0 ist fest mit dem Pin RIGHT-2 verbunden, die anderen Interrupts können auf andere Pins umgelegt werden, wenn der voreingestellte Pin belegt ist. Dies nennt man PPS für Peripheral Pin Select. Auf diese Möglichkleiten kommen wir später zurück. Die Pinbelegung und die Alternative sind im folgenden Diagramm dargestellt: {{:helvepic32:bspinterrupt:folie3.png?800|Interrupts}} Wir können nun den Encoder mit einem der Interrupt Pins verbinden. Wird der Encoder gedreht, können wir die Drehschritte mitzählen ohne dass wir in loop() ständig den Encoder abfragen müssen. SO kann man auch die Stellung einer Achse überwachen und bei Bedarf abfragen. Für das Beispile verbinden wir den Encoder A mit RIGHT-4. Da der HelvePic32 keine internen Pull-up Widerstände hat, müssen wir diese extern hinzufügen. {{:helvepic32:bspringcoder:encoder.png?600|}} Der Code ist der Gleiche wie beim Arduino. Die Variablen, welche auch im Hauptprogramm verwendet werden sollen müssen als **//volatile//** gekennzeichnet werden. #include #include volatile int encoderPin1 = nP[RIGHT][4]; // pin connected to INT-1 by default volatile int encoderPin2 = nP[RIGHT][5]; volatile int number = 0; int oldnumber = number; void setup(){ Serial.begin(9600); pinMode(encoderPin1, INPUT); pinMode(encoderPin2, INPUT); attachInterrupt(1, isr_A, FALLING); Serial.println("Starting Encoder"); } void loop(){ int val; for (int i=0; i<256; i++){ delay(30); if (oldnumber != number){ Serial.print(number); oldnumber = number; Serial.println(); } } } void isr_A(){ delay(3); // Debounce time // Trade off bounce vs missed counts int LSB = digitalRead(encoderPin1); int MSB = digitalRead(encoderPin2); if(LSB == LOW){ // A still LOW ? if(MSB == HIGH) number++; if(MSB == LOW) number--; } } ===== Auslesen des Tasters ===== Auf die gleiche Weise wollen wir nun den Taster überwachen. Deshalb haben wir ihn auch im vorherigen Kapitel auf Pin RIGHT-3 gelegt, denn dieser ist der vordefinierte Pin von int_3 Den Code für die Auslese des Tasters zu schreiben ist eine gute Übung. Daher wird hier jetzt kein Beispiel gegeben. Im Abschluss des Kapitels ist aber der gesamte Code zu sehen und man kann seine Lösung mit unserer vergleichen. {{:helvepic32:bspringcoder:switch.png?600|}} =>[[helvepic32:|HelvePic32]]