牟曉東
霍爾傳感器是一種用來(lái)檢測(cè)磁場(chǎng)的傳感器,其內(nèi)部磁場(chǎng)中有個(gè)霍爾半導(dǎo)體片,在恒定電流經(jīng)過(guò)時(shí)(洛侖茲力的作用)就會(huì)產(chǎn)生電位差,即“霍爾電壓”?;魻栯妷簳?huì)隨磁場(chǎng)強(qiáng)度的變化而變化——磁場(chǎng)越強(qiáng),電壓就越高;磁場(chǎng)越弱,電壓也就越低。常見(jiàn)的霍爾傳感器有四個(gè)引腳,除了VCC正極和GND接地端外,另外兩個(gè)引腳分別標(biāo)注為DO和AO,對(duì)應(yīng)數(shù)字信號(hào)和模擬信號(hào)的輸入。利用霍爾傳感器檢測(cè)磁場(chǎng)時(shí)能夠產(chǎn)生數(shù)字或模擬信號(hào)的特性,我們可以在Arduino中分別設(shè)計(jì)實(shí)現(xiàn)“時(shí)速計(jì)”和“智能路燈”。
利用霍爾傳感器能夠?qū)z測(cè)到的磁場(chǎng)產(chǎn)生數(shù)字信號(hào)的特性,可以對(duì)“車(chē)輪”(由風(fēng)扇模塊來(lái)代替)每分鐘轉(zhuǎn)動(dòng)的圈數(shù)進(jìn)行計(jì)數(shù),然后就能計(jì)算出它的時(shí)速。實(shí)驗(yàn)器材分為兩大部分:一部分是樹(shù)莓派帶動(dòng)風(fēng)扇進(jìn)行勻速轉(zhuǎn)動(dòng),風(fēng)扇的邊緣處通過(guò)熱熔膠粘貼上一小塊圓形磁鐵;另一部分是Arduino控制霍爾傳感器對(duì)旋轉(zhuǎn)的風(fēng)扇磁鐵進(jìn)行檢測(cè)并計(jì)數(shù),最終計(jì)算出“車(chē)輪”的時(shí)速進(jìn)行輸出。
實(shí)驗(yàn)器材包括樹(shù)莓派3B+和古德微擴(kuò)展板各一塊,ArduinoUNO一塊,KY-024霍爾傳感器一個(gè),風(fēng)扇模塊一個(gè),紅色LED燈兩支,圓形小磁鐵一個(gè),杜邦線若干。首先,將一支紅色LED燈插入樹(shù)莓派擴(kuò)展板的5號(hào)引腳,注意“長(zhǎng)腿正、短腿負(fù)”的規(guī)則;接著,通過(guò)杜邦線將風(fēng)扇模塊的VCC、GND和IA端分別連接到樹(shù)莓派擴(kuò)展板的24號(hào)引腳的VCC、GND和D端;最后,為樹(shù)莓派連接數(shù)據(jù)線,通電啟動(dòng)操作系統(tǒng)。在瀏覽器中訪問(wèn)古德微機(jī)器人網(wǎng)站,切換進(jìn)入“積木”編程區(qū),通過(guò)“控制5號(hào)小燈亮”和“控制24號(hào)GPIO輸出PWM800”等模塊,實(shí)現(xiàn)風(fēng)扇的轉(zhuǎn)動(dòng)(如圖1)。
在Arduino中先將另外一支紅色LED燈的長(zhǎng)腿插入13號(hào)引腳、短腿插入GND引腳,然后通過(guò)杜邦線將霍爾傳感器的VCC、GND和DO端分別插入Arduino的5V、GND和7號(hào)引腳,最后插入數(shù)據(jù)線并與計(jì)算機(jī)的USB接口連接。
運(yùn)行Mind+,點(diǎn)擊“擴(kuò)展”按鈕將“主控板”中的“ArduinoUno”添加后開(kāi)始進(jìn)行圖形化編程。
在程序的初始化部分先設(shè)置串口波特率為9600,再新建“車(chē)輪半徑”“車(chē)輪周長(zhǎng)”和“圈數(shù)的計(jì)算值”三個(gè)變量,并且根據(jù)測(cè)量將“車(chē)輪半徑”賦值為0.02(單位為米),即風(fēng)扇模塊上小磁鐵與圓心間的距離是2厘米,“車(chē)輪周長(zhǎng)”的計(jì)算公式即圓周長(zhǎng)的求解公式,而變量“圈數(shù)的計(jì)算值”的初始值為0,作用是計(jì)算1分鐘內(nèi)車(chē)輪轉(zhuǎn)過(guò)的圈數(shù)。
新建一個(gè)“重復(fù)執(zhí)行1000次”的循環(huán)結(jié)構(gòu),內(nèi)嵌的延時(shí)模塊控制每次循環(huán)均等待0.005秒,因此循環(huán)從開(kāi)始到結(jié)束的時(shí)間是5秒鐘;在循環(huán)中設(shè)置變量“霍爾傳感器”,其值為“讀取數(shù)字引腳7”的信號(hào),即檢測(cè)到磁場(chǎng)信號(hào)時(shí)就會(huì)變?yōu)?(高電平);然后對(duì)其值進(jìn)行是否為1的判斷,條件成立的話則先將變量“圈數(shù)的計(jì)數(shù)值”進(jìn)行“自增1”運(yùn)算,再點(diǎn)亮紅色LED燈作為提示;循環(huán)結(jié)束后新建變量“車(chē)輪轉(zhuǎn)速”,并進(jìn)行兩次計(jì)算和輸出:第一次計(jì)算的公式是變量“圈數(shù)的計(jì)數(shù)值”乘以60再除以5,這樣得到的結(jié)果是車(chē)輪每分鐘轉(zhuǎn)動(dòng)的圈數(shù),即“車(chē)輪轉(zhuǎn)速”,單位為“轉(zhuǎn)/分鐘”(r/min);第二次計(jì)算的公式是變量“車(chē)輪轉(zhuǎn)速”乘以60再乘以變量“車(chē)輪周長(zhǎng)”后再除以1000,此時(shí)的計(jì)算結(jié)果就是真正的“時(shí)速”,單位為“千米/小時(shí)”(km/h),均通過(guò)串口監(jiān)視器輸出顯示。
將程序保存為“Arduino‘時(shí)速計(jì)’.sb3”,上傳至Arduino中運(yùn)行測(cè)試,注意此時(shí)要將轉(zhuǎn)動(dòng)的風(fēng)扇模塊靠近霍爾傳感器的檢測(cè)探頭(保證風(fēng)扇每轉(zhuǎn)動(dòng)一周時(shí)小磁鐵都能近距離經(jīng)過(guò)),同時(shí)還要打開(kāi)串口監(jiān)視窗口。很快就會(huì)有結(jié)果輸出:“車(chē)輪的轉(zhuǎn)速為:1296.00轉(zhuǎn)/分鐘”“車(chē)輪的時(shí)速為:9.77千米/小時(shí)”(如圖2)。
保持實(shí)驗(yàn)器材及連接方式不變,再來(lái)嘗試使用代碼編程實(shí)現(xiàn)Arduino“時(shí)速計(jì)”。首先,通過(guò)“int Hall_Sensor_pin = 7;”和“int Red_LED_pin = 13;”實(shí)現(xiàn)霍爾傳感器和LED與Arduino連接引腳號(hào)的聲明,再通過(guò)“int Hall_Sensor_State = 0;”將霍爾傳感器的初始狀態(tài)定義為0(低電平);由于待構(gòu)建的循環(huán)是固定的1000次循環(huán),而不是一直循環(huán),因此要保持void loop()函數(shù)為空,代碼語(yǔ)句均在void setup()函數(shù)中完成——
設(shè)置霍爾傳感器的引腳為輸入:“pinMode(Hall_Sensor_pin,INPUT);”,設(shè)置紅色LED燈的引腳為輸出:“pinMode(Red_LED_pin,OUTPUT);”,設(shè)置串口波特率:“Serial.begin(9600);”;新建浮點(diǎn)型變量car_r(車(chē)輪半徑),賦值為0.02(單位為米);再新建浮點(diǎn)型變量car_c(車(chē)輪的周長(zhǎng)),按照?qǐng)A的周長(zhǎng)公式進(jìn)行計(jì)算賦值:“float car_c = 2*3.14*car_r;”;新建變量car_counter(對(duì)應(yīng)圈數(shù)的計(jì)數(shù)值),初始值為0;使用for建立運(yùn)行1000次的循環(huán)結(jié)構(gòu)(for(int i=0;i<1000;i++)),語(yǔ)句“Hall_Sensor_State = digitalRead(Hall_Sensor_pin);”的作用是將霍爾傳感器檢測(cè)磁場(chǎng)的狀態(tài)寫(xiě)入變量Hall_Sensor_State中(1對(duì)應(yīng)高電平);然后通過(guò)if語(yǔ)句對(duì)Hall_Sensor_State的值進(jìn)行判斷,如果該值是1:“if(Hall_Sensor_State==1)”,則執(zhí)行兩條語(yǔ)句:一是變量car_counter進(jìn)行自增1運(yùn)算:“car_counter++;”,二是點(diǎn)亮紅色LED燈:“digitalWrite(Red_LED_pin,HIGH);”;接著,通過(guò)語(yǔ)句“delay(5);”延時(shí)5毫秒,并且熄滅LED燈:“digitalWrite(Red_LED_pin,LOW);”。
1000次循環(huán)結(jié)束后,新建浮點(diǎn)型變量car_v1(車(chē)輪的轉(zhuǎn)速),通過(guò)計(jì)算公式為其賦值為“car_counter*60/5”(單位為轉(zhuǎn)/分鐘),然后通過(guò)Serial.println將結(jié)果顯示輸出;再新建浮點(diǎn)型變量car_v2(車(chē)輪的時(shí)速),通過(guò)計(jì)算公式為其賦值為“car_v1*car_c*60/1000”(單位為千米/小時(shí)),同樣也是通過(guò)Serial.println將結(jié)果顯示輸出。
將程序代碼保存為“Speedometer.ino”,編譯上傳至Arduino進(jìn)行測(cè)試,操作方法與圖形化編程方式類(lèi)似,同樣注意要打開(kāi)“工具”菜單下的串口監(jiān)視器。此時(shí)可嘗試在古德微機(jī)器人網(wǎng)站的“積木”代碼中修改一下風(fēng)扇模塊的轉(zhuǎn)速,比如提高至原來(lái)的3倍大小,最終測(cè)試的結(jié)果為:“車(chē)輪的轉(zhuǎn)速(轉(zhuǎn)/分鐘)為:3444.00”“車(chē)輪的時(shí)速(千米/小時(shí))為:25.95”(如圖3)。
利用霍爾傳感器能夠?qū)z測(cè)到的磁場(chǎng)產(chǎn)生模擬量信號(hào)的特性,根據(jù)這個(gè)模擬量數(shù)據(jù)范圍再進(jìn)行映射計(jì)算,對(duì)應(yīng)驅(qū)動(dòng)LED燈亮度的PWM值(0-255),最終實(shí)現(xiàn)有“人”(帶磁鐵)靠近時(shí)LED燈才發(fā)光、越靠近LED的燈光就越亮的“智能路燈”效果——當(dāng)人遠(yuǎn)離至一定范圍時(shí)(霍爾傳感器檢測(cè)不到有磁場(chǎng)信號(hào)),LED燈熄滅。
實(shí)驗(yàn)器材包括ArduinoUNO一塊,KY-024霍爾傳感器一個(gè),紅色LED燈一支,圓形小磁鐵一個(gè),微型改錐一把,小型面包板一塊,杜邦線若干。首先,通過(guò)兩根杜邦線從Arduino中將5V和GND引至面包板的側(cè)邊紅色和藍(lán)色卡槽線;接著,將霍爾傳感器的VCC和GND端通過(guò)杜邦線連接至面包板的側(cè)邊卡槽,再將AO端連接至Arduino的A0模擬引腳;然后,將紅色LED燈的短腿插入面包板的藍(lán)色卡槽,長(zhǎng)腿則通過(guò)杜邦線連接至Arduino的3號(hào)引腳(序號(hào)前標(biāo)注有“~”表示支持PWM信號(hào));最后,將圓形小磁鐵吸至微型改錐的尖頭處,放置待用,給Arduino插入數(shù)據(jù)線與計(jì)算機(jī)的USB接口連接。
運(yùn)行Mind+,同樣也是先設(shè)置好串口的波特率為9600,然后在“循環(huán)執(zhí)行”中先建立變量“霍爾傳感器”,賦值為“讀取模擬引腳A0”的數(shù)據(jù),并且使用串口字符串輸出其讀取的磁場(chǎng)信號(hào)值;接著,新建變量“LED的PWM值”,為其賦值為“映射變量霍爾傳感器從[519,170]到[0,255]”,其中的519和170兩個(gè)數(shù)據(jù)是運(yùn)行程序測(cè)試得出的,分別對(duì)應(yīng)霍爾傳感器探頭周?chē)緹o(wú)磁場(chǎng)信號(hào)和小磁鐵最靠近探頭時(shí)讀取的模擬數(shù)據(jù)量,同樣也是將該值顯示輸出——“驅(qū)動(dòng)LED的PWM值”;然后,通過(guò)“設(shè)置PWM引腳3輸出”模塊將變量“LED的PWM值”作為目標(biāo)值,即控制LED燈發(fā)出對(duì)應(yīng)強(qiáng)度的光線;最后,添加“等待0.01秒”的延時(shí)模塊。
將程序保存為“Arduino‘智能路燈’.sb3”,連接設(shè)備后再上傳至Arduino進(jìn)行測(cè)試。當(dāng)微型改錐帶動(dòng)小磁鐵越來(lái)越靠近霍爾傳感器的探頭時(shí),之前保持熄滅狀態(tài)的紅色LED燈會(huì)逐漸發(fā)光,而且是隨著二者距離的縮短而越來(lái)越亮,直至相互接觸時(shí)發(fā)出最強(qiáng)的紅光;當(dāng)遠(yuǎn)離時(shí),LED燈的光線強(qiáng)度則會(huì)越來(lái)越弱,最終隨著距離的增大而熄滅。同時(shí),在屏幕的串口顯示窗口上也會(huì)不斷顯示有相對(duì)應(yīng)的提示信息:“從A0端讀取的磁場(chǎng)信號(hào)為:376.00”“驅(qū)動(dòng)LED的PWM值為:104.00”,實(shí)現(xiàn)了“智能路燈”的功能(如圖4)。
依照上面Arduino“時(shí)速計(jì)”的圖形化與代碼編程方式,同樣可以對(duì)“智能路燈”進(jìn)行代碼編程。