一塊兒玩轉樹莓派(4)——用開關控制蜂鳴器發聲

一塊兒玩轉樹莓派(4)——用開關控制蜂鳴器發聲

在本系列的前幾篇博客中,咱們使用桌面軟件控制過紅綠燈,也編程點亮過炫彩的3色LED 燈。在這些實驗的過程當中,相信你對樹莓派GPIO引腳如何輸出高低電平,以及如何使用PWM技術來控制電壓輸出等都有了瞭解。本篇博客,咱們將再探索一些樹莓派編程更多新鮮好玩的領域,來嘗試使用硬件來控制硬件。python

如今,咱們將嘗試完成這樣一個實驗,使用按壓開關控制蜂鳴器的發聲。將開關元件和蜂鳴器都鏈接到樹莓派,當按下開關時,讓蜂鳴器發聲,當鬆開開關時,蜂鳴器中止發聲。編程

1、主角登場

開始動手實驗前,咱們先來認識一下將要出場的主角們,固然,不管什麼實驗,樹莓派都是當之無愧的第一主角,但我相信你已經對它已經有了足夠的瞭解(若是沒有,能夠查看本系列的前幾篇博客),所以咱們將介紹的重點放在兩個新登場的「角色」上:蜂鳴器與按壓開關。markdown

1.本實驗的「主角甲」——有源蜂鳴器

蜂鳴器,顧名思義,其是一種發聲元件。普遍應用於計算機、打印機、電話、玩具等電子設備中。ide

蜂鳴器能夠分爲「有源蜂鳴器」和「無源蜂鳴器」。其中的源並不是指電源,而是指蜂鳴器內部是否有震盪源。有源蜂鳴器自帶一個震盪源模塊,其使用起來很是簡單,只要接通直流電,其就會自動發出聲音。而無源蜂鳴器內部沒有震盪源,須要外接使用必定頻率的方波來驅動其發聲。關於無源蜂鳴器更多深刻的用法,咱們後續博客再專門介紹。這裏,咱們先着重理解有源蜂鳴器的工做原理。函數

本實驗中,咱們採用的是低電平觸發的有源蜂鳴器,元件以下圖所示:學習

一塊兒玩轉樹莓派(4)——用開關控制蜂鳴器發聲

其有3個引腳,GND引腳用來接地,VCC引腳用來接3.3V的電源,I/O引腳用來進行蜂鳴器是否播放聲音的控制。你可能有些疑惑,爲何低電平也能夠觸發元件的「開」狀態,這要歸功於PNP型三極管的功勞,對於PNP型三極光,當輸入管腳爲低電平時,三極管處於導通狀態,使得蜂鳴器被加電壓,當輸入管腳爲高電平時,三極管處於截止狀態,蜂鳴器無電壓。原理以下圖所示:編碼

一塊兒玩轉樹莓派(4)——用開關控制蜂鳴器發聲

如今,咱們先來編寫一段簡單的Python程序,來使蜂鳴器發出聲音。3d

2. 觸發蜂鳴器播放聲音

咱們使用的蜂鳴器的3個引腳,其中VCC接電源,GND接地,I/O引腳咱們能夠選擇樹莓派BCM編碼爲27的GPIO引腳,經過查表,能夠獲得其物理編碼爲13。連線示意以下:code

一塊兒玩轉樹莓派(4)——用開關控制蜂鳴器發聲

編寫Python程序代碼以下:blog

#coding:utf-8

# 導入GPIO控制薄塊
import RPi.GPIO as GPIO
# 導入time模塊
import time

# 定義引腳
fm = 13
# 設置使用的引腳編碼模式
GPIO.setmode(GPIO.BOARD)
# 進行引腳的初始化,由於是低電平觸發,初始時設置爲高電平
GPIO.setup(fm,GPIO.OUT, initial=GPIO.HIGH)

# 進行一長兩短的聲音播放
# 播放1秒聲音
GPIO.output(fm, GPIO.LOW)
time.sleep(1)
GPIO.output(fm, GPIO.HIGH)
time.sleep(0.1)
# 播放0.5秒聲音
GPIO.output(fm, GPIO.LOW)
time.sleep(0.5)
GPIO.output(fm, GPIO.HIGH)
time.sleep(0.1)
# 播放0.5秒聲音
GPIO.output(fm, GPIO.LOW)
time.sleep(0.5)
# 中止蜂鳴器播放
GPIO.output(fm, GPIO.HIGH)
GPIO.cleanup()

