在上期的“開啟Arduino的Python編程之旅——基礎(chǔ)篇”中,我們在Arduino中通過調(diào)用PinPong庫使用Python編程,分別實現(xiàn)了“數(shù)字輸出:閃爍的LED燈”“數(shù)字輸入:按鈕控制LED燈亮與滅”“模擬輸入:打印輸出滑桿傳感器的位置數(shù)據(jù)”和“模擬輸出:PWM模式控制LED燈的明暗程度均勻變化”四個開源硬件編程項目案例;在本期的“常規(guī)篇”中,我們嘗試在Arduino上連接溫濕度傳感器、光線傳感器、超聲波傳感器和WS2812燈帶等外設(shè),同樣是調(diào)用PinPong庫進(jìn)行Python編程,制作實現(xiàn)四個不同效果的經(jīng)典項目案例。
首先,將DHT11溫濕度傳感器的VCC和GND引腳分別通過紅色、黑色杜邦線連接至ArduinoUNO的3.3V和GND引腳,再將DAT引腳通過黃色杜邦線連接至Arduino的6號引腳(如圖1)。
打開PythonIDE進(jìn)入編輯界面開始編程,仍需要先導(dǎo)入庫模塊及相關(guān)的類:“import time”“from pinpong.board import Board,Pin,DHT11”,如果使用的是DHT22溫濕度傳感器,此處需更改為“from pinpong.board import Board,Pin,DHT22”;初始化ArduinoUNO:“Board(“uno”).begin()”,再建立變量dht11,賦值為“DHT11(Pin(Pin.D6))”——若為DHT22則同樣作類似的修改,比如連接引腳使用7號,對應(yīng)的命名均為“DHT22”,即“DHT22(Pin(Pin.D7))”;接下來,在“while True”循環(huán)結(jié)構(gòu)中建立變量my_temp和my_humi,分別賦值為“dht11.temp_c()”和“dht11.humidity()”,作用是讀取對應(yīng)的攝氏溫度值和濕度值;然后,通過“print(“現(xiàn)在的室溫是:”,my_temp,“℃,濕度為:”,my_humi)”語句將溫度值和濕度值進(jìn)行打印輸出;最后,添加時間等待語句“time.sleep(3)”,作用是控制每次循環(huán)讀取及顯示溫度和濕度的持續(xù)時間為3秒(如圖2)。
將程序保存為“【01】讀取并顯示即時室溫及濕度.py”,再將Arduino通過數(shù)據(jù)線與電腦連接,運(yùn)行程序進(jìn)行測試。屏幕上開始出現(xiàn)第一條顯示輸出:“現(xiàn)在的室溫是:22.1℃,濕度為:70.0”,此時嘗試使用打火機(jī)模擬火源在一定范圍內(nèi)靠近DHT11溫濕度傳感器(或者用手掌握住),靜置一段時間,屏幕上每隔5秒鐘就會顯示一行提示信息,溫度值和濕度值均有不同程度的變化,比如溫度值會從最初的22.1 ℃升高至26.7 ℃(如圖3)。
從Arduino上拆下DHT11溫濕度傳感器,換用光線傳感器來實現(xiàn)根據(jù)周圍環(huán)境的光線強(qiáng)度來控制LED燈發(fā)光。首先將光線傳感器的VCC和GND端通過紅色和黑色杜邦線連接至Arduino的3.3V和GND接地端,再將模擬信號輸出AO端通過黃色杜邦線連接至Arduino的A0引腳;然后,將一支紅色LED燈的長、短引腳分別插入Arduino的13號及相鄰的GND端(如圖4)。
先導(dǎo)入庫模塊及相關(guān)的類并進(jìn)行Arduino主板的初始化:“import time”“from pinpong.board import Board,Pin”“Board(“uno”).begin()”;然后建立my_LED和my_adc兩個變量,分別賦值為“Pin(Pin.D13,Pin.OUT)”和“Pin(Pin.A0,Pin.ANALOG)”,作用分別是將連接在13號引腳的LED燈設(shè)置為數(shù)字輸出、將連接在A0引腳的光線傳感器設(shè)置為模擬輸入;接下來,在“while True”循環(huán)結(jié)構(gòu)中建立變量my_light,賦值為“my_adc.read_analog()”,作用是從A0引腳讀取模擬數(shù)據(jù),即光線傳感器檢測到的周圍環(huán)境光線值;通過“print(“現(xiàn)在檢測到的光線值是:”,my_light)”語句將光線數(shù)據(jù)在屏幕上打印輸出后,再通過“if (my_light>=400)”對my_light的值進(jìn)行是否“大于等于400”的判斷,條件成立的話,說明周圍環(huán)境的光線比較暗,則分別執(zhí)行“print(“LED燈工作中…”)”和“my_LED.value(1)”,控制LED燈發(fā)光;條件不成立,則熄滅LED燈:“my_LED.value(0)”;最后,添加時間等待語句“time.sleep(0.5)”,控制每次循環(huán)讀取光線傳感器數(shù)據(jù)的持續(xù)時間為0.5秒鐘(如圖5)。
將程序保存為“【02】根據(jù)光線強(qiáng)度控制LED燈是否發(fā)光.py”,運(yùn)行程序進(jìn)行測試,屏幕上每隔0.5秒鐘顯示輸出一個檢測到的光線值:122、141、67……此時對應(yīng)的是白天正常的照明情況;嘗試用一只黑盒子蓋住光線傳感器的光敏電阻,檢測到的光線數(shù)據(jù)就變成528、557、555……LED燈也開始亮起來,同時屏幕上也有“LED燈工作中…”的提示;如果再撤掉蓋住光線傳感器模擬黑暗環(huán)境的黑盒子,檢測到的光線值就會重新恢復(fù)為較小的數(shù)值,LED燈也熄滅(如圖6)。
保持LED燈插接在13號引腳不變,將光線傳感器拆下,開始安裝SR04超聲波傳感器(也可以使用精度更高的URM超聲波傳感器):先分別通過紅色和黑色杜邦線將超聲波傳感器的VCC和GND端連接至Arduino的5V和GND接地端(如果接3.3V端有可能工作不正常),再通過黃色和綠色杜邦線將超聲波傳感器的Trig信號發(fā)射端、Echo信號接收端連接至Arduino的7號和8號引腳(如圖7)。
先導(dǎo)入庫模塊及相關(guān)的類并進(jìn)行Arduino主板的初始化:“import time”“from pinpong.board import Board,Pin,SR04_URM10”“Board(“uno”).begin()”;然后建立變量my_LED,仍賦值為“my_LED = Pin(Pin.D13,Pin.OUT)”;再建立TRIGER_PIN和ECHO_PIN兩個變量,分別賦值為“Pin(Pin.D7)”和“Pin(Pin.D8)”,作用是設(shè)置超聲波傳感器的信號發(fā)射端和接收端的引腳分別為7號和8號;建立變量sonar,賦值為“SR04_URM10(TRIGER_PIN,ECHO_PIN)”,作用是初始化SR04超聲波傳感器(將對應(yīng)的引腳編號作為參數(shù)傳遞進(jìn)去);接下來,在“while True”循環(huán)結(jié)構(gòu)中建立變量my_dis,賦值為“sonar.distance_cm()”,作用是獲取超聲波傳感器的檢測距離值(單位為厘米);再通過“print(‘距離前方障礙物的間距為:{0:.2f} cm’.format(my_dis))”語句,將數(shù)據(jù)在屏幕上打印輸出;然后通過“if (my_dis<=10)”對間距值進(jìn)行“是否小于等于10”的判斷,條件成立的話,則先在屏幕打印輸出“注意安全,間距已不足10cm!”的警告信息,再控制LED燈發(fā)光:“my_LED.value(1)”;條件不成立,則關(guān)閉LED燈:“my_LED.value(0)”;最后,仍然是為循環(huán)結(jié)構(gòu)添加0.1秒鐘的時間等待語句“time.sleep(0.1)”(如圖8)。
將程序保存為“【03】超聲波測距和LED燈光報警.py”,運(yùn)行程序進(jìn)行測試:超聲波傳感器每隔0.1秒鐘就會檢測獲取一個與前方障礙物的間距值:35.00cm、14.00cm、11.00cm……當(dāng)放置的模擬障礙物距離足夠近時,屏幕輸出的提示信息變?yōu)椋骸熬嚯x前方障礙物的間距為:9.00cm”“注意安全,間距已不足10cm!”此時的LED燈也會發(fā)光進(jìn)行報警;直至移走障礙物,LED燈熄滅,又會恢復(fù)正常的監(jiān)控狀態(tài)(如圖9)。
將超聲波傳感器和LED燈從Arduino上拆下,開始安裝WS2812燈帶:通過紅色和白色杜邦線將燈帶的+5V和GND端分別連接至Arduino的5V和GND接地端,再將燈帶的DO端通過綠色杜邦線連接至Arduino的9號引腳(如圖10)。
先導(dǎo)入庫模塊及相關(guān)的類:“import time”“from pinpong.board import Board,Pin,NeoPixel”(其中的NeoPixel類對應(yīng)WS2812燈帶),再從random隨機(jī)庫中導(dǎo)入隨機(jī)取整函數(shù)randint:“from random import randint”;接著,進(jìn)行Arduino主板的初始化:“Board(“uno”).begin()”;建立變量NEOPIXEL_PIN,賦值為“Pin(Pin.D9)”,即燈帶的信號引腳是與Arduino的9號引腳相連;再建立變量PIXELS_NUM,賦值為60,對應(yīng)標(biāo)準(zhǔn)WS2812燈帶的60個燈珠,每個燈珠均相當(dāng)于一顆RGB微型LED燈;再建立變量my_np,賦值為“NeoPixel(NEOPIXEL_PIN,PIXELS_NUM)”,將燈帶的引腳號和燈珠數(shù)量作為參數(shù)傳遞進(jìn)去;在“while True”循環(huán)結(jié)構(gòu)中建立for內(nèi)層循環(huán),對編號為0-59共60個燈珠進(jìn)行隨機(jī)顏色的“賦值”;my_red、my_green和my_blue三個變量的值均被賦為“randint(0,255)”(從0至255中隨機(jī)取整),再通過“my_np[i] = (my_red,my_green,my_blue)”語句,實現(xiàn)為每個燈珠設(shè)置紅色、綠色和藍(lán)色三種隨機(jī)顏色的目的;最后,添加0.001秒鐘的時間等待語句:“time.sleep(0.001)”,控制相鄰兩個燈珠每次進(jìn)行顏色切換的時間差(如圖11)。
將程序保存為“【04】隨機(jī)顏色炫彩燈帶.py”,運(yùn)行程序進(jìn)行測試:燈帶很快就從第0顆燈珠開始亮起,接著就會快速亮起第1顆、第2顆……每顆燈珠亮起顯示的均為隨機(jī)顏色;第一次循環(huán)(內(nèi)層嵌套的for循環(huán))結(jié)束后,第二次循環(huán)立刻運(yùn)行,將上一次循環(huán)所設(shè)置的隨機(jī)顏色“覆蓋”并重新亮起一種新的隨機(jī)顏色,這樣我們就得到了隨機(jī)顏色炫彩燈帶(如圖12)。