PIGPIO - Fehlermeldung

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
towi
User
Beiträge: 9
Registriert: Sonntag 6. November 2016, 20:50

Hallo zusammen,

ich bin neu in Eurem Forum und benötige Eure Hilfe.

Ich betreibe auf einem Raspi Pi2 B+ ein Python-Script, in welchem ich über einen Interrupt den Status diverse GPIO-Eingänge erfasse und in eine DB schreibe. Das Script funktioniert mit RPi.GPIO - allerdings werden manche Flanken verkehrt interpretiert und dadurch verkehrt in die DB geschrieben.
Im Raspi-Forum wurde der Einsatz der PIGPIO-Bibliothek empfohlen, woraufhin ich diese installiert habe. Danach wurde mit Hilfe des Raspi-Forums der Code für den Einsatz mit pigpio angepasst.

Nachdem ich den PIGPIO-Dienst per sudo pigpiod gestartet habe kommt kurz nach Start des Python-Scriptes diese Meldung:

Code: Alles auswählen

pi@raspberrypi:~ $ sudo pigpiod
pi@raspberrypi:~ $ sudo /test04.py
Traceback (most recent call last):
 File "/test04.py", line 31, in <module>
   pi.set_mode(gpio, pigpio.INPUT)
 File "/usr/local/lib/python2.7/dist-packages/pigpio.py", line 1161, in set_mod                                                                                        e
   return _u2i(_pigpio_command(self.sl, _PI_CMD_MODES, gpio, mode))
 File "/usr/local/lib/python2.7/dist-packages/pigpio.py", line 943, in _u2i
   raise error(error_text(v))
pigpio.error: 'no permission to update GPIO'
Habe PIGPIO bereits nochmalig deinstalliert und wiederholt installiert. Die installierte Versionsnummer lautet:

Code: Alles auswählen

pi@raspberrypi:~ $ sudo pigpiod -v
58
Würde mich über Eure Hilfe sehr freuen - Gruß towi
BlackJack

@towi: Wie kommt `pi` zustande? Welchen Wert hat `gpio`? Du verwendest die Broadcom-Pin-Nummern?
towi
User
Beiträge: 9
Registriert: Sonntag 6. November 2016, 20:50

Hallo BlackJack,

hier mal das Python Script und JA ich werwende die BOARD-Nummerierung:

Code: Alles auswählen

#!/usr/bin/python
#
# http://www.forum-raspberrypi.de/Thread- ... #pid246631
#

from __future__ import print_function
import pigpio
import Queue
import requests


uuid=dict()
# uuid[<gpio>] = "<id>"
uuid[29] = "c8ef0690-993e-11e6-93bf-05928009d3e3"
uuid[31] = "6c63f740-94b6-11e6-8b55-15bb6ce24a5e"
URL = "http://192.168.178.103/middleware.php/data/{}.json?value={}"


queue = Queue.Queue()
pi = pigpio.pi()
LOOKUP = {}

# ISR
def interrupt_Event(gpio, level, tick):
    queue.put((gpio, level)) # Tuple aus Kanal und HIGH/LOW


try:
    # Interrupt Event fuer jeden gpio hinzufuegen.
    for gpio in uuid:
        pi.set_mode(gpio, pigpio.INPUT)
        pi.set_pull_up_down(gpio, pigpio.PUD_UP)    #GPIO -> 3V3
        pi.callback(gpio, pigpio.EITHER_EDGE, interrupt_Event)
        LOOKUP.update({ (gpio, pigpio.LOW)  : URL.format(uuid.get(gpio), 0) })
        LOOKUP.update({ (gpio, pigpio.HIGH) : URL.format(uuid.get(gpio), 100) })
    
    # Queue abarbeiten
    while True:
        url = LOOKUP[queue.get()]  # blockiert bis Eintrag im queue vorhanden
        requests.post(url)
    
except (KeyboardInterrupt, SystemExit):
    print("\nQuit\n")
Schon mal besten Dank - towi
Zuletzt geändert von Anonymous am Sonntag 6. November 2016, 22:25, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@towi: Ich fragte nach der Broadcom-Nummerierung, nicht nach der Board-Nummerierung. Womit wir wohl auch schon das Problem identifiziert hätten. 29 und 31 gibt es nicht. Du meinst wahrscheinlich 5 und 6.
towi
User
Beiträge: 9
Registriert: Sonntag 6. November 2016, 20:50