在樹莓派上運行代碼,你應該已經能夠聽到蜂鳴器發出一長兩短的鳴叫聲了。

3.本實驗的「主角乙」——按壓開關

按壓開關是電子設備中最爲經常使用的一種元件,關於按壓開關自己的結構和原理,其實很是簡單,其按鍵內部會有彈簧進行控制,當沒有外力做用時,彈簧會將開關自動頂起,接觸器上升。當外力將按鍵按下時,接觸器降低。經過接觸器的上升和降低來控制電路的導通。以下圖所示:

一塊兒玩轉樹莓派(4)——用開關控制蜂鳴器發聲

本次實驗,咱們使用的按壓開關元件以下圖所示:

一塊兒玩轉樹莓派(4)——用開關控制蜂鳴器發聲

咱們使用的此開關當按鍵按下式,會向引腳輸入低電平,當按鍵鬆開時,會向引腳輸入低電平。在連線時,按壓開關的「-」引腳接地,中間引腳節3.3V電壓,「S」引腳接GPIO信號引腳,咱們能夠將其接BCM編碼爲GPIO5的引腳,其物理編碼爲29。連線以下圖所示:

一塊兒玩轉樹莓派(4)——用開關控制蜂鳴器發聲

下面,咱們要來學習點新東西了,如何獲取到GPIO引腳的輸入。

4. 使用GPIO輸入信號

以前,咱們都是將GPIO做爲輸出引腳進行使用,即讓GPIO輸出高電平或低電平從而控制元件。其實還有不少場景,須要讀取GPIO的輸入信號,例如各類傳感器和開關元件。一般,咱們能夠採用兩種方式來獲取GPIO的輸入信號:輪詢式中斷式

輪詢式很好理解,即咱們不停的詢問當前GPIO引腳:輸入的信號是什麼啊?以後GPIO會將當前的輸入信息告訴咱們,這種不停的讀取某個GPIO引腳的值的方式就是輪詢式獲取輸入信號。更多時候,咱們會採起中斷式,中斷式是指在程序運行過程當中,若是出現外部事件,則中斷當前程序運行來處理外部事件。在本實驗中,開關的按下和鬆開就能夠理解爲中斷事件。

須要注意,對於做爲輸入使用的GPIO引腳來講,當咱們未接任何輸入源時,其值多是任意的,即其值是浮動且不可控的,所以咱們須要爲其配置一個默認值,硬件上,咱們一般使用下拉電阻或上拉電阻。軟件上咱們也能夠經過GPIO庫的相關接口來實現一樣的功能,例如使用下面的方式初始化引腳:

# 將引腳初始化爲輸入引腳,同時設置默認值爲高電平
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# 將引腳初始化爲輸入引腳,同時設置默認值爲低電平
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

若要獲取到某個輸入引腳當前的電平狀況,可使用以下方法:

# 1表示高電平 0表示低電平
GPIO.input(channel)

例如能夠經過以下的方式輪訓檢查某個引腳的輸入:

while GPIO.input(channel) == GPIO.LOW:
    time.sleep(0.01)

咱們一般只須要關心電平的變化,以及變化方向,以本實驗爲例,當按下開關時,電平由低變高,當鬆開開關時,電平由高到低。下面方法能夠中斷當前程序的運行,等待電平變化的信號:

# 當channel引腳由低電平變到高電平時會觸發向後執行, timeout設置超時時間
GPIO.wait_for_edge(channel, GPIO.RISING, timeout=5000)

GPIO.RISING表示要等待的是由低到高的電平變化,與之對應的還有GPIO.FALLING表示由高到低的電平變化,GPIO.BOTH表示兩個方向的電平變化都會觸發。

對於本實驗的場景,GPIO.wait_for_edge方法並不實用,若是咱們要採用輪詢的方式獲取GPIO輸入信號,則能夠實用下面的方法:

