Interrupt Delay am Raspberry Pi

Interrupt Delay am Raspberry Pi

Durch seine GPIO Ports ist der Raspberry Pi sehr interessant für Projekte an denen man einige IOs benötigt um etwas Elektronik zu steuern. Gleichzeitig bekommt man mit dem Pi noch einen (fast) vollwertigen LINUX Computer. Es ist also möglich einen Webserver inklusiver richtigen Datenbank auf dem Pi laufen zu lassen und trotzdem direkt mit Hardware zu kommunizieren.

Normalerweise verwende ich Mikrocontroller für diverse Hardwareansteuerungen. Diese programmiere ich dann entweder in C oder wenn es mal wirklich sein muss in Assembler. Auf einem Mikrocontroller ist das auch alles schön und in Ordnung, wenn man allerdings ein bisschen was auf dem Netzwerk machen möchte, Daten in und aus einer SQL Datenbank lesen möchte usw., dann gibt es angenehmere Sprachen als C für so etwas.

Bisher habe ich Webinterfaces mit SQL Datenbank in PHP programmiert. Es wäre jetzt natürlich schön weiterhin so einfach auf z.B. MySQL zugreifen zu können wie in PHP und gleichzeitig die Hardware ansprechen zu können. Sobald man etwas nach Raspberry Pi und GPIO googled trifft man auf Python. Für diese Sprache gibt es Bibliotheken um sehr einfach die GPIOs anzusprechen und dabei gibt es sogar die Möglichkeit Interrupts zu benutzten. Da es eh mal wieder an der Zeit war eine neue Programmiersprache zu lernen (sollte man ja eigentlich jedes Jahr machen) dachte ich mir: Das schau ich mir mal an!

Da ich sonst ja auch jedem erzähle (egal ob er will oder nicht), dass gegen guten nativ compilierten C-Code nichts in punkto Geschwindigkeit ranreicht habe ich also mal geschaut wie schnell der Raspberry Pi mit Python auf einen Interrupt reagiert und das dann mit C verglichen.

IRQ_Test

Der Aufbau ist ganz einfach: Der Raspberry Pi bekommt ein Rechtecksignal mit 2Hz und 3,3V Pegel an GPIO 7 dieses Signal liegt gleichzeitig auf Kanal 1 meines Scopes und dient als Trigger. An Kanal 2 des Scopes ist GPIO 8 angeschlossen. Die Software soll nun nichts weiter tun als einen Interrupt zu konfigurieren und dann zu schlafen. In der Interruptroutine wird nun als allererstes GPIO 8 eingeschaltet. Danach wird auf der Konsole ausgegeben, dass eine Flanke erkannt wurde. Nach der Textausgabe auf der Konsole wird GPIO 8 wieder abgeschaltet. Mit dem Scope kann man nun messen wie lange es nach einer steigenden Flanke auf einen der GPIOs dauert bis die erste Code Zeile im Interrupt ausgeführt wird.

Hier also mein aller erstes Python Programm. Sollte es hier noch Verbesserungsvorschläge geben bin ich ganz Ohr 🙂 (Ich weiß, dass GPIO.cleanup() so nie erreicht wird. Es wäre aber sauberer, wenn man dies am Ende ausführt.)

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(7, GPIO.IN)
GPIO.setup(8, GPIO.OUT)

def FlankeIRQ(channel):
     GPIO.output(8, GPIO.HIGH)
     print "Flanke erkannt"
     GPIO.output(8, GPIO.LOW)

GPIO.add_event_detect(7, GPIO.RISING, callback = FlankeIRQ, bouncetime = 0)

while True:
     time.sleep(1)

GPIO.cleanup()

Es fällt schon mal positiv auf, dass es wirklich sehr einfach nachzuvollziehen ist.

RPI_IRQ_Python

Ich habe das Programm etwa eine halbe Minute laufen lassen um zu sehen wie stabil das Ganze ist. Dafür, dass darunter noch ein LINUX läuft war ich erstaunt, dass es zum einen überhaupt so schnell ist und auch einigermaßen stabil. Ein Delay von durchschnittlich 205µs kann sich durchaus sehen lassen. Damit ist der Pi mit Python auf jeden Fall schnell genug um Drehencoder usw. einzulesen ohne etwas zu verschlucken.

So das heißt jetzt noch schnell das ganze in C, damit ich auch recht behalte ;). Für die C Version habe ich wiringPi (http://wiringpi.com/) verwendet. Hier ist zu beachten, dass die Bezeichnung der GPIOs etwas anders ist als man sie in den meisten Pinouts des Pi findet. Eine entsprechende Tabelle ist jedoch auf der Website zu finden.

#include <stdio.h>
#include <wiringPi.h>

void FlankeIRQ(void) {
    digitalWrite(10, HIGH);
    printf("Flanke erkannt\n");
    digitalWrite(10, LOW);
}

int main(void) {
    wiringPiSetup();
    pinMode(10, OUTPUT);
    wiringPiISR(11, INT_EDGE_RISING, &FlankeIRQ);

    while(1) delay(1000);

  return 0;
}

Auch der C-Code ist dank wiringPi sehr kompakt. Die eigentlichen Vorzüge spielt Python eher woanders aus. Wie erwartet ist der kompilierte C-Code natürlich schneller. Aber gerade mal doppelt so schnell, was mich ehrlich gesagt überrascht hat. Der Interrupt in C wird nach durchschnittlich 99µs aufgerufen. Ebenfalls zu erkennen ist, dass C sich auch bei der Ausgabe des Textes etwas weniger Zeit lässt.

RPI_IRQ_C

Während dieses Tests habe ich übrigens alle Dienste, die ich auf dem Pi habe, weiter laufen lassen. Für Leute denen es auf die letzte µs ankommt ist hier also sicher noch etwas Raum. Zusammenfassend kann man sagen, dass GPIO mit Python offensichtlich eine sehr brauchbare Sache ist.

Advertisements

Ein Gedanke zu „Interrupt Delay am Raspberry Pi

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s