Hallo BlackJack,

DANKE .... war genau der richtige Tip ... DANKE ... funktioniert!

Gruß towi
BlackJack

@towi: Noch ein paar Anmerkungen zum Quelltext:

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Funktionsnamen schreibt man per Konvention klein_mit_unterstrichen. KOMPLETT_IN_GROSSBUCHSTABEN nur Konstanten.

`uuid` braucht kein Wörterbuch zu sein. Der Schlüsselzugriff wird nicht benötigt. `get()` noch weniger weil an der Stelle sicher ist, dass der Schlüssel vorhanden ist. Ausserdem wäre `uuid` ein guter Name für *eine UUID* aber nicht für ein Wörterbuch das Pinnummern auf UUIDs abbildet.

`dict.update()` mit einem Wörterbuch mit *einem* Schlüssel/Wert-Paar macht keinen Sinn. Um ein Paar in ein Wörterbuch einzutragen ist die normale []-Syntax gedacht.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/python
from __future__ import print_function
import Queue
from functools import partial

import pigpio
import requests
 
URL = 'http://192.168.178.103/middleware.php/data/{}.json?value={}'


def handle_gpio_event(queue, pin, state, _tick):
    queue.put((pin, state))


def main():
    try:
        pins_and_uuids = [
            (5, 'c8ef0690-993e-11e6-93bf-05928009d3e3'),
            (6, '6c63f740-94b6-11e6-8b55-15bb6ce24a5e'),
        ]
        queue = Queue.Queue()
        pi = pigpio.pi()
        callback = partial(handle_gpio_event, queue)
        pin_and_state2url = dict()
        # 
        # Interrupt Event fuer jeden Pin hinzufuegen.
        # 
        for pin, uuid in pins_and_uuids:
            pi.set_mode(pin, pigpio.INPUT)
            pi.set_pull_up_down(pin, pigpio.PUD_UP)  # GPIO -> 3V3
            pi.callback(pin, pigpio.EITHER_EDGE, callback)
            for state, value in [(pigpio.LOW, 0), (pigpio.HIGH, 100)]:
                pin_and_state2url[(pin, state)] = URL.format(uuid, value)
        #        
        # Queue abarbeiten.
        # 
        while True:
            requests.post(pin_and_state2url[queue.get()])
       
    except KeyboardInterrupt:
        pass  # Intentionally ignored.
    print('\nQuit\n')


if __name__ == '__main__':
    main()
towi
User
Beiträge: 9
Registriert: Sonntag 6. November 2016, 20:50

Hallo BlackJack,

besten Dank für die fachgerechte Überarbeitung - Danke! "Ich spiele halt´ erst Kreisklasse - was das Programmieren betrifft!!!!"

Ich habe aber noch eine Frage: Bei RPi.GPIO gibt´s zur Entprellung der GPIO´s die bouncetime - wie funktioniert das bei PIGPIO. Ich habe einiges ausprobiert(wait...; trigger...) aber leider ohne Erfolg.

Vielleicht hast Du noch einen Tipp dazu - Gruß towi
BlackJack

@towi: Das muss man sich bei PIGPIO selber programmieren.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

@BlackJack eigentlich nicht. Es gibt dort Filterfunktionen - set_glitch_filter und set_noise_filter.
BlackJack

@__deets__: Ups, die Funktionen habe ich glatt übersehen. :oops:
towi
User
Beiträge: 9
Registriert: Sonntag 6. November 2016, 20:50

Hallo __deets__,

danke >>> damit hatte ich es noch nicht probiert.

Gruß towi
towi
User
Beiträge: 9
Registriert: Sonntag 6. November 2016, 20:50

Hallo zusammen,

mit pi.set_glitch_filter(pin, 100000) funktioniert es prima!

Besten Dank un Grus towi !!!
towi
User
Beiträge: 9
Registriert: Sonntag 6. November 2016, 20:50

Hallo zusammen nochmal,

