RPI.GPIO
使用手冊
1 導(dǎo)入模塊
import RPi.GPIO as GPIO
通撑枪颍可以try catch
該導(dǎo)入語句來檢查導(dǎo)入是否成功
2 引腳號
在RPi.GPIO
中揪阿,有兩種方法可以對Raspberry Pi
上的IO引腳
進(jìn)行編號。第一種是使用BOARD
編號系統(tǒng)包警。這是指Raspberry Pi
板上P1
接頭上的引腳號。使用這種編號系統(tǒng)的優(yōu)點(diǎn)是底靠,無論樹莓派的電路板版本如何害晦,您的硬件都能正常工作。你不需要重新連接你的連接器或更改你的代碼暑中。
第二個編號系統(tǒng)是BCM
號碼壹瘟。這是一種較低級別的工作方式 - 它指的是Broadcom SOC
上的通道號碼。您必須始終使用那個通道編號所對應(yīng)的樹莓派板上哪個引腳的圖表鳄逾。您的腳本程序可能會在Raspberry Pi
板的硬件修訂后而不能使用稻轨。
要指定您使用引腳編號方式:
GPIO.setmode(GPIO.BOARD)
# or
GPIO.setmode(GPIO.BCM)
通過mode = GPIO.getmode()
可以檢查設(shè)置的引腳編號方式
3警告
您可能在Raspberry Pi
的GPIO
上有多個腳本/電路。因此雕凹,如果RPi.GPIO
檢測到引腳已被配置為默認(rèn)(輸入)以外的其他引腳殴俱,則在嘗試配置腳本時會收到警告。要禁用這些警告:
GPIO.setwarnings(False)
4枚抵、設(shè)置一個通道
您需要設(shè)置您用作輸入或輸出的每個通道线欲。將通道配置為輸入:
GPIO.setup(channel, GPIO.IN)
(其中通道是基于您指定的編號系統(tǒng)(BOARD
或BCM
)的通道編號)。
有關(guān)設(shè)置輸入通道的更多高級信息可以在這里找到汽摹。
要將通道設(shè)置為輸出:
GPIO.setup(channel, GPIO.OUT)
您還可以為您的輸出通道指定一個初始值:
GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)
4李丰、設(shè)置多個頻道
您可以一次設(shè)置多個通道(從0.5.8
開始)。例如:
chan_list = [ 11 逼泣,12 ] #加你想盡可能多的渠道趴泌!
#你可以用元組代替舟舒,即:
#chan_list =(11,12)
GPIO.setup(chan_list, GPIO.OUT)
輸入
讀取GPIO
引腳的值:
GPIO.input(channel)
( 其中通道是基于您指定的編號系統(tǒng)(BOARD或BCM)的通道編號)。這將返回0 / GPIO.LOW / False或1 / GPIO.HIGH / True嗜憔。
有幾種方法可以將GPIO
輸入到您的程序中秃励。第一種也是最簡單的方法是在某個時間點(diǎn)檢查輸入值。這就是所謂的“輪詢”吉捶,如果你的程序在錯誤的時間讀取了值莺治,可能會錯過輸入。輪詢在循環(huán)中執(zhí)行帚稠,并可能是處理器密集型的谣旁。響應(yīng)GPIO
輸入的另一種方式是使用'中斷'(邊沿檢測)。邊沿是從高電平到低電平(下降沿)或從低電平到高電平(上升沿)的意思滋早。
5.1 上拉/下拉電阻
如果你沒有連接到任何輸入引腳榄审,它將'浮空'。換句話說杆麸,讀入的值是未定義的搁进,因?yàn)樗挥性诎聪掳粹o或開關(guān)時才會連接到任何東西。由于引腳會接收到干擾昔头,可能讀取到變化的值饼问。
為了解決這個問題,我們使用上拉或下拉電阻揭斧。這樣莱革,可以設(shè)置輸入的默認(rèn)值《锟可以在硬件上使用上拉/下拉電阻并使用軟件盅视。在硬件中,通常使用輸入通道和3.3V
(上拉)或0V
(下拉)之間的10K
電阻旦万。RPi.GPIO
模塊允許您配置Broadcom SOC
以在軟件中執(zhí)行此操作:
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# or
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
(其中通道是基于您指定的編號系統(tǒng)的通道編號 - BOARD或BCM)
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# or
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
5.2 測試輸入(輪詢)
您可以立即讀取IO引腳的輸入值:
if GPIO.input(channel):
print('Input was HIGH')
else:
print('Input was LOW')
要通過輪詢輪詢等待按鈕按下
while GPIO.input(channel) == GPIO.LOW:
time.sleep(0.01) # wait 10 ms to give CPU chance to do other things
中斷和邊緣檢測
邊沿是電信號從低電平變?yōu)楦唠娖剑ㄉ仙兀┗驈母唠娖阶優(yōu)榈碗娖剑ㄏ陆笛兀┑臓顟B(tài)變化闹击。很多時候,我們更關(guān)心輸入狀態(tài)的變化而非價值成艘。這種狀態(tài)變化是一個事件赏半。
為了避免在程序忙于做其他事情時按下按鈕,有兩種方法可以解決這個問題:
wait_for_edge()
函數(shù)
event_detected()
函數(shù)
在檢測到邊緣時運(yùn)行線程的回調(diào)函數(shù)
wait_for_edge()
函數(shù)
wait_for_edge()
函數(shù)設(shè)計(jì)用于阻止程序的執(zhí)行淆两,直到檢測到邊緣断箫。換句話說,上面等待按鈕按下的示例可以被重寫為:
GPIO.wait_for_edge(channel, GPIO.RISING)
請注意琼腔,您可以檢測GPIO.RISING
瑰枫,GPIO.FALLING
或GPIO.BOTH
類型的邊沿。這樣做的好處是它使用的CPU
時間可以忽略不計(jì)丹莲,因此CPU
還有很多工作要做光坝。
如果您只想等待一段時間,則可以使用timeout
參數(shù):
#上升沿等待最多5秒(超時以毫秒為單位)
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000)
if channel is None:
print('Timeout occurred')
else:
print('Edge detected on channel', channel)
event_detected()函數(shù)
event_detected()函數(shù)設(shè)計(jì)用于與其他工作一起循環(huán)使用甥材,但與輪詢不同盯另,在CPU忙于處理其他事情時,不會錯過輸入狀態(tài)的變化洲赵。當(dāng)使用類似Pygame或PyQt的東西時鸳惯,這可能很有用,因?yàn)橹餮h(huán)會及時監(jiān)聽和響應(yīng)GUI事件叠萍。
GPIO.add_event_detect(channel, GPIO.RISING) # add rising edge detection on a channel
do_something()
if GPIO.event_detected(channel):
print('Button pressed')
請注意芝发,您可以檢測GPIO.RISING,GPIO.FALLING或GPIO.BOTH的事件苛谷。
Threaded
回調(diào)
RPi.GPIO
為回調(diào)函數(shù)運(yùn)行第二個線程辅鲸。這意味著回調(diào)函數(shù)可以與主程序同時運(yùn)行,并立即響應(yīng)邊緣事件腹殿。例如:
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) # add rising edge detection on a channel
...the rest of your program...
如果你想要多個回調(diào)函數(shù):
ef 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)
請注意独悴,在這種情況下,回調(diào)函數(shù)按順序運(yùn)行锣尉,而不是同時運(yùn)行刻炒。這是因?yàn)橹挥幸粋€線程用于回調(diào),每個回調(diào)都按照定義的順序運(yùn)行自沧。
5.4開關(guān)抖動
您可能會注意到坟奥,每次按下按鈕都會多次調(diào)用回調(diào)。這是所謂的“開關(guān)抖動”的結(jié)果拇厢。處理抖動有兩種方法:
在開關(guān)輸入腳上添加一個0.1uF
的電容筏勒。
軟件去除抖動
以上兩種方法的結(jié)合
要使用軟件去抖動,請將bouncetime =參數(shù)
添加到指定回調(diào)函數(shù)的函數(shù)中旺嬉。抖動時間應(yīng)以毫秒為單位指定管行。例如:
#在通道上添加上升沿檢測,忽略處理
GPIO的開關(guān)抖動操作的進(jìn)一步邊緣200ms 邪媳。
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback, bouncetime=200)
要么
GPIO.add_event_callback(channel, my_callback, bouncetime=200)
5.5 刪除事件檢測
如果由于某種原因捐顷,您的程序不再希望檢測邊緣事件,則可以刪除它們:
GPIO.remove_event_detect(channel)
6雨效、輸出
要設(shè)置GPIO
引腳的輸出狀態(tài)迅涮,請執(zhí)行以下操作:
GPIO.output(channel, state)
(其中通道是基于您指定的編號系統(tǒng)(BOARD或BCM)的通道編號)。
狀態(tài)可以是0 / GPIO.LOW / False或1 / GPIO.HIGH / True徽龟。
A.設(shè)置輸出高電平:
GPIO.output(12, GPIO.HIGH)
# or
GPIO.output(12, 1)
# or
GPIO.output(12, True)
B.設(shè)置輸出低電平:
GPIO.output(12, GPIO.LOW)
# or
GPIO.output(12, 0)
# or
GPIO.output(12, False)
7叮姑、輸出到幾個通道
您可以一次設(shè)置輸出多個頻道(從0.5.8
開始)。例如:
chan_list = [11,12] # also works with tuples
GPIO.output(chan_list, GPIO.LOW) # sets all to GPIO.LOW
GPIO.output(chan_list, (GPIO.HIGH, GPIO.LOW)) # sets first HIGH and second LOW
8.在RPi.GPIO
中使用PWM
要創(chuàng)建一個PWM
實(shí)例:
p = GPIO.PWM(channel, frequency)
要啟動PWM:
p.start(dc) # where dc is the duty cycle (0.0 <= dc <= 100.0)
要更改頻率:
p 。ChangeFrequency (freq ) #其中freq是以Hz為單位的新頻率
要改變占空比:
p.ChangeDutyCycle(dc) # where 0.0 <= dc <= 100.0
要停止PWM:
p.stop()
請注意传透,如果實(shí)例變量'p'超出范圍耘沼,PWM也會停止。
每兩秒閃爍一次LED
的示例:
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
p = GPIO.PWM(12, 0.5)
p.start(1)
input('Press return to stop:') # use raw_input for Python 2
p.stop()
GPIO.cleanup()
增亮/調(diào)暗LED
的示例:
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
p = GPIO.PWM(12, 50) # channel=12 frequency=50Hz
p.start(0)
try:
while 1:
for dc in range(0, 101, 5):
p.ChangeDutyCycle(dc)
time.sleep(0.1)
for dc in range(100, -1, -5):
p.ChangeDutyCycle(dc)
time.sleep(0.1)
except KeyboardInterrupt:
pass
p.stop()
GPIO.cleanup()
9朱盐、GPIO
恢復(fù)默認(rèn)
在程序的末尾群嗤,清理您可能使用的任何資源是一種很好的做法。這與RPi.GPIO
沒有什么不同兵琳。通過將您用過的所使用的通道返回到到無上拉/下拉輸入的狀態(tài)狂秘,這樣可以避免短接GPIO
引腳來導(dǎo)致意外損壞您的樹莓派。請注意躯肌,這樣只會清除你寫的腳本中使用的GPIO
通道者春。請注意,GPIO.cleanup()
也會清除正在使用的引腳編號系統(tǒng)清女。
在你的腳本程序的末尾寫上:
GPIO.cleanup()
當(dāng)您的程序退出時钱烟,可能不希望清理每個通道,而留下一些設(shè)置校仑。您可以清理個別通道忠售,使用通道的元組或列表做為參數(shù)輸入:
GPIO.cleanup(channel)
GPIO.cleanup( (channel1, channel2) )
GPIO.cleanup( [channel1, channel2] )
10、RPi
板信息和RPi.GPIO
版本
發(fā)現(xiàn)有關(guān)您的RPi
的信息:
GPIO.RPI_INFO
發(fā)現(xiàn)Raspberry Pi電路板版本:
GPIO.RPI_INFO [ 'P1_REVISION']
GPIO.RPI_REVISION(不建議使用)
要發(fā)現(xiàn)RPi.GPIO的版本:
GPIO.VERSION
11迄沫、編寫一個測試程序blinkled.py
這個測試程序控制樹莓派上一GPIO 25
每2秒變化一個電平稻扬,如果接一個LED
燈到這個IO
上面,就會看到這個燈亮2秒滅2秒
羊瘩。
#!/usr/bin/python
#*coding:utf-8*
#GPIO控制LED燈程序
import RPi.GPIO as GPIO
import time
pin = 25
GPIO.setmode(GPIO.BCM)
GPIO.setup(pin, GPIO.OUT)
while True:
GPIO.output(pin, GPIO.HIGH)
time.sleep(2)
GPIO.output(pin, GPIO.LOW)
time.sleep(2)
https://blog.csdn.net/fhqlongteng/article/details/80395059
https://sourceforge.net/p/raspberry-gpio-python/wiki/BasicUsage/