# 爲channel輸入引腳添加[從低到高]的電平變化監聽
GPIO.add_event_detect(channel, GPIO.RISING)  
# 下面的判斷能夠放在輪詢中,只要有[從低到高]的電平變化,即會命中if判斷
if GPIO.event_detected(channel):
    print('從低到高變化')

須要注意,GPIO.add_event_detect方法比直接輪詢經過GPIO.input方法獲取信號要可靠的多,直接輪詢可能會錯過某些電平變化事件,而GPIO.add_event_detect 不會。在使用GPIO.add_event_detect方法時,咱們也能夠直接設置回調函數,當有變化發生時,即會執行到回調函數,例如:

# 定義回調函數
def my_callback(channel):
    pass
# 註冊回調函數 bouncetime參數用來進行防抖
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback, bouncetime=200)

上面示例代碼中,bouncetime參數可以提供軟件防抖的功能,其單位爲毫秒,200毫秒內的屢次電平變化來回將被忽略。

最後,若是你再也不須要監聽,可使用以下方法移除:

GPIO.remove_event_detect(channel)

5. 獲取按壓開關元件的狀態

如今,咱們能夠嘗試使用樹莓派讀取按壓開關元件的開關狀態了。示例代碼以下:

#coding:utf-8

# 導入GPIO控制薄塊
import RPi.GPIO as GPIO
# 導入time模塊
import time

# 設置使用的引腳編碼模式
GPIO.setmode(GPIO.BOARD)

# 定義開關引腳
swi = 29
# 進行開關引腳的初始化,設置爲輸入引腳,且默認爲高電平
GPIO.setup(swi, GPIO.IN, pull_up_down=GPIO.PUD_PU)
# 定義狀態變化的回調函數
def switch(channel):
    # 高電平的開關鬆開
    if GPOI.input(channel):
        print("開關鬆開")
    # 低電平爲開關按下
    else:
        print("開關按下")

# 添加輸入引腳電平變化的回調函數
GPIO.add_event_detect(swi, GPIO.BOTH, callback=switch, bouncetime=200)
# 開啓循環
while True:
    pass

在樹莓派運行上面代碼,經過按壓和鬆開開關,觀察控制檯的輸出是否正確。

2、開關控制蜂鳴器播放

若是你成功作完了前面的工做,那麼好了,本節的內容將很是簡單,只須要將上面編寫的蜂鳴器程序和開關程序進行結合,你就可使用開關來控制蜂鳴器了。示例代碼以下:

#coding:utf-8

# 導入GPIO控制薄塊
import RPi.GPIO as GPIO
# 導入time模塊
import time

# 設置使用的引腳編碼模式
GPIO.setmode(GPIO.BOARD)

# 定義開關引腳
swi = 29
# 定義蜂鳴器引腳
fm = 13
# 進行開關引腳的初始化,設置爲輸入引腳,且默認爲高電平
GPIO.setup(swi, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# 進行蜂鳴器引腳的初始化,由於是低電平觸發,初始時設置爲高電平
GPIO.setup(fm,GPIO.OUT, initial=GPIO.HIGH)
# 定義狀態變化的回調函數
def switch(channel):
    # 高電平的開關鬆開
    if GPI0.input(channel):
        GPIO.output(fm, GPIO.HIGH)
    # 低電平爲開關按下
    else:
        GPIO.output(fm, GPIO.LOW)

# 添加輸入引腳電平變化的回調函數
GPIO.add_event_detect(swi, GPIO.BOTH, callback=switch, bouncetime=200)
# 開啓循環
while True:
    pass

如今,運行程序,用開關來控制蜂鳴器的聲音播放吧。恭喜!你已經可以使用硬件來控制硬件了!

3、休息一下吧

經過本篇博客,你應該收穫了GPIO輸入信號的編程方法,以及經過GPIO讀取有輸入功能的傳感器數據的方法。本篇博客涉及的內容不少,重點在於GPIO輸入引腳中斷的相關用法,須要你多多練習。說了這麼多,你有沒有發現此次咱們完成的實驗很像生活中的一種東西?沒錯,就是門鈴,你已經可使用樹莓派實現一個簡單的門鈴器件啦。

專一技術,懂的熱愛,願意分享,作個朋友

QQ:316045346

相關文章
相關標籤/搜索