Hallo zusammen,
auf diesen Beitrag setze ich auf, um einen Benchmark über meine GPIO-Bibliothek zu bringen.
Mal aus wirklich ernsthaftem Interesse: das waere aber doch wohl auch kaum Icon, oder? Benchmarks sind dazu schwer zu finden, aber die ICON-Homepage fuehrt klar aus, dass es nur interpretiert ist. Und die GPIO-Lib von dir sieht nach Druebersicht auch nach ganz normaler file-basierter IO aus. Gross anders ist das mit Bordmitteln ja auch nicht hinzubekommen.
Im konkreten Fall hier wuerde ich denken die paar hundert Hertz sind machbar, besonders mit PIGPIO - denn es geht ja um aggregierte Daten mit Timestamps, da spielen weder Schedulerpraezision noch Performance der Sprache eine signifikante Rolle.
Verwendete GPIO-Bibliothek
Ich verwende die aktuellste Version meiner GPIO-Library, die zuletzt hier Beitrag #9 gepostet wurde.
Diese Bibliothek wird im Icon-Quellcode durch folgende Zeile
eingebunden.
Eingesetzte Raspberry Pi-Modelle
Der Benchmark wird auf folgenden mir vorliegenden Modellen durchgeführt:
- B
- B+
- A+
- 3B
Testmethodik
Ein Arduino erzeugt über einen Zeitraum von einer Sekunde auf einem digitalen Ausgabe-Pin einen LOW-Pegel, hält diesen für eine vorgegebene Zeit, wechselt auf einen HIGH-Pegel, hält diesen für eine vorgegebene Zeit. Über einen Spannungsteiler (R1 = 3k3, R2 = 1k8 - dadurch liegt max. knapp 3,3 V bei Arduino-HIGH = 5 V an) wird dieser Pegel auf einem digitalen Eingabe-Pin des Raspberry Pi empfangen.
Test 1: Halten von 4 Zyklen á 1000 ms LOW, 1000 ms HIGH
Auf dem Arduino läuft folgendes Sketch
#define PIN 10
#define DEL 1000
void setup() {
// put your setup code here, to run once:
pinMode(PIN, OUTPUT);
for ( int i = 1; i < 5000 / DEL; i ++)
{ digitalWrite(PIN, LOW);
delay(DEL);
digitalWrite(PIN, HIGH);
delay(DEL);
}
digitalWrite(PIN, LOW);
}
void loop() {
// put your main code here, to run repeatedly:
delay(2000);
}
Alles anzeigen
Hier habe ich eine etwas ungewöhnliche Technik verwendet. In [font="Courier New"]setup()[/font] passiert alles Interessante, in [font="Courier New"]loop()[/font] befindet sich nur eine Verzögerung. Warum so?
Ganz einfach. [font="Courier New"]setup()[/font] läuft einmal durch, [font="Courier New"]loop()[/font] wird in einer Endlosschleife ständig wiederholt, bis ein neues Sketch daherkommt oder der Strom abgeschaltet wird. Wenn ich hier Aktionen starte, die die CPU des Arduino zu 100% auslastet, dann ist er weniger empfänglich, wenn ich das Sketch aktualisieren oder tauschen möchte.
Ein weiterer Vorteil besteht darin, dass ich das Sketch komfortabel durch den Reset-Taster starten kann. Und - bei der hier geposteten Version - nach 2 Sekunden ein Messwert vorhanden ist.
Auf dem Raspberry Pi läuft folgendes Programm
link graphics, GPIO
$define PIN 17
procedure main()
HIGHs := 0
while GPIO(PIN) = 0 do {}
repeat
{ if GPIO(PIN) = 1 then HIGHs +:= 1 else break
}
write("HIGHs = ", HIGHs)
end
Alles anzeigen
Programm-Deutung:
Die GPIO-Bibliothek wird eingebunden und der zu verwendende PIN definiert.
In der Hauptroutine [font="Courier New"]main()[/font] wird die Variable [font="Courier New"]HIGHs[/font] auf 0 gesetzt.
Die Zeile
wartet solange, wie auf dem GPIO-Pin 0 = LOW anliegt. Wir erinnern uns: Das Arduino-Programm erzeugt für 1000 ms LOW, dann für 1000 ms HIGH. Mit dieser Zeile wird sichergestellt, dass die Endlosschleife ([font="Courier New"]repeat{}[/font]) erst dann gestartet wird, sobald der erste HIGH-Pegel erkannt wurde.
In der Endlosschleife wird der [font="Courier New"]GPIO(PIN)[/font] = GPIO(17) gelesen. Handelt es sich um HIGH, dann wird der Zähler [font="Courier New"]HIGHs[/font] hochgezählt. Bei LOW wird die Endlosschleife mit [font="Courier New"]break[/font] abgebrochen.
Nach Verlassen wird die Endlosschleife wird der Wert von [font="Courier New"]HIGHs[/font] angezeigt.
Und jetzt mache ich es mir ganz einfach:
Der Arduino sendet für 1000 ms HIGH-Pegel. Das Programm auf dem RPi hat einen HIGH-Pegel bereits gelesen. HIGHs entspricht dann einfach der Frequenz mit der Einheit 1/s.
Ich vernachlässige mal, dass HIGHs eigentlich mit 1 initialisiert werden müsste - denn das erste Signal ist ja bereits ausgelesen worden. Aber egal. So kleinkariert bin ich heute mal nicht.
Dieses Programm wird aus Geany heraus durch Drücken der Taste F5 compiliert und gestartet. Nachdem das Programm ein Textausgabe-Fenster erzeugt hat, betätige ich den Reset-Taster des Arduino.
Messwerte
Das Programm wird aus Geany heraus gestartet:
HIGHs (RPi B+) mit [font="Courier New"]link graphics[/font]
1863
1817
1846
1861
1863
-----
Mittelwert: 1850 Hz
Das Programm wird aus LXTerminal heraus gestartet:
HIGHs (RPi B+) ohne [font="Courier New"]link graphics[/font]
1868
1875
1888
1865
1853
-----
Mittelwert: 1870 Hz
Das Programm wird aus der Konsole ohne X11-Umgebung gestartet:
HIGHs (RPi B+) ohne X11-Umgebung
1951
1966
1941
1924
1935
-----
Mittelwert 1943 Hz
Hier die Benchmark-Daten für RPi A+
Aus Geany heraus gestartet:
2052
2021
2041
2051
2032
-----
Mittelwert 2039
Das Programm wird aus LXTerminal heraus gestartet:
2020
2012
2001
1921
1920
-----
Mittelwert 1975
Das Programm wird aus der Konsole ohne X11-Umgebung gestartet:
2107
2109
2143
2107
2119
-----
Mittelwert 2117
Hier die Benchmark-Daten für RPi 3B
Aus Geany heraus gestartet:
-----
Mittelwert
Das Programm wird aus LXTerminal heraus gestartet:
-----
Mittelwert
Das Programm wird aus der Konsole ohne X11-Umgebung gestartet:
-----
Mittelwert
Fortsetzung folgt.
Beste Grüße
Andreas