和我一起玩樹莓派3B+--RPI.GPIO模塊(十一)

一、RPI.GPIO模塊

GPIO(General Purpose I/O Ports)意思為通用輸入/輸出端口,通俗地說,就是一些引腳,可以通過它們輸出高低電平或者通過它們讀入引腳的狀態(tài)-是高電平或是低電平。GPIO是個(gè)比較重要的概念,用戶可以通過GPIO口和硬件進(jìn)行數(shù)據(jù)交互(如UART),控制硬件工作(如LED、蜂鳴器等),讀取硬件的工作狀態(tài)信號(hào)(如中斷信號(hào))等。GPIO口的使用非常廣泛。掌握了GPIO,差不多相當(dāng)于掌握了操作硬件的能力。

二、安裝RPI.GPIO

# 更換鏡像源
pi@raspberrypi:~ $ sudo sed -i 's#://raspbian.raspberrypi.org#s://mirrors.ustc.edu.cn/raspbian#g' /etc/apt/sources.list 
pi@raspberrypi:~ $ sudo sed -i 's#://archive.raspberrypi.org/debian#s://mirrors.ustc.edu.cn/archive.raspberrypi.org/debian#g' /etc/apt/sources.list.d/raspi.list

# 更新軟件包
pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get install python3-rpi.gpio

三、針腳編號(hào)

第一種編號(hào)是BOARD編號(hào),這和樹莓派電路板上的物理引腳編號(hào)相對(duì)應(yīng)。使用這種編號(hào)的好處是,你的硬件將是一直可以使用的,不用擔(dān)心樹莓派的版本問題。因此,在電路板升級(jí)后,你不需要重寫連接器或代碼。
第二種編號(hào)是BCM規(guī)則,是更底層的工作方式,它和Broadcom的片上系統(tǒng)中信道編號(hào)相對(duì)應(yīng)。在使用一個(gè)引腳時(shí),你需要查找信道號(hào)和物理引腳編號(hào)之間的對(duì)應(yīng)規(guī)則。對(duì)于不同的樹莓派版本,編寫的腳本文件也可能是無法通用的。
對(duì)于GPIO號(hào)接口的12引腳GPIO信號(hào)18.如果你使用GPIO.BCM模式,你可以使用數(shù)字18使用它,但如果你使用GPIO.BOARD模式,你需要使用數(shù)字12使用它。


編號(hào)對(duì)應(yīng)圖

帶GPIO的為BCM編號(hào)。

指定一種編號(hào)規(guī)則:

GPIO.setmode(GPIO.BOARD)
  # or
GPIO.setmode(GPIO.BCM)
# 返回被設(shè)置的編號(hào)規(guī)則
mode = GPIO.getmode()

四、警告

如果RPi.GRIO檢測(cè)到一個(gè)引腳已經(jīng)被設(shè)置成了非默認(rèn)值,那么你將看到一個(gè)警告信息。你可以通過下列代碼禁用警告:

GPIO.setwarnings(False)

四、引腳設(shè)置

在使用一個(gè)引腳前,你需要設(shè)置這些引腳作為輸入還是輸出。配置一個(gè)引腳的代碼如下:

# 將引腳設(shè)置為輸入模式
GPIO.setup(channel, GPIO.IN)
 # 將引腳設(shè)置為輸出模式
GPIO.setup(channel, GPIO.OUT)
 # 為輸出的引腳設(shè)置默認(rèn)值
GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)

五、釋放

一般來說,程序到達(dá)最后都需要釋放資源,這個(gè)好習(xí)慣可以避免偶然損壞樹莓派。釋放腳本中的使用的引腳:

GPIO.cleanup()

注意,GPIO.cleanup()只會(huì)釋放掉腳本中使用的GPIO引腳,并會(huì)清除設(shè)置的引腳編號(hào)規(guī)則。

六、輸出

要想點(diǎn)亮一個(gè)LED燈,或者驅(qū)動(dòng)某個(gè)設(shè)備,都需要給電流和電壓他們,這個(gè)步驟也很簡單,設(shè)置引腳的輸出狀態(tài)就可以了,代碼如下:

