Neuigkeiten    Das Projekt    Technik    RoboSpatium    Unterstützung    Stichwortverzeichnis    Download    Reaktionen    Spiele    Gadgets    Kontakt   




<<< Python: Puslweitenmodulation         Python: Kommandozeilenparameter >>>

Python: Hintergrundaktivität

Der Schaltplan zum Kapitel

Schalten fon LEDs und einem Seervo mittels Python
Abbildung 1:
Zwei LEDs und ein Servo werden in den Beispielen dieses Kapitels geschaltet. Das Servo sollte ein Microservo (auch 9g Servo genannt) sein, da diese einen geringeren Strom ziehen als Standardservos.
Alles zum korrekten Anschließen von LEDs an GPIOs gibt's im Kapitel zu LEDs mit Hilfe von GPIOs schalten.
Welche Pins welche Funktion haben, ist im Kapitel zur Hardware des Raspberry Pi nachzulesen.

Parameter ändern, ohne das Programm neu zu starten

Bislang haben wir ein Python Skript immer neu starten müssen, um Parameter innerhalb des Programmes ändern zu können. In diesem Kapitel möchte ich zeigen, wie man das auch machen kann, während das Programm läuft. Ein üblicher Weg, Daten an ein laufendes Programm zu übergeben, besteht im Einlesen von Dateien. Das Programm muss dazu ständig prüfen, ob eine bestimmte Datei vorhanden ist und sollte das der Fall sein, die darin enthaltenen Parameter einlesen. In dem folgenden Beispiel lautet der Name der Datei "ParameterGPIO.txt" und diese muss in dem Verzeichnis "/home/pi/" liegen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/env python    
   
from time import sleep  # needed to make command "sleep" available    
from gpiozero import Device, Servo  # Needed for Servo control signals  
from gpiozero import Device, PWMLED # needed to switch LED with pwm  
 
# The older Raspberry Pi 1 or Pi Zero require to set the pin factory    
from gpiozero.pins.pigpio import PiGPIOFactory  
 
import os      # needed for file operations  
   
try: # Watch for interrupt events    
   
    # Pin factory for older Raspberry Pi models    
    Device.pin_factory = PiGPIOFactory()    
   
    # Control line of Servo connected to pin 1_12 on Raspberry Pi    
    servo12 = Servo("BOARD12")    
      
    # LEDs connected to pins 16 and 22  
    pwm16 = PWMLED("BOARD16", True, 0, 100)    
    pwm22 = PWMLED("BOARD22", True, 0, 100)      
    
    while (1 == 1): # This while loop runs forever    
   
        # Look if the parameter file exists  
        if os.path.isfile("/home/pi/ParameterGPIO.txt"):   
            print("Parameter file detected, analyzing content")  
              
            try:   
                # Open the parameter file  
                f = open("/home/pi/ParameterGPIO.txt", "r")  
                command = f.readline() # Read first line of file  
                commandDone = 0  
                  
                # compare first 6 characters of command line  
                if command[0:6] == "GPIO12": # Command to set servo  
                    # Parameter is number after first 6 characters  
                    servoAngle = float(command[6:])  
                    # Make sure parameter is inside allowed range  
                    if servoAngle >= -1.0 and servoAngle <= 1.0:  
                        servo12.value = servoAngle  # Set servo angle  
                        print("Servo set to " + str(servoAngle))  
                    else:  
                        print("Servo " + str(servoAngle) + " out of range ( -1.0 to 1.0)!")  
                    commandDone = 1  
 
                # compare first 6 characters of command line  
                if command[0:6] == "GPIO16": # Command to set LED 16  
                    # Parameter is number after first 6 characters  
                    dutyCycle16 = float(command[6:])  
                    # Make sure parameter is inside allowed range  
                    if dutyCycle16 >= 0.0 and dutyCycle16 <= 1.0:  
                        pwm16.value = dutyCycle16   
                        print("LED 16 set to " + str(dutyCycle16))  
                    else:  
                        print("Dutycycle16 " + str(dutyCycle16) + " out of range ( 0.0 to 1.0)!")  
                    commandDone = 1  
                      
                # compare first 6 characters of command line  
                if command[0:6] == "GPIO22": # Command to set LED 22  
                    # Parameter is number after first 6 characters  
                    dutyCycle22 = float(command[6:])  
                    # Make sure parameter is inside allowed range  
                    if dutyCycle22 >= 0.0 and dutyCycle22 <= 1.0:  
                        pwm22.value = dutyCycle22  
                        print("LED 22 set to " + str(dutyCycle22))  
                    else:  
                        print("Dutycycle22 " + str(dutyCycle22) + " out of range ( 0.0 to 1.0)!")  
                    commandDone = 1  
                f.close()  
                  
                if commandDone == 1:  
                    print("Command executed, GPIO set.")  
                else:  
                    print("No valid command found!")  
                # Remove file to make clear that operation was executed  
                os.remove("/home/pi/ParameterGPIO.txt")  
                  
            except IOError: # Print message if a file error has happened  
                print("Error handling Parameter file!")             
                  
        sleep(1.0) # slow down loop speed to lower CPU load  
   
