Interrupt bei einem GPIO Pin des RasPi

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von mschnell »

Socke hat geschrieben:
Fr 7. Mai 2021, 15:00
Da die sysfs-Schnittstelle blockierend genutzt wird, muss für jeden Input ein eigener Thread erzeugt werden.
Was genau die perfekte Methode ist, um in Userspace-Programmen mit Interrupts zu arbeiten.
Nur so kann man minimale Latenz und minimalen Resourcenverbrauch kombinieren.
Seit Lazarus TThread.Queue hat, ist die Kommunikation zwischen Thread und Mainthread auch kein Problem mehr.
-Michael

Nimral
Beiträge: 390
Registriert: Mi 10. Jun 2015, 11:33

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von Nimral »

Hi Michael,

ich häng mich hier mal an, als Lernender, weil mich das Thema auch interessiert, und weil ich es vermutlich bald mal brauchen werde. Die Anwendung: mehrere Linearmaßstäbe an einem Raspi. Sie liefern ein Clock und ein Data Signal. Da parallel dazu auch noch eine GUI zu bedienen ist habe ich über einen Polling Ansatz nicht ernsthaft nachgedacht. Überhaupt finde ich "wozu braucht man das" den getarnten Zwilling von "Ich hab keine Ahnung davon, würde aber gerne über etwas Anders reden was ich zufällig weiß", und damit nicht nützlich.

In meiner von Windows und PC Hardware geprägten Vorstellung triggert Clock einen Interrupt, der zeigt auf meine ISR, und die liest den Data Pin und setzt ein Bit im Ergebnis. Parallel schaue ich auf den internen Timer, wenn der Interrupt länger nicht kam beginnt ein neues Datenwort. Wenn das Datenwort komplett ist, wollte ich erstens ein Event setzen. Ich würde dann pro Messgerät einen eigenen Thread erzeugen der mit WaitFor auf Messwerte wartet, diese weiterbearbeiten und dann was mit ihnen tun, also daran rumrechnen, ihn wegspeichern oder mit Synchronize ins MainForm schieben zwecks Anzeige, was auch immer mir da noch einfällt.

Insofern wäre ich grundsätzlch unendlich dankbar für ein Code-Beispiel das zeigt, wie man in Lazarus eine ISR deklariert und sie im Raspi an einen bestimmten Interrupt klemmt. Gab es da nicht mal das Projekt "RaspiHAL"? Es scheint viel abzudecken zum Thema GPIO, aber Interrupts werden nirgends erwähnt, ich fand aber in der Source einige Hinweise dass die Library intern Gebrauch von Interrupts macht, es könnte also möglich sein.

Wo würde mir die Thread.Queue Methode, deren Existenzberechtigung mir erst mal überhaupt unklar ist, helfen? Ich habe die Delphi Doku dazu gefunden und 10 Mal gelesen, aber wie fast immer verstehe ich nicht, welche Rolle diese Methode in welchem Gesamtkonzept spielen soll. Auf den ersten, zweiten und dritten Blick erinnert sie mich an TThread.Synchronize, wo ist der Unterschied?

HG, Armin.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von Socke »

Nimral hat geschrieben:
Mo 10. Mai 2021, 18:24
Wo würde mir die Thread.Queue Methode, deren Existenzberechtigung mir erst mal überhaupt unklar ist, helfen? Ich habe die Delphi Doku dazu gefunden und 10 Mal gelesen, aber wie fast immer verstehe ich nicht, welche Rolle diese Methode in welchem Gesamtkonzept spielen soll. Auf den ersten, zweiten und dritten Blick erinnert sie mich an TThread.Synchronize, wo ist der Unterschied?
TThread.Synchronize wartet bis der Hauptthread die Methode abgearbeitet hat. TThread.Queue stellt die Methode einfach in die Queue des Hauptthreads und kehrt dann zum aufrufenden Thread zurück.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von Timm Thaler »

Nimral hat geschrieben:
Mo 10. Mai 2021, 18:24
In meiner von Windows und PC Hardware geprägten Vorstellung triggert Clock einen Interrupt, der zeigt auf meine ISR, und die liest den Data Pin und setzt ein Bit im Ergebnis.
Ja oder Du schaust mal ins Datenblatt Deiner Geber was das für ein Protokoll ist und ob Du da mit SPI oder I2C nicht besser bedient bist als jedes Bit einzeln zu sampeln.