GPIO.output(channel, state)

狀態(tài)可以設(shè)置為0 / GPIO.LOW / False / 1 / GPIO.HIGH / True。如果編碼規(guī)則為,GPIO.BOARD,那么channel就是對(duì)應(yīng)引腳的數(shù)字。
如果想一次性設(shè)置多個(gè)引腳,可使用下面的代碼:

chan_list = [11,12]
GPIO.output(chan_list, GPIO.LOW)
GPIO.output(chan_list, (GPIO.HIGH, GPIO.LOW)) 

你還可以使用Input()函數(shù)讀取一個(gè)輸出引腳的狀態(tài)并將其作為輸出值,例如:

GPIO.output(12, not GPIO.input(12))

七、輸入

我們也常常需要讀取引腳的輸入狀態(tài),獲取引腳輸入狀態(tài)如下代碼:

GPIO.input(channel)

低電平返回0 / GPIO.LOW / False,高電平返回1 / GPIO.HIGH / True。
如果輸入引腳處于懸空狀態(tài),引腳的值將是漂動(dòng)的。換句話說,讀取到的值是未知的,因?yàn)樗]有被連接到任何的信號(hào)上,直到按下一個(gè)按鈕或開關(guān)。由于干擾的影響,輸入的值可能會(huì)反復(fù)的變化。
使用如下代碼可以解決問題:

GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
  # or
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

需要注意的是,上面的讀取代碼只是獲取當(dāng)前一瞬間的引腳輸入信號(hào)。
如果需要實(shí)時(shí)監(jiān)控引腳的狀態(tài)變化,可以有兩種辦法。最簡單原始的方式是每隔一段時(shí)間檢查輸入的信號(hào)值,這種方式被稱為輪詢。如果你的程序讀取的時(shí)機(jī)錯(cuò)誤,則很可能會(huì)丟失輸入信號(hào)。輪詢是在循環(huán)中執(zhí)行的,這種方式比較占用處理器資源。另一種響應(yīng)GPIO輸入的方式是使用中斷(邊緣檢測(cè)),這里的邊緣是指信號(hào)從高到低的變換(下降沿)或從低到高的變換(上升沿)。

八、輪詢方式

while GPIO.input(channel) == GPIO.LOW:
    time.sleep(0.01)  # 等10毫秒給CPU一個(gè)信號(hào)

九、邊緣檢測(cè)

邊緣是指信號(hào)狀態(tài)的改變,從低到高(上升沿)或從高到低(下降沿)。通常情況下,我們更關(guān)心于輸入狀態(tài)的該邊而不是輸入信號(hào)的值。這種狀態(tài)的該邊被稱為事件。
先介紹兩個(gè)函數(shù):
wait_for_edge() 函數(shù)。
wait_for_edge()被用于阻止程序的繼續(xù)執(zhí)行,直到檢測(cè)到一個(gè)邊沿。也就是說,上文中等待按鈕按下的實(shí)例可以改寫為:

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() 函數(shù)
該函數(shù)對(duì)一個(gè)引腳進(jìn)行監(jiān)聽,一旦引腳輸入狀態(tài)發(fā)生了改變,調(diào)用event_detected()函數(shù)會(huì)返回true,如下代碼:

do_something()
// 下面的代碼放在一個(gè)線程循環(huán)執(zhí)行。
if GPIO.event_detected(channel):
    print('Button pressed')

上面的代碼需要自己新建一個(gè)線程去循環(huán)檢測(cè)event_detected()的值,還算是比較麻煩的。
不過可采用另一種辦法輕松檢測(cè)狀態(tài),這種方式是直接傳入一個(gè)回調(diào)函數(shù):

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)

如果你想設(shè)置多個(gè)回調(diào)函數(shù),可以這樣:

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)

注意:回調(diào)觸發(fā)時(shí),并不會(huì)同時(shí)執(zhí)行回調(diào)函數(shù),而是根據(jù)設(shè)置的順序調(diào)用它們。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,538評(píng)論 3 417
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評(píng)論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,761評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,207評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,419評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,959評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,782評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,222評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評(píng)論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,678評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,978評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容