except KeyboardInterrupt:      
    # This is the code section executed after 'ctrl+c' is pressed    
    # Script ends after that section.    
    print ("...keyboard interrupt detected\n")    
    

Speichert dieses Skript unter "/home/pi/background.py" und macht es ausführbar:
chmod a+x background.py

Damit das Programm im Hintergrund läuft, muss dieses mit einem '&' Zeichen am Ende der Befahlszeile gestartet werden:
./background.py&

Läuft das Programm im Hindergrund, so könnt ihr Parameter an dieses übergeben, indem ihr eine Datei mit Namen "/home/pi/ParameterGPIO.txt" generiert und in diese eine Befehlszeile schreibt. Das kann mit dem Befehl "echo" gemacht werden. Um somit die LED an Pin 16 mit 40% Pulsweite einzuschalten, lautet der Befehl:
echo GPIO16 0.4 > /home/pi/ParameterGPIO.txt

Den Servohebel auf 90° im Uhrzeigersinn zu drehen, geht mit:
echo GPIO12 -1.0 > /home/pi/ParameterGPIO.txt

Den Servohebel auf 90° entgegen dem Uhrzeigersinn zu drehen, geht mit:
echo GPIO12 1.0 > /home/pi/ParameterGPIO.txt

Übergebt ihr für das Servo einen ungültigen Parameter, so erscheint eine Fehlermeldung:
echo GPIO12 -2.0 > /home/pi/ParameterGPIO.txt

Wichtig ist die korrekte Groß- und Kleinschreibung! So wird der Befehl:
echo Gpio12 -2.0 > /home/pi/ParameterGPIO.txt
schlicht und einfach ignoriert!

Ihr könnt das Skript nicht mehr mit der Tastenkombination 'ctrl+c' beenden, da im Hintergrund laufende Prozesse keine Tastatureingaben erhalten. Um das Skript dennoch zu beenden, muss der Befehl:
killall python
eingegeben werden.

Dienste

Ein derartiges, im Hintergrund laufendes Programm bezeichnet man auch als Dienst, Service oder Daemon. Im Kapitel zu Pulsweitenmodulation wurde bereits darauf hingewiesen, dass die Funktionen von "gpiozero" in Python nur funktionieren, wenn der entsprechende "Daemon", also ein Programm namens "pigpiod" im Hintergrund läuft. Das Programm überwacht die Datei "/dev/pigpio". Somit kann die LED an Pin 16 auch ohne ein Python Skript von der Kommandozeile durch den Befehl:
echo "p 23 40" > /dev/pigpio
mit einer Pulsweite von 40% eingeschaltet werden. Zu beachten ist, dass dieser Befehl nicht die physische Nummerierung verwendet, sondern die Nummerierung wie sie der Befehl:
pinout
für die GPIOs ausgibt. Der physische Pin 16, an dem in unserem Beispiel eine LED angeschlossen ist, entspricht GPIO 23 an einem Raspberry Pi 1, Model B+.
Im Gegensatz zu unserem Python Skript beherrscht das Programm pigpiod wesentlich mehr Befehle und kann auf alle GPIOs zugreifen - nicht nur auf die 3 GPIOs in dem Beispielskript zu diesem Kapitel. Der Vorteil unseres Skripts liegt aber darin, dass wir sehr schnell beliebige Befehle, selbst solche die pigpiod nicht beherrscht, hinzufügen können.


<<< Python: Puslweitenmodulation         Python: Kommandozeilenparameter >>>


Neuigkeiten    Das Projekt    Technik    RoboSpatium    Unterstützung    Stichwortverzeichnis    Archiv    Download    Reaktionen    Spiele    Verweise    Gadgets    Kontakt    Impressum   





Twitter YouTube Hackaday Patreon TPO