News    The Project    Technology    RoboSpatium    Contribute    Subject index    Download    Responses    Games    Shopping tips    Contact   




<<< Python: Pulse-width modulation         Python: Commandline parameters >>>

Python: Background activity

The circuit used in this chapter

Switching LEDa and a servo via a GPIO using Python
Figure 1:
Two LEDs and a servo are switched in the examples of this chapter. The servo should be a microservo (also called a 9g servo), as these draw less current than standard servos.
More about how to connect LEDs to GPIOs is written in the chapter on switching LEDs via GPIOs.
Which pins have which function can be found in the chapter on the hardware of the Raspberry Pi.

Change parameters without restarting a script

So far we always had to restart a Python script in order to be able to change parameters within the program. In this chapter I want to show how you can do this while the program is running. A common way of transferring data to a running program is to read special command files. To do this, the program must constantly check whether a certain file existse and, should that be the case, read the parameters it contains. In the following example the name of the file is "ParameterGPIO.txt" and it must be stored in the directory "/home/pi/":
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")    
    

Store the script in the directory "/home/pi/background.py" and declare it to be executable:
chmod a+x background.py

To make the program run in background, it must be started with an "&" at the end of the command line:
./background.py&

If the program is running in the background, you can transfer parameters to it by generating a file with the name "/home/pi/ParameterGPIO.txt" and writing a command line into it. This can be done with the "echo" command. In order to switch on the LED on pin 16 with 40% pulse width, the needed command line is:
echo GPIO16 0.4 > /home/pi/ParameterGPIO.txt

To turn the servo lever for 90° clockwise use:
echo GPIO12 -1.0 > /home/pi/ParameterGPIO.txt

To turn the servo lever 90° counterclockwise use:
echo GPIO12 1.0 > /home/pi/ParameterGPIO.txt

If you write a non valid parameter for the servo lever into the file, an error message is displayed:
echo GPIO12 -2.0 > /home/pi/ParameterGPIO.txt

Using correct upper and lower case is important! For example the command:
echo Gpio12 -2.0 > /home/pi/ParameterGPIO.txt
is simply ignored!

You can no longer end the execution of the script by pressing 'ctrl+c', because keyboard inputs are not forwarded to programs running in background. To end the script, you can type the command:
killall python

Services

Such a program running in the background is also known as a service or daemon. In the chapter on pulse width modulation it was already pointed out that the functions of "gpiozero" in Python only work if the corresponding "daemon", which is a program called "pigpiod", is running in the background. That program monitors the file "/dev/pigpio". This means that the LED on pin 16 can also be set to a duty cycle of 40% from the command line without a Python script using the command:
echo "p 23 40" > /dev/pigpio
Note that this command does not use physical numbering for the GPIOs, but the numbering as displayed by the command:
pinout
The physical pin 16, to which an LED is connected in our example above, corresponds to GPIO 23 on a Raspberry Pi 1, Model B+.
In contrast to our Python script, the pigpiod program can handle a lot more commands and it can access all of the GPIOs on your Raspberry Pi - not only the 3 GPIOs in the example script above. The advantage of our script, however, is that we can very quickly add any commands needed, even those that are not implemented in pigpiod.


<<< Python: Pulse-width modulation         Python: Commandline parameters >>>


News    The Project    Technology    RoboSpatium    Contribute    Subject index    Archives    Download    Responses    Games    Links    Shopping tips    Contact    Imprint   





Twitter YouTube Hackaday Patreon TPO