Deine von Windows geprägte Vorstellung muss sehr alt sein, so Win 3.11 irgendwas. Denn seit Win95 gibt es keine echten Hardware-Interrupts mehr - was damals viele Programme unbrauchbar machte die noch mit Bitschubsen und direkten Registerzugriff an Schnittstellen gearbeitet haben.

Und was Du Dir klarmachen solltest: Der Raspi ist zumindest unter Raspbian kein Echtzeit-OS. Du kannst Dich NIE darauf verlassen, dass mit welchem Interrupt auch immer Du Bitwechsel an den GPIO rechtzeitig mitbekommst und sie rechtzeitig auslesen kannst. Entweder einen AVR vorschalten, oder ein Echtzeit-OS verwenden, oder das richtige Protokoll verwenden (Uart, SPI, I2C) und die fertig gesampelten Daten auslesen.

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von Timm Thaler »

Btw: Bei Mikrocontroller.net werden regelmäßig Leute zusammengefaltet, die Drehgeber mit Interrupt auslesen wollen. Und ja, ich habe das für Encoder auch schon so gemacht, und meine Motoren laufen damit seit Jahren. Aber ich würde es nicht mehr so machen. Aus Gründen.

https://www.mikrocontroller.net/article ... t_gut_sind

Man kann dazulernen. Oder man kann ewig auf seinen Fehlern hängenbleiben.

Benutzeravatar
six1
Beiträge: 782
Registriert: Do 1. Jul 2010, 19:01

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von six1 »

@Timm Thaler
aber jetzt vergleichst du Äpfel mit Birnen...
Ein AVR hat kein OS und läuft damit Real Time.
Warum sollte man nicht die Flanke "A" an einen INT Eingang legen und im Int die Flanke "B" checken? Das ist ein Zweizeiler!

Zum Problem: Die Idee von Timm, eines vorgeschalteten AVR um die Signale zu erkennen, finde ich gut.


Abseits vom Thema:
"Mikrocontroller.net" und "regelmäßig Leute zusammengefaltet" beschreibt den Laden gut. Ein unmöglicher Umgangston.
Gruß, Michael

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6197
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von af0815 »

six1 hat geschrieben:
Di 11. Mai 2021, 06:31
Abseits vom Thema:
"Mikrocontroller.net" und "regelmäßig Leute zusammengefaltet" beschreibt den Laden gut. Ein unmöglicher Umgangston.
Das kann schon sein, aber es sind auch sehr gute Artikel, wie zum Beispiel der oben, vorhanden. Das entschädigt für den Ton dort, wenn man nicht Mitdiskutatnt ist :-)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Nimral
Beiträge: 390
Registriert: Mi 10. Jun 2015, 11:33

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von Nimral »

Timm Thaler hat geschrieben:
Mo 10. Mai 2021, 23:40
Btw: Bei Mikrocontroller.net werden regelmäßig Leute zusammengefaltet, die Drehgeber mit Interrupt auslesen wollen.
Stimmt. der überhebliche Ton den dort manche Member anschlagen nervt. Warum die Mods das Anflegeln von Einsteigern ins Thema akzeptieren ist mir schleierhaft. Ich nehms in Kauf, immerhin bekomme ich dort meistens irgendwann auch sehr gute Infos - seltsamerweise aber meistens eben gerade nicht von den Leuten die sich so oberlehrerhaft geben. Jeder beginnt bei jedem Thema mal als Anfänger, und hat Anfängerfragen, das ist keine Schande.

Bisher schalte ich ebenfalls Arduino Nanos vor, ich lese damit z.B. Messuhren aus https://forum.zerspanungsbude.net/viewt ... 2&start=10. Das Lazarus Programm das ich da auch eingestellt habe läuft auf WIndows und Linux (Raspi). Die China-Teile - und das trifft auch auf die billigen Lineargeber zu (Siehe Shahe DRO Linear Scales, IGaging, EZ-DRO, Accuremote und Konsorten) liefern tatsächlich kein SPI oder RS-232 oder I²2, einfach nur blank Clock und Data. Es war übrigens mein Einstiegsprojekt ins Thema Multithreading mit Lazarus, und es mag eventuell gefinkeltere Lösungen geben, aber immerhin funktioniert es produktiv - man kann sogar die Messuhren im Lauf ab- und anstecken, so schlecht kann es also nicht sein. ENtwickelt zu 100% auf WIndows (wegen der besseren Anlage), debuggt und eingesetzt auf Linux. Hier sehe ich einen großen Vorteil für Lazarus, vielleicht sogar den *einzigen" Killer-Vorteil den Lazarus noch hat.

