(erledigt) python (oder auch C) - ständig laufende Abfrage

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
smutbert
Beiträge: 8342
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

(erledigt) python (oder auch C) - ständig laufende Abfrage

Beitrag von smutbert » 21.06.2014 16:27:58

Hi,


jetzt spiele ich mich schon ein Zeiterl mit meinem Cubietruck und bin schon wieder auf ein Problem gestoßen: ich möchte ein paar Taster an die gpio-Pins anschließen und dann mit einem Programm die Pins abfragen und darauf reagieren. Der Hardwareteil funktioniert wie gewünscht, aber beim Programmieren hapert es.

Fürs erste verwende ich zwei Dateien im sysfs, von denen mir eine den Status eines Tasters liefert und die andere ermöglicht es mir eine LED ein- und auszuschalten. Fürs erste will ich also nur eine LED auf etwas komplizierte Art ein- und ausschalten können:

Code: Alles auswählen

import sys
import time

print "Hello gpio!"

def read_button():
        f1 = open("/sys/class/gpio/gpio3_pg3/value","r")
        value = f1.read()
        return value
        f1.close()

def write_led(value):
        f2 =  open("/sys/class/leds/white:ph11:led3/brightness","w")
        f2.write(str(value))
        f2.close()

while True:
        button_value =  read_button()
        write_led(button_value)
Das funktioniert zwar, erzeugt aber laut top 100% CPU-Last und läßt die Temperatur sofort um 2-3°C ansteigen. Gibt es vielleicht eine Möglichkeit eine Datei (im sysfs) auf (kurzzeitige und vorrübergehende) Veränderungen zu überwachen oder hat jemand eine Idee wie man das anders lösen kann?

(Außerdem erzeugte nach dem Abbruch mit ^C aus für mich unerfindlichen Gründen udev eine CPU-Last von ~80%. Das ist zwar vielleicht wieder recht hardwarespezifisch, aber falls jemand auch da eine Idee hat, bin ich ganz Ohr.)


viele liebe Grüße, smutbert
Zuletzt geändert von smutbert am 22.06.2014 12:36:53, insgesamt 1-mal geändert.

Benutzeravatar
smutbert
Beiträge: 8342
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: python (oder auch C) - ständig laufende Abfrage

Beitrag von smutbert » 22.06.2014 10:55:32

Ok, also ein paar Dinge habe ich herausgefunden:

Die fiese CPU-Last von udev rührt vom Schreiben in das sysfs, wenn ich das nur bei tatsächlichen Änderungen mache und nicht automatisch bei jedem Schleifendurchgang, verbessert sich das ganze schon deutlich — dann schafft meine Schleife auch statt <3000 Durchgängen/Sekunde mehr als 10000.
Auch habe ich mich mit dem Taster gespielt, um herauszufinden, wie lange eine normale Tasterbetätigung ca. dauert. Herausgekommen ist, dass ich 50 Schleifendurchgänge/Sekunde benötige um wirklich jede Betätigung zu registrieren, wenn ich mich mit fast jeder Betätigung begnüge reichen auch ~15 Durchgänge in der Sekunde. Baue ich ein entsprechendes time.sleep(float(x)/1000) ein, lande ich damit immerhin schon bei höchstens 5% CPU-Last.

Ich weiß ja nicht, ob sich überhaupt jemand die Mühe macht, das zu lesen, aber ich frage mich, ob es nicht eine elegantere Lösung für das Problem gibt. Kennt zB vielleicht jemand einen Weg eine Schleife etwa 50 Mal/Sekunde laufen zu lassen, ohne dass ich einen fixen Wert für ein sleep-Kommando angeben müsste?

Noch schöner wäre es natürlich, wenn die Änderung der Datei im sysfs ein etwas auslösen könnte, aber dafür habe ich keine Möglichkeit gefunden.

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: python (oder auch C) - ständig laufende Abfrage

Beitrag von Cae » 22.06.2014 11:21:15

Generell will man sowas per Interrupts machen, weil Polling, wie du bereits festgestellt hast, ziemlich ineffizient ist. Ich bin mir nicht sicher, ob das im sysfs funktioniert, aber inotifywait aus Debianinotify-tools geht in die Richtung. Man registriert sich eine bestimmte Veraenderung an einer Datei und bekommt aktiv einen Hinweis darauf, dass diese Veraenderung gerade stattgefunden hat. Fuer inotify gibt's ziemlich wahrscheinlich auch C- und auch Python-Bindings.

Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Benutzeravatar
smutbert
Beiträge: 8342
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: python (oder auch C) - ständig laufende Abfrage

Beitrag von smutbert » 22.06.2014 12:36:07

Ok, danke. Deine Stichworte haben meine Suchergebnisse gleich um einiges verbessert, auch wenn das Ergebnis ernüchternd ist:
[…]
> Can I user inotify with sysfs?

No.
[…]
https://www.mail-archive.com/kernelnewb ... 07651.html

Interrupts funktionieren offensichtlich auch nicht, denn sonst gäbe es, laut dem was ich gelesen habe die Datei /sys/class/gpio/gpio3_pg3/edge, mit der ich festlegen könnte, ob bei steigender und/oder fallender Flanke ausgelöst wird :( Aber vielleicht finde ich am Cubietruck ja noch andere gpio-Pins, die das unterstützen.

Sonst bleibe ich beim Polling und lasse die Scheife möglichst lange schlafen.
Zuletzt geändert von smutbert am 22.06.2014 14:57:54, insgesamt 1-mal geändert.

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: (erledigt) python (oder auch C) - ständig laufende Abfra

Beitrag von Cae » 22.06.2014 13:45:16

Noch was zum Thema [1,2]. Zwar fuer den Pi, aber das Prinzip ist dasselbe: Man registriert einen Interrupt und wird aktiv informiert, sobald sich der Zustand aendert. Insbesondere der bei [1] indirekt (wget-Zeilen) verlinkte Quellcode ist interessant, offensichtlich kann man effizient per epoll_wait(2) eine Datei bzw. einen Stream auf neue/geaenderte Daten hin ueberwachen.

Gruss Cae

[1] http://raspi.tv/2013/how-to-use-interru ... d-rpi-gpio
[2] http://www.raspberrypi.org/forums/viewt ... =44&t=7509
[3] http://sourceforge.net/projects/raspberry-gpio-python/
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Antworten