PIGPIO - Fehlermeldung

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

Sonntag 6. November 2016, 21:13

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

Sonntag 6. November 2016, 21:37

@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

Sonntag 6. November 2016, 21:52

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

Sonntag 6. November 2016, 23:01

@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

Montag 7. November 2016, 00:35

Hallo BlackJack,

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

Gruß towi
BlackJack

Montag 7. November 2016, 01:53

@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

Montag 7. November 2016, 22:11

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

Montag 7. November 2016, 22:30

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

Freitag 11. November 2016, 00:25

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

Freitag 11. November 2016, 00:54

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

Samstag 12. November 2016, 21:04

Hallo __deets__,

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

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

Sonntag 13. November 2016, 12:08

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

Mittwoch 4. Januar 2017, 22:16

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

Mittwoch 4. Januar 2017, 22:19

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: 10595
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 4. Januar 2017, 22:30

@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')
Antworten