seit dem das Script zur Erfassung der Zustande der GPIO-Eingänge bereits länger ohne Probleme auf dem Pi läuft, wollte ich der graphischen Übersicht halber die values-Pegel in Abhängigkeit der GPIO-Eingänge etwas differenzierter darstellen lassen.
Z.B. sollte bei HIGH-Level am GPIO5 ein Wert von 95 per request an die DB übermittelt werden - bei GPIO6 nur ein Wert von 90 u.s.w.(siehe nachfolgend)

Habe das Script im entsprechenden Teil mal so geändert - klappt leider nicht so, wie ich es mit dachte.

Code: Alles auswählen

 for pin, uuid in pins_and_uuids:
            pi.set_mode(pin, pigpio.INPUT)
            pi.set_pull_up_down(pin, pigpio.PUD_UP)  # GPIO -> 3V3
            pi.set_glitch_filter(pin, 100000)
            pi.callback(pin, pigpio.EITHER_EDGE, callback)
            for pin, state, value in [(( 5, pigpio.LOW, 0), ( 5, pigpio.HIGH, 95)),
                                     (( 6, pigpio.LOW, 0), ( 6, pigpio.HIGH, 90)),
                                               (( 13, pigpio.LOW, 0), ( 13, pigpio.HIGH, 85)),
                                               (( 19, pigpio.LOW, 0), ( 19, pigpio.HIGH, 80))]:
                pin_and_state2url[(pin, state)] = URL.format(uuid, value)
Wie kann mann das fachgerecht machen - kriege das einfach nicht so hin.

MfG - towi
towi
User
Beiträge: 9
Registriert: Sonntag 6. November 2016, 20:50

Sorry,

die Klammerausrichtungen stimmen so leider nicht:

Code: Alles auswählen

 for pin, uuid in pins_and_uuids:
            pi.set_mode(pin, pigpio.INPUT)
            pi.set_pull_up_down(pin, pigpio.PUD_UP)  # GPIO -> 3V3
            pi.set_glitch_filter(pin, 100000)
            pi.callback(pin, pigpio.EITHER_EDGE, callback)
            for pin, state, value in [(( 5, pigpio.LOW, 0), ( 5, pigpio.HIGH, 95)),
                                      (( 6, pigpio.LOW, 0), ( 6, pigpio.HIGH, 90)),
                                      (( 13, pigpio.LOW, 0), ( 13, pigpio.HIGH, 85)),
                                      (( 19, pigpio.LOW, 0), ( 19, pigpio.HIGH, 80))]:
                pin_and_state2url[(pin, state)] = URL.format(uuid, value)
MfG - towi
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@towi: dafür würde man wohl am besten die »pins_and_uuids« Liste erweitern

Code: Alles auswählen

def main():
    try:
        pins_uuids_and_values = [
            (5, 'c8ef0690-993e-11e6-93bf-05928009d3e3', 0, 90),
            (6, '6c63f740-94b6-11e6-8b55-15bb6ce24a5e', 0, 95),
        ]
        queue = Queue.Queue()
        pi = pigpio.pi()
        callback = partial(handle_gpio_event, queue)
        pin_and_state2url = dict()

        # Interrupt Event fuer jeden Pin hinzufuegen.
        for pin, uuid, low_value, hi_value in pins_uuids_and_values:
            pi.set_mode(pin, pigpio.INPUT)
            pi.set_pull_up_down(pin, pigpio.PUD_UP)  # GPIO -> 3V3
            pi.callback(pin, pigpio.EITHER_EDGE, callback)
            pin_and_state2url[pin, pigpio.LOW] = URL.format(uuid, low_value)
            pin_and_state2url[pin, pigpio.HIGH] = URL.format(uuid, hi_value)

        # Queue abarbeiten.
        while True:
            requests.post(pin_and_state2url[queue.get()])
    except KeyboardInterrupt:
        pass  # Intentionally ignored.
    print('\nQuit\n')
BlackJack

@towi: Anzahl und Struktur der Werte in einem Element der Liste passt ganz offensichtlich nicht mit der Anzahl und Struktur der Namen zusammen auf die jedes Element abgebildet werden soll.
towi
User
Beiträge: 9
Registriert: Sonntag 6. November 2016, 20:50

Hallo Sirius3,

besten Dank - :D funktioniert - DANKE

MfG - towi
Antworten