Das Thema mit den Interrupts kenne ich, wage aber leise zu zweifeln, und würde das nie öffentlich äußern, sonst gibt es wieder Haue von den Oberlehrern. Der Raspi 3 und seine Nachfolger haben 4 Cores. Für die Anwendungen, die ich im Auge habe, laufen dann einige Hintergrundprozesse und mein Lazarus Programm (das die Raspi-GUI zu 100% ersetzt, die ist also auch nicht aktiv), Das sollte doch reichen um Interrupts zeitnah zu bedienen, zumal es dann nicht passieren kann dass ein User probiert, parallel Videos zu codieren, im Internet rumzuhängen oder mit LibreOffice Briefe zu schreiben. Das Argument, man könne mit einer ISR einen Bitwechsel auch "versäumen", nun ja, das gilt für Polling genaus wenn nicht sogar noch mehr, und man wird sehen. In meiner (veralteten) Welt sperrt eine ISR andere Interrupts und damit m.E. auch das Multitasking bis sie abgearbeitet ist, das Auslesen erfolgt also mehr oder weniger unmittelbar nach dem Auslösen des Interrupts. Vielleicht geht dadurch die Systemuhr ein wenig nach - na und? Eher kitzlig (gedanklich): was wenn zwei Messgeräte gleichzeitig senden? Gibt es eine Queue so dass jeder Interrupt mal drankommt, oder fallen, wenn eine ISR getriggert wurde, alle anderen Interrupts ins Nichts?

Sobald mir jemand verraten hat, ob, und wenn ja wie man mit Lazarus eine ISR einhängen kann (Socke? Hast Du da einen Lösungsansatz?), probiere ich aus, ob die Bedenkenträger *immer* Recht hatten, oder ob es einfach nur ein paar Randbereiche gibt, in denen Interruptsteuerung tatsächlich nicht funktioniert. Mich überzeugen die Bedenken erst mal nicht hundertprozentig: da ist die Rede von prellenden mechanischen Gebern (die Hallsensoren waren grad aus?) oder supermepfindlichen Dingens die durch Vibration zu Geben beginnen. Hm. Das sind nicht unbedingt alltägliche Rahmenbedingungen, man könnte auch versucht sein, andere Geber einzusetzen.

Mir gehts übrigens nicht mal unbedingt darum, wegen 5 Euro Arduinos wegzurationalisieren. Platz ist ein Argument, und es wird bei den USB Anschlüssen am Raspi schnell eng: 1 für Maus und Tastatur, 1 für Touchscreen, einer für USB Stick zur Datenspeicherung, einer für die Messuhr, und schon sind sie weg. Klar gibt es Hub-Hats, aber da wären doch noch eine Batterie ungenützte GPIO Pins ... da kommt man schon auf die Idee sie nützen zu wollen.

Arduinos davorschalten kann ich immer noch :-) 4 hab ich schon mal anghängt: https://www.reichelt.de/raspberry-pi-us ... qVEALw_wcB, und kein Problem gehabt - wobei die Messuhren natürlich im Unterschied zu Weggebern sehr "harmlose" weil eher seltene und sicher prellfreie Signale senden.

Armin.
Zuletzt geändert von Nimral am Di 11. Mai 2021, 09:26, insgesamt 3-mal geändert.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6197
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von af0815 »

Wenn du unter einem Betriebsystem ISR verwenden willst, so benötigst du einen entsprechenden Treiber. Dieser stellt dann den entsprechenden Callback zur Verfügung.

Bezüglich Echtzeitfähigkeit ist das ein guter Link zum Anknüpfen https://www.industry-of-things.de/so-wi ... -a-631650/

Man kann natürlich auch eine Maschinensteuerung drauf laufen lassen, es gibt da professionelle Pakete, die nicht mal sooo teuer sind (im Vergleich zu anderen Steuerungen).
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Nimral
Beiträge: 390
Registriert: Mi 10. Jun 2015, 11:33

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von Nimral »

Sehr interessanter Link! Ich denke, wenn ich das Projekt wieder weiter verfolge wird das sicher ein Bestandteil werden.

Bleibt noch das "Missing Link": wie kann man eine ISR unter Lazarus schreiben?

