Impulse über GPIO Auslesen

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo,
    ich stehe vor der Aufgabe eine Messkammer mit dem RasPI aus zu lesen und die Liter Menge auf einer PHP Webseite auszugeben.
    Ich habe schonmal mit den GPIO Pins gearbeitet und sie über eine Webseite angesteuert/ausgelesen.

    Mein Problem ist nun das diese Messkammer pro Liter 100 Impulse abgibt bei einer Durchflussmenge von bis zu 10 Litern in der Minute komme ich also auf bis zu 1000 Impulse/min ich denke nicht das ich das mit der BASH machen kann.
    Daher meine Frage welcher Weg ist der einfachste mit den GPIO Pins impulse zu zählen und in Liter/min umzurechnen um die errechnete Litter Menge dann ständig aktuell in eine Datei oder Datenbank zu speichern ?

  • Hallo bingobango,

    herzlich Willkommen in unserem Forum!

    Du willst 1000 Impulse pro Minute erfassen. Das geht mit Bash auf Basis von sysfs, das geht mit jeder Programmiersprache und einer GPIO-Abfrage basierend auf sysfs . im Bereich wenige 1000 Impulse pro Sekunde! Erst recht geht das mit Programmiersprachen wie C oder C++ basierend auf entsprechend flotten GPIO-Libraries.



    Daher meine Frage welcher Weg ist der einfachste mit den GPIO Pins impulse zu zählen und in Liter/min umzurechnen um die errechnete Litter Menge dann ständig aktuell in eine Datei oder Datenbank zu speichern ?

    Der einfachste Weg besteht darin, die Programmiersprache auf dem Raspberry Pi einzusetzen, die Du kannst.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (14. Januar 2017 um 16:56)


  • Mit Python. Findest du Tonnen an Material hier. Ich empfehle pigpio oder gpiozero zu verwenden, und SQLite. Was soll mit den Daten passieren?

    Also der erfasste Liter/min Menge soll erstmal in einer Datei oder Datenbank gespeichert werden damit ich die Daten anschließend mit einen PHP Script weiter verarbeiten kann.
    Die aktuelle Liter Menge soll letztendlich in einerm Webinterface leicht Zeitversetzt angezeigt werden.
    Eine Aktualisierungsrate von rund 5 Sekunden wäre schon okay aber je aktueller je besser ;)

  • Na es stellt sich auch ein bisschen die Frage ob die Daten persistent sein sollen, also auch einen Neustart überleben, oder nicht.

    Und wenn du schon Python benutzt, kannst du es auch für die Webseite benutzen. Schau mal hier in meigrafds FAQs.


  • Na es stellt sich auch ein bisschen die Frage ob die Daten persistent sein sollen, also auch einen Neustart überleben, oder nicht.

    Und wenn du schon Python benutzt, kannst du es auch für die Webseite benutzen. Schau mal hier in meigrafds FAQs.

    Danke für den Tipp also die Daten sollen natürlich geloggt werden aber eine Messung dauert bis zu 30 minuten (kann auch vorher beendet werden ) danach wird das ganze wieder auf null gesetzt

  • Hm. Auch wenn der pi da geeignet ist, es wäre ggf. zu überlegen, ob du aus Robustheitsgründen einen arduino zwischenschaltest - der schmiert nicht ab.

  • Hallo,

    Du hast zwei Möglichkeiten. Erstens Du zählst jeden Impuls. Dazu solltest du bei jedem Impuls einen Interrupt auslösen. Mit ständiger Abfrage der Pins, ob sich was geändert hat belastet das System sehr stark.

    Wenn das zeitlich Probleme bringt, weil Du eine ineffiziete Programmiersprache nutzt, gibt es noch eine andere Möglichkeit.

    Du gibst die Impulse auf eine Zähler - Ic, die Du auf eine Lochrasterleiterplatte bringst und fragst jede Sekunde oder alle 2 Sekunden 4 Bit über 4 GPIO´s ab. Nach der Abfrage rechnest Du die Differenz zur letzten Messung ab und speicherst den aktuellen Wert für die nächste Messung.

    Wenn die Gefahr besteht, das in einem Zeitinterval der Zähler überläuft, kannst Du auch 2 Zähler hintereinander schalten und 8 Bit abfragen und berechnen.

    Entscheidend ist, ob der aktuelle Stand jede Sekunde oder auch in einem größeren Zeitinterval für die Anwendung ausreichend genau sind.

  • Aro wie löst man denn in Linux einen interrupt aus? Soweit mir bekannt ist das dem Kernel und seinen Treibern vorbehalten.

  • Hallo __deets__,

    das ist ganz einfach. Da es Dir aber unbekannt ist, geht das offenbar nicht unter Python. In C und Lazarus ist das überhaupt kein Problem. In C beispielsweise geht das über wirringpi. Der Nachteil des Programms ist, das man jeden Pin extra behandeln muß.

    Ich habe in Lazarus den Adressbereich der GPIO´s gemapt und kann somit direkt auf alle Register der Pins zugreifen. Da kann ich z.B auch innerhalb von 2 oder 3 Prozessortakten beliebig viele Pins gleichzeitig setzen oder auf Masse ziehen oder beliebig viele Pins mit einmal abfragen und mit einem vorgegebenen Wert vergleichen. Die eigentliche Umschaltung erfolgt zwar etwas verzögert aber mein Programm kann nach dem setzen der Register sofort neue Aufgaben übernehmen.

    Ich verwende die Interruptauslösung durch die Pins zu fast 100 % wenn es um die Abfrage der Eingangspins geht. Das verstehe ich unter resourcenschonender Programmierung.

  • Hallo Aro,


    Ich habe in Lazarus den Adressbereich der GPIO´s gemapt und kann somit direkt auf alle Register der Pins zugreifen. Da kann ich z.B auch innerhalb von 2 oder 3 Prozessortakten beliebig viele Pins gleichzeitig setzen oder auf Masse ziehen oder beliebig viele Pins mit einmal abfragen und mit einem vorgegebenen Wert vergleichen. Die eigentliche Umschaltung erfolgt zwar etwas verzögert aber mein Programm kann nach dem setzen der Register sofort neue Aufgaben übernehmen.

    wobei Du korrekterweise sagen solltest, dass "beliebig viele Pins" maximal 10 bedeutet. Und dann auch nicht 10 beliebige Pins, sondern nur in Gruppen zu je 10 Stück (also GPIO ... GPIO9, GPIO10, ... GPIO19, ...) ausgewählt werden können.

    Mehr lässt der BCM 2835/2836/2837 lt. Manuals nicht zu. Aber das wird in den GPIO-Libraries, die ich kenne, nicht unterstützt. U.a. aus diesem Grund schreibe ich nebenher - wenn ich mal ein paar Stunden Zeit finde - eine solche Library in Assembler. Ich bin bereits jetzt schon von den Geschwindigkeiten total begeistert.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • Aro: Deine Annahme, dass das in Python nicht gehen wuerde, ist natuerlich einfach nur deiner Ignoranz geschuldet. https://github.com/RPi-Distro/pyt…/pins/native.py zeigt, dass dein Speichermapping selbstverstaendlich auch in Python moeglich ist. Genauso selbstverstaendlich gibt es auch Bindings zu wiringPI (eine eher schlechte Bibliothek uebrigens, PIGPIO ist deutlich besser).

    Doch vollends absurd wird es bei der Behauptung, es wuerde sich dabei um "resourcenschonende Programmierung mit Interrupts" handeln. Man sollte schon ein bissche Ahnung von Linux haben, bevor man sich so weit aus dem Fenster lehnt.

    Ausser dem SYSFS basierten & sehr langsamen Interface gibt es keine Interrupt-basierte GPIO Programmierung im User-Space mit Linux. Bare-Metal geht natuerlich. Und Treiber schreiben. Aber wohl kaum mit Lazarus, oder?

    Stattdessen verwenden die Bibliotheken hochpriorisierte Echtzeitthreads, welche die GPIO-Zustaenden POLLEN. Und bei Zustandsaenderung deine Callback aufrufen. Bestenfalls tun sie das mit Unterstuetzung eines DMA-Kanals, um sich vom Scheduling-Jitter des Kernels unabhaengiger zu machen. Soviel als zu "Interrupt" und "resourcenschonend". Wenn man da mal an der Sample-Periode dreht, kommen locker zweistellige Prozessorlasten zustanden. Das ist halt der Preis fuer 1Mhz Abtastrate.

    Es ist ja nichts dagegen einzuwenden, das du deine dir genehme und gute Umgebung gefunden hast. Ein bisschen weniger Herablassung gegenueber den Erfahrungen und Herangehensweisen *anderer* waere allerdings wuenschenswert. Das habe *ich* in meinem Leben so gelernt...

  • Für jeden Impuls einen Interrupt auslösen. Ich glaub ab da fängt es an das aneinander vorbei geredet wird.

    Aro schreibt in Beitrag#8 dass ständiges abfragen der GPIO's das System stark belasten würde...
    Wenn man weiß wie dann eigentlich nicht.
    Leider ist ein weit verbreiteter Ansatz eine 'while' Schleife zu verwenden.. Wenn die ungehindert rotiert verballert das natürlich ziemlich viel CPU-Aufmerksamkeit, bremst man sie aus um letzteres zu verhindern ist aber keine so hohe Abfrage möglich.... Ich vermute daher Aro hat an dieser Stelle gefährliches Halbwissen

    1000 Impulse pro Minute, also ~17 pro Sekunde, zu erfassen stellt IMHO kein Problem dar. Allerdings würde ich dafür den Pi allgemein für ungeeignet betrachten, auch nicht irgendeinen Zähler-IC den man ständig abfragen und irgendwelche Differenzen berechnen soll...
    Spontan würde ich einen AVR Chip mit 'hardware interrupt' mit einem Quarz anpeilen der dann selbstständig agiert und viel schneller reagieren kann als ein Betriebssystem-basiertes-System... Aber das sei nur mal laut daher gedacht, letztlich hab ich davon eh keine Ahnung :fies:

    Aber betrachtet noch mal den ersten Beitrag und lest ihn aufmerksam(er).

    Pro Liter werden 100 Impulse ausgegeben.
    Durchflussmenge pro Minute sind max. 10 Liter.

    Was er nun haben möchte ist eine Umrechnung auf " Liter pro Minute " bzw das Erfassen der aktuellen Menge in eine Datenbank.

    Bevor ich vorschlagen würde welche Hardware oder Software er verwenden könnte, würde ich erst mal hinterfragen wie genau er die Messwerte in seine Datenbank schreiben möchte und was er denkt damit später anzufangen :huh:
    Davon abhängig würde ich den Rest machen. Denn wenn er einfach nur speichern möchte " 1l waren es um 12:00:00 und 2l waren es 12:01:00 ", dann brauch man sich nicht so viele Gedanken machen als wenn er jeden einzelnen Impuls (also max.100 pro Liter) in die Datenbank schreiben möchte


    //EDIT: Schade das hier wieder eine Grundsatzdiskussion entsteht anstatt auf das Anliegend des ThemenErstellers (direkt) einzugehen.

  • Hallo Andreas,

    leider liegst Du falsch. Du verwechselst das möglicherweise mit den GPFSELn - Registern, mit dem sich die Belegung des Pins programmieren läßt. Da dort pro Pin mehrere Bits notwendig sind, kann man nicht alle Pins gleichzeitig programmieren. Aber das macht man je gewöhnlich nur einmal am Programmanfang.


    Das Register GPSET0 ( auf Adresse 0x 7E20 001C) ist für das setzen aller GPIO zuständig, die im Pi über den Pfostenstecker ereichbar sind. Und das Beschreiben des Registers mit 0xFFFFFFFF setzt alle Pins die als Ausgang programmiert sind mit dieser einen Ausgabe!

    Ebenso ist das Register GPCLR0 (auf Adresse 0x 7E20 0028) dafür zuständig, alle Pins die als Ausgang programmiert sind gelöscht, also auf Masse gezogen werden !

    Das auslesen des Registers GPLEV0 ( auf Adresse x 7E20 0034) gibt den aktuellen Status aller Pins die im Pi über den Pfostenstecker ereichbar sind zurück. Gleichgültig, ob diese als Eingang, Ausgang oder einer speziellen Funktion programmiert sind.

    Damit bleibt es eindeutig meiner Aussage, das ich mit einer Ausgabe alle Pins setzen oder löschen kann. Wenn ich einige Pins setzen und einige löschen will, muß ich natürlich 2 Ausgaben machen. In jedes Register jeweils eine.

    Das es derzeit keine GPIO-Libraries auf dem Markt gibt, die das unterstützen ist schon möglich.

    Versuche es doch einfach mal.
    Wenn Du ganz schnell zum erfolg kommen willst, holst Du Dir als erstes wirringpi.

    Dann ergäntzt du die Datei wiringpi.c und H um eine Funktion

    void *getIOPointer(void)

    {
    return(gpio);
    }
    und neu nach Anleitung kompilieren.

    in einem C -Programm die Dateien einbinden.

    Das ist der Pointer auf den Begin eines gemapten Bereiches.
    um 28 X 4 Byte erhöht hast Du einen Pointer PDWord auf das Register GPSET0

    Passieren kann nichts. Es werden nur die Pins beeinflusst, die als Ausgänge programmiert wurden.

    um weitere 12 X 4 Byte erhöht hast Du GPCLR0

    und um weitere 12 X 4 Byte erhöht hast GPLEV0

    Du wirst nicht nur sehen, das ich Recht hatte sondern wirst von der effiziens begeistert sein.

    Auf Dauer solltest Du einen eigenen Weg finden, den Bereich zu mappen und an den Pointer zu kommen. Aber zur Überprüfung meiner Aussage dürfte der Eingriff erlaubt sein.

  • Hallo Aro,

    [OT]
    ich habe da noch mal in meinen Unterlagen zur BCM-Programmierung geschaut.



    Du verwechselst das möglicherweise mit den GPFSELn - Registern, mit dem sich die Belegung des Pins programmieren läßt. Da dort pro Pin mehrere Bits notwendig sind, kann man nicht alle Pins gleichzeitig programmieren. Aber das macht man je gewöhnlich nur einmal am Programmanfang.

    Da habe ich in der Tat was verwechselt. Mit den GPFSEL-Registern werden die Funktionalitäten (Eingang, Ausgang, Alternativ-Funktionalität) für Gruppen von 10 GPIOs gesetzt.



    Das Register GPSET0 ( auf Adresse 0x 7E20 001C) ist für das setzen aller GPIO zuständig, die im Pi über den Pfostenstecker ereichbar sind. Und das Beschreiben des Registers mit 0xFFFFFFFF setzt alle Pins die als Ausgang programmiert sind mit dieser einen Ausgabe!


    :thumbs1:



    Ebenso ist das Register GPCLR0 (auf Adresse 0x 7E20 0028) dafür zuständig, alle Pins die als Ausgang programmiert sind gelöscht, also auf Masse gezogen werden !


    :thumbs1:



    Das auslesen des Registers GPLEV0 ( auf Adresse x 7E20 0034) gibt den aktuellen Status aller Pins die im Pi über den Pfostenstecker ereichbar sind zurück. Gleichgültig, ob diese als Eingang, Ausgang
    oder einer speziellen Funktion programmiert sind.


    :thumbs1:

    Danke auch für den C-Code. Aber darüber bin ich in Assembler schon hinaus. Der aktuelle Stand ist, dass ich gezielte GPIO-Pins als Ausgang setzen, ein- und ausschalten kann, Pins als Eingang schalten kann und deren Status auslesen kann sowie an das aufrufende Programm zurückmelden sowie eine vorgegebene Anzahl an GPIO-Ereignissen speichern kann.

    Wie das mit dem Memory-Map funktioniert, habe ioch bereits herausgefunden. Und das


    Das ist der Pointer auf den Begin eines gemapten Bereiches.
    um 28 X 4 Byte erhöht hast Du einen Pointer PDWord auf das Register GPSET0

    Passieren kann nichts. Es werden nur die Pins beeinflusst, die als Ausgänge programmiert wurden.

    um weitere 12 X 4 Byte erhöht hast Du GPCLR0

    und um weitere 12 X 4 Byte erhöht hast GPLEV0


    habe ich auch schon herausgefunden und in Assembler umgesetzt. Mit wiringpi möchte ich mich nicht zu sehr inspirieren lassen, da dort einige Sachen sehr ungünstig realisiert sind.



    Du wirst nicht nur sehen, das ich Recht hatte sondern wirst von der effiziens begeistert sein.


    Von der Effizienz bin ich schon seit Wochen mehr als begeistert.



    Auf Dauer solltest Du einen eigenen Weg finden, den Bereich zu mappen und an den Pointer zu kommen. Aber zur Überprüfung meiner Aussage dürfte der Eingriff erlaubt sein.


    Ich benutze hierfür noch die mmap-Funktion von C.
    [/OT]


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (15. Januar 2017 um 18:04)

  • Hallo Andreas,

    Deine Worte gehen runter wie Öl. Wirring Pi währe nur ein schneller Weg gewesen, wie Du an den Pointer kommst um das mal zu probieren. Mir ist das auch zu langsam. Ich hoffe nur, __deets__ hat sich das auch mal durchgelesen, damit er endlich merkt, wie viele Möglichkeiten es gibt, von denen er keinen Plan hat und hält sich in Zukunft etwas zurück. Es ist ja keine Schande wenn man sich nur in Pyhton auskennt. Das ist,warum auch immer, nun mal die offizelle Sprache des Pi . Es ist aber kein Grund alles und jedes zu verteufeln, was andere besser, schneller und resourcenschonender können.


  • Deine Worte gehen runter wie Öl. Wirring Pi währe nur ein schneller Weg gewesen, wie Du an den Pointer kommst um das mal zu probieren. Mir ist das auch zu langsam. Ich hoffe nur, __deets__ hat sich das auch mal durchgelesen, damit er endlich merkt, wie viele Möglichkeiten es gibt, von denen er keinen Plan hat und hält sich in Zukunft etwas zurück. Es ist ja keine Schande wenn man sich nur in Pyhton auskennt. Das ist,warum auch immer, nun mal die offizelle Sprache des Pi . Es ist aber kein Grund alles und jedes zu verteufeln, was andere besser, schneller und resourcenschonender können.

    Oh, ich kenne ausreichend viele Moeglichkeiten und nutze sie auch, wenn das denn notwendig sein sollte. Der Unterschied zwischen uns ist, dass du Moeglichkeiten nicht kennst, aber *Meinungen* zu diesen Moeglichkeiten hast, die grobe Unkenntnis verraten. Was und was nicht moeglich ist in Python zB. Insofern - verteufeln tut hier nur einer. Genauso wie sich fuer etwas besseres halten.

    Greifbar wird die Ironie dann, wenn du dann aber deine eigenen Tools wie wiringPI und Linux im allgemeinen noch nicht mal ansatzweisein ihrer Funktion begreifst - doch anderen von der Kanzel predigst, sie wuerden verschwenderisch mit ihrer CPU umgehen, waehrend im Hintergund ein Thread munter vor sich hinpollt.... Oder externen Speicher zur Interprozesskommunikation anbindest.

    Insofern: ich hab' hier genug zu lachen, danke dafuer :D :D

  • Hallo __deets__,

    wer lesen kann ist klar im Vorteil. Wirringpi ist nicht mein Tool !!!! dass habe ich Andreas nur aufgezeigt, falls er einen Weg braucht um am schnellsten an den Bereich der Register zu kommen !

    Aber weder er noch ich haben das nötig!

    Die Register direkt zu setzen hat absolut nichts mit Linux zu tun, sondern geht direkt am Betriebssystem vorbei. Und nur deshalb bin ich auf Deine Linuxanspielungen nicht eingegeangen!

    Warum soll ich denn Aufgaben durch das Betriebssystem übernehmen lassen, wenns auf dem direkten Weg viel schneller geht ?

  • Sorry Aro,


    ... Warum soll ich denn Aufgaben durch das Betriebssystem übernehmen lassen, wenns auf dem direkten Weg viel schneller geht ?

    aber behaupte doch bitte nicht immer so einen Unsinn. Mir ist jetzt schon öfter aufgefallen, dass Du unbelegte Aussagen von Dir als Fakten in den Raum stellst. Es mag ja sein, dass Du der Meinung bist, dem ist so. Aber dann kennzeichne das bitte entsprechend. Es gibt unbedarfte Nutzer, die nehmen solche Aussagen für bare Münze.
    Im Prinzip ist es mir egal, wer welchen Mumpitz erzählt, solange es offensichtlich ist ... aber wenn die Gefahr besteht, Leser mit Fehlinformationen in die Irre zu führen, dann sehe ich das etwas anders.

    1. Dein Userland-Programm ist dem Scheduling des OS ausgeliefert. Du kommst niemals am OS vorbei ...
    2. Du kannst gar nicht direkt auf die Hardware zugreifen, sondern die Register werden über z.B. mmap nur virtuell in Deinem Adressbereich verfügbar gemacht. Irgendwann werden die Werte dann vom Kernel aus dem Userspace geholt und synchronisiert. Ob das jetzt effizienter ist, als ein LKM direkt im Kernel überlasse ich jetzt mal der Fantasie des geneigten Lesers.

    Also bitte, immer schön auf dem Teppich bleiben ...

    //EDIT: den fremden Thread hier zu kapern ohne sich zu entschuldigen ist imho auch nicht netiquette ...

    cu,
    -ds-

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!