Basic introduction to GPIO
GPIO (General Purpose I/O Ports) means general input / output ports. Generally speaking, it is some pins that can output high and low levels or read the status of pins - high level or low level. GPIO is an important concept. Users can interact with hardware through GPIO port (such as UART), control hardware work (such as LED, buzzer, etc.), and read hardware working status signals (such as interrupt signals). GPIO port is widely used. Mastering GPIO is almost equivalent to mastering the ability to operate hardware.
How are the 40 pins numbered?
If it is numbered according to the physical position, it is easy to remember as long as you master a rule: the pin closest to the corner is pin 2, and next to it is pin 1.
The 40 pins are defined by different numbering rules. Although the names of different rules are different, their actual purposes are the same. Here, only one numbering rule, that is, physical location number, is learned, which makes it easier to make physical connection.
For example, pin 1 outputs a 3.3V voltage, that is, if the voltage of this pin is measured with a digital multimeter, it will always be a constant and unchangeable 3.3V. Pin 2 is the same as pin 4, but the output voltage is 5V.
Pin 6 is a GND, that is, ground. If the voltage is measured, it is 0 V. (9, 14, 20, 25, 30, 34 and 39 are the same)
Pin 11 is a green icon. In fact, this interface is an ordinary interface, which can be input or output. If it is set to output, high voltage or low voltage can be output. The output high voltage is 3.3 volts and the output low voltage is 0 volts. It can be controlled by program.
Control GPIO
The most convenient way to use python to control GPIO is to use some python class libraries, such as RPi.GPIO integrated by raspberry pie system itself. This article describes in detail how to use RPi.GPIO to control GPIO.
Import RPi.GPIO module
You can import the RPi.GPIO module with the following code.
import RPi.GPIO as GPIO
After the introduction, you can use the functions of the GPIO module. If you want to check whether the module is successfully introduced, you can also write this:
try: import RPi.GPIO as GPIO except RuntimeError: print("Introduction error")
Pin number
In RPi.GPIO, two GPIO PIN numbers on raspberry pie are supported at the same time. The first number is the BOARD number, which corresponds to the physical pin number on the raspberry pie circuit BOARD. The advantage of using this number is that your hardware will always be available without worrying about the version of raspberry pie. Therefore, after the circuit BOARD is upgraded, you do not need to rewrite the connector or code.
The second number is the BCM rule, which is a lower level working mode. It corresponds to the channel number in Broadcom's on-chip system. When using a pin, you need to find the corresponding rules between the channel number and the physical pin number. For different versions of raspberry pie, the script file may not be universal.
You can specify a numbering scheme using the following code (mandatory):
GPIO.setmode(GPIO.BOARD) # or GPIO.setmode(GPIO.BCM)
The following code will return the number sequence set
mode = GPIO.getmode()
warning
If RPi.GRIO detects that a pin has been set to a non default value, you will see a warning message. You can disable warnings with the following code:
GPIO.setwarnings(False)
Pin setting
Before using a pin, you need to set these pins as input or output. The code for configuring one pin is as follows:
# Set pin to input mode GPIO.setup(channel, GPIO.IN) # Set pin to output mode GPIO.setup(channel, GPIO.OUT) # Sets the default value for the output pin GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)
release
Generally speaking, the program needs to release resources at the end. This good habit can avoid accidental damage to raspberry pie. Release the pins used in the script:
GPIO.cleanup()
Note that GPIO.cleanup() will only release the GPIO pins used in the script and clear the set pin numbering rules.
output
If you want to light an LED lamp or drive a device, you need to give them current and voltage. This step is also very simple. Just set the output state of the pin. The code is as follows:
The status can be set to 0 / gpio.low/false/1/gpio.high/true. If the encoding rule is GPIO.BOARD, then channel is the number of the corresponding pin.
If you want to set more than one pin at a time, you can use the following code:
chan_list = [11,12] GPIO.output(chan_list, GPIO.LOW) GPIO.output(chan_list, (GPIO.HIGH, GPIO.LOW))
You can also use the Input() function to read the state of an output pin and take it as the output value, for example:
GPIO.output(12, not GPIO.input(12))
read
We also often need to read the input status of the pin and obtain the pin input status as follows:
GPIO.input(channel)
Low level returns 0 / gpio.low/false, high level returns 1 / gpio.high/true.
If the input pin is suspended, the value of the pin will drift. In other words, the read value is unknown because it is not connected to any signal until a button or switch is pressed. Due to the influence of interference, the input value may change repeatedly.
Use the following code to solve the problem:
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP) # or GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
It should be noted that the above reading code only obtains the pin input signal at the current moment.
There are two ways to monitor the status changes of pins in real time. The simplest and original way is to check the input signal value at regular intervals, which is called polling. If your program reads at the wrong time, it is likely to lose the input signal. Polling is performed in a loop, which is more processor intensive. Another way to respond to GPIO input is to use interrupt (edge detection), where the edge refers to the transformation of the signal from high to low (falling edge) or from low to high (rising edge).
Polling mode
while GPIO.input(channel) == GPIO.LOW: time.sleep(0.01) # wait 10 ms to give CPU chance to do other things
edge detection
Edge refers to the change of signal state, from low to high (rising edge) or from high to low (falling edge). In general, we are more concerned with this side of the input state than the value of the input signal. This side of this state is called an event.
Two functions are introduced first:
- wait_for_edge() function.
wait_for_edge() is used to prevent the program from continuing until an edge is detected. That is, the example of waiting for the button to be pressed in the above can be rewritten as:
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000) if channel is None: print('Timeout occurred') else: print('Edge detected on channel', channel)
- add_event_detect() function
This function monitors a pin. Once the pin input state changes, call event_ The detected() function will return true, as shown in the following code:
GPIO.add_event_detect(channel, GPIO.RISING) # add rising edge detection on a channel do_something() // The following code is executed in a thread loop. if GPIO.event_detected(channel): print('Button pressed')
The above code needs to create a new thread to detect the event loop_ The value of detected () is troublesome.
However, another way to easily detect the status is to directly pass in a callback function:
def my_callback(channel): print('This is a edge event callback function!') print('Edge detected on channel %s'%channel) print('This is run in a different thread to your main program') GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback)
If you want to set multiple callback functions, you can:
def my_callback_one(channel): print('Callback one') def my_callback_two(channel): print('Callback two') GPIO.add_event_detect(channel, GPIO.RISING) GPIO.add_event_callback(channel, my_callback_one) GPIO.add_event_callback(channel, my_callback_two)
Note: when the callback is triggered, the callback functions will not be executed at the same time, but will be called according to the set order.
Comprehensive example: Lighting LED
Well, the above explains the usage of a lot of function libraries, so it's time to have a simple experiment. This experiment is very simple. Light up an LED light.
- Before writing code, first you need to connect the pin of led lamp to the pin of raspberry pie through DuPont wire. For example, you can connect to pin 11.
- Create a new main.py file and write the following code:
import RPi.GPIO as GPIO //Introduce function library import time RPi.GPIO.setmode(GPIO.BOARD) //Set pin numbering rules RPi.GPIO.setup(11, RPi.GPIO.OUT) //Set pin 11 to output mode while True GPIO.output(channel, 1) //Set the status of the pin to high level, and the LED is on time.sleep(1) //The program is dormant for 1 second and the LED is on for 1 second GPIO.output(channel, 0) //Set the pin status to low level and the LED is off time.sleep(1) //The program sleeps for 1 second and the LED is off for 1 second GPIO.cleanup() //Don't forget to clear all resources at the end of the program
- Save and exit the file. Execute python3 main.py to view the effect. Ctrl+C to close the program.
- In addition, you might as well try other functions to enhance your impression.
Use PWM
This python function library also supports PWM mode output. We can use PWM to make breathing lamp effect. See code for details:
import time import RPi.GPIO as GPIO //Import and warehousing GPIO.setmode(GPIO.BOARD) //Set numbering method GPIO.setup(12, GPIO.OUT) //Set pin 12 to output mode p = GPIO.PWM(12, 50) //Initialize pin 12 as a PWM instance with a frequency of 50Hz p.start(0) //Start pulse width modulation, parameter range: (0.0 < = DC < = 100.0) try: while 1: for dc in range(0, 101, 5): p.ChangeDutyCycle(dc) //The modified duty cycle parameter range is: (0.0 < = DC < = 100.0) time.sleep(0.1) for dc in range(100, -1, -5): p.ChangeDutyCycle(dc) time.sleep(0.1) except KeyboardInterrupt: pass p.stop() //Stop outputting PWM wave GPIO.cleanup() //eliminate