Mir gehts bei Eigenbauten übrigens nicht ums Geld, sondern einfach um den Spaß an der Sache. Ich war leidenschaftlicher Lego-Spieler, Arduino und Raspi sind wie Lego mit Strom ...

Für die Weggeber gibt es für unter 30 Euro fixfertige, etwa zündholzschachtelgroße Anzeigeeinheiten. Für Drehbank und Fräse würde es bereits reichen, für jede Achse eine davon zu nehmmen und alle übereinander zu schrauben, und damit hätte ich 95% des Zusatznutzens einer solchen Anzeige bereits erreicht, mit minimalem Aufwand an Zeit und Hirn.

Armin.
Zuletzt geändert von Nimral am Mi 12. Mai 2021, 19:14, insgesamt 2-mal geändert.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6197
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von af0815 »

Hier wird um ähnliches diskutiert https://forum.lazarus.freepascal.org/in ... ic=49461.0

Dort wird auch auf https://github.com/laz2wiringpi/laz2wir ... errupt.pas verwiesen. Vielleicht dein missing Link ?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Nimral
Beiträge: 390
Registriert: Mi 10. Jun 2015, 11:33

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von Nimral »

Das schaut supergut aus, vielen Dank! Damit arbeite ich mich mal weiter ins Thema, mal sehen ob ich an Grenzen stoße :-)

HG, Armin,

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6197
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von af0815 »

Nimral hat geschrieben:
Di 11. Mai 2021, 09:34
Für die Weggeber gibt es für unter 30 Euro fixfertige, etwa zündholzschachtelgroße Anzeigeeinheiten. Für Drehbank und Fräse würde es bereits reichen, für jede Achse eine davon zu nehmmen und alle übereinander zu schrauben, und damit hätte ich 90% des Zusatznutzens einer solchen Anzeige bereits erreicht, mit minimalem Aufwand an Zeit und Hirn.
DIe Displays nebeneinanderlegen und mit einer Raspi Kamera filmen und auswerten. Ganz ohne ISR :D SCNR
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von mschnell »

Nimral hat geschrieben:
Mo 10. Mai 2021, 18:24
Wo würde mir die Thread.Queue Methode, deren Existenzberechtigung mir erst mal überhaupt unklar ist, helfen? Ich habe die Delphi Doku dazu gefunden und 10 Mal gelesen, aber wie fast immer verstehe ich nicht, welche Rolle diese Methode in welchem Gesamtkonzept spielen soll. Auf den ersten, zweiten und dritten Blick erinnert sie mich an TThread.Synchronize, wo ist der Unterschied?
Short: Bei "Synchronize" wartet der Thread bis der Mainthread mit der Bearbeitung der "Synchronize" Methode fertig ist. Bei "Queue" wartet der Thread nicht.
Sinn: Der Mainthread kann "beliebig lange" mit anderem Zeug blockiert sein, so dass er einen "Snychronize" Aufruf erst nach langer Zeit bearbeiten kann. Der Thread wäre so lange inaktiv. Der Thread wird bei "Queue" nicht aufgehalten und kann weiter tun, was er soll. z.B. auf "Interrupts" (blocking read) warten und weitere Daten sammeln. Alle weiteren "Queue" Aurufe werden (wie der Name sagt) in einer Warteschlange gespeichert, so dass der Mainthread einen nach dem anderen abarbeiten kann.
Achtung; Da beliebig viele Events/Mitteilungen in der Queue warten können,. muss man die an den Mainthread zu übertragenden Daten ebenfalls Queuen. Ein hübscher Trick ist dafür eine Transport Klasse zu definieren, jeweils ein Daten-Transport Element zu instanzeren und diese Instanz als Parameter per "Queue" zu übergeben und die Insanz-Variable dann zu vergessen. Im Maintread dann die Daten rausholen und free aufrufen um das Transport-Element zu zerstören.
-Michael

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Interrupt bei einem GPIO Pin des RasPi

Beitrag von mschnell »

Nimral hat geschrieben:
Di 11. Mai 2021, 08:42
Bisher schalte ich ebenfalls Arduino Nanos vor,
Wenn wir schon bei RasPi sind, dann doch lieber RasPi Pico (zwei ARM M0+ Prozessoren, extrem schnelle und intelligente Signalverarbeitung durch acht I/O-Kopozessoren, USB und viel nettes dabei für unter 5 Euro ). Das Teil finde ich ziemlich Klasse und es gibt unendlich viel Software dafür, obwohl es noch gar nicht so lange verführbar ist.
-Michael

Antworten