這篇博客展示了如何使用樹莓派上的神經(jīng)網(wǎng)絡(luò)USB插件來檢測或“推斷”一個(gè)人的位置,從而構(gòu)建一個(gè)安全系統(tǒng)。Arduino型接收器從零開始構(gòu)建,通過遠(yuǎn)程LoRa射頻協(xié)議從樹莓派發(fā)射器獲取數(shù)據(jù),并顯示和發(fā)出警報(bào)。我試著展示了這個(gè)項(xiàng)目背后的一些想法,展示的是一整套python,arduino和PCB等等以便實(shí)施。
難度級(jí)別:需要具備一定的樹莓派技能但是并非專家級(jí),焊接技能簡單。
網(wǎng)絡(luò)上關(guān)于LoRa的大部分信息似乎都指向“Things Network”,但如果我們只需要在兩個(gè)設(shè)備之間進(jìn)行基本數(shù)據(jù)傳輸,而不希望全世界都能看到我們的數(shù)據(jù),該怎么辦呢?那就需要點(diǎn)對(duì)點(diǎn)通信了。
在本例中,樹莓派搭配Dragonino LoRa/GPS擴(kuò)展板,將遠(yuǎn)程位置(如農(nóng)場大門)的安全狀態(tài)數(shù)據(jù)發(fā)送出去,以告知我們是否有人進(jìn)入,甚至是否有人偷走了我們的牛。接收器是Arduino MKRWAN 1300,上面焊接了專用的LoRa芯片。注意:這款A(yù)rduino是3.3V設(shè)備,如果向任何(或大多數(shù))引腳施加5V電壓,設(shè)備將被燒毀。此外,在未連接天線的情況下,切勿操作Dragino擴(kuò)展板或Arduino設(shè)備!就代碼而言,兩者都非常簡單,盡管我花了一段時(shí)間才弄清楚需要為Arduino刷入固件升級(jí)才能使其正常工作。插入Dragino擴(kuò)展板后,樹莓派的處理步驟如下:
$wget "https://codeload.github.com/dragino/rpi-lora-tranceiver/zip/master> "https://codeload.github.com/dragino/rpi-lora-tran...> "https://codeload.github.com/dragino/rpi-lora-tran...> "https://codeload.github.com/dragino/rpi-lora-tran...> "https://codeload.github.com/dragino/rpi-lora-tran...> https://codeload.github.com/dragino/rpi-lora-tran...>>>>>$ unzip master$cdrpi-lora-tranceiver-master/dragino_lora_app$make$cdrpi-lora-tranceiver-master/dragino_lora_app &&./dragino_lora_app$./dragino_lora_app sender
此數(shù)據(jù)不安全,但如有需要,可以使用Python腳本。
重要提示:RPi必須配備合適的電源,并在設(shè)置中啟用SPI。使用的操作系統(tǒng)是Raspian Stretch。Arduino的設(shè)置同樣簡單,但需注意以下幾點(diǎn):
首先,在我的案例中,RPi嘗試每3秒在868.1 MHz頻率上發(fā)送“HELLO”,因此Arduino需相應(yīng)配置……868.1 MHz = 8681 x 105 = 8681E5。其他地區(qū)(如美國)使用不同頻率。然后在從此處下載Arduino LoRa庫(兩者均需安裝)
以正常方式安裝庫后,打開MKWAN示例集,將“MKRWANFWUpdate _ standalone”加載到Arduino并打開串行控制臺(tái)。觀察更新進(jìn)度,接下來,找到“LoRa”示例集,選擇“LoRaReceiver”并上傳。不要忘記像前面提到的那樣編輯頻率!打開串行控制臺(tái),您應(yīng)該會(huì)看到從RPI發(fā)送的HELLO。

第一步:組件清單


Arduino MKRWAN 1300
樹莓派3
RS PRO 5V表面貼裝電磁蜂鳴器,97dB(3個(gè))
PCB滑動(dòng)開關(guān)(單刀雙擲,鎖存型,3A @ 120V AC)
L293E電機(jī)驅(qū)動(dòng)IC(STMicroelectronics,36V 1A)
Draganino Seeed Studio Raspberry Pi LoRa/GPS HAT(支持868MHz)
Arduino PCB天線
樹莓派PiNoir相機(jī)V2模塊(CSI-2,3280×2464分辨率)
Logitech C930e全高清攝像頭
Movidius神經(jīng)網(wǎng)絡(luò)計(jì)算棒NCSM2450.DK1
USB延長線(12CM USB 2.0 AM AF BLK EXT)
帶透明蓋的機(jī)箱
39Ω電阻
第二步:將代碼移植到Python
由于神經(jīng)網(wǎng)絡(luò)模塊使用Python 3,我認(rèn)為讓樹莓派的LoRa發(fā)射器HAT(Dragonino)也通過Python控制更合理。
但需補(bǔ)充幾個(gè)步驟,此處詳細(xì)說明:
1.從RPi取出SD卡,插入合適的PC。
2.將/boot文件夾中的config.txt復(fù)制到桌面。
3.使用chmod 777修改權(quán)限,編輯文件并添加:
dtoverlay=spi0-cs,cs0_pin=25
到文件頂部。
4.保存后將文件復(fù)制回SD卡的boot文件夾。這是唯一快捷的編輯方式!
5.下載Python文件:https://github.com/mayeranalytics/pySX127x?, 解壓后用文本編輯器打開 'board_config.py'。
6.在board_config中設(shè)置以下值:
DIO0=4 DIO1=23 DIO2=24 DIO3=21 LED=18 SWITCH=7
注意:若在歐洲,使用868 MHz頻段,需將low_band = true改為false(根據(jù)注釋說明)。
low_band=true
7.修改constants.py文件,添加以下內(nèi)容(注意用4個(gè)空格縮進(jìn)以兼容Python格式):
@add_lookupclassSPI_BAUD_RATE: MAX_SPEED_HZ= 5000@add_lookupclassSPI_MODE: SPI_MODE= 0b01
8.打開LoRa.py文件,找到spi = BOARD.SpiDev():
spi= BOARD.SpiDev()
在其下插入
spi.max_speed_hz= SPI_BAUD_RATE.MAX_SPEED_HZspi.mode= SPI_MODE.SPI_MODE
9.打開終端,進(jìn)入包含tx_beacon.py的目錄(如cd /home/pi/Desktop/dragonino/psySX127x-master/)。
10.其中,“869”是以MHz為單位的頻率,“7”是擴(kuò)頻因子,使用python tx_beacon.py -f 869 -s 7運(yùn)行信標(biāo)程序
11.將Arduino調(diào)至8690E5,串口控制臺(tái)應(yīng)顯示類似以下內(nèi)容:
Receivedpacket' 'withRSSI-33Receivedpacket' 'withRSSI-23Receivedpacket' 'withRSSI-33Receivedpacket' 'withRSSI-26Receivedpacket' 'withRSSI-25
成功!
12.如需顯示更有意義的內(nèi)容,用文本編輯器打開tx_beacon.py,找到第65行附近的:
self.write_payload([0x0f])
修改為:
self.write_payload([0x57,0x68,0x61,0x74,0x20,0x74,0x68,0x65,0x20,0x66,0x75,0x63,0x6B,0x21])
第三步:準(zhǔn)備Python傳輸數(shù)據(jù)
我以前沒有用Python編程過,但是與C++相比,它已經(jīng)看起來簡單多了,也直觀多了。
我發(fā)現(xiàn)Lora信標(biāo)可能是起點(diǎn),它需要一個(gè)代表ANSII字符的數(shù)字“列表”,這些數(shù)字可以是十進(jìn)制或十六進(jìn)制值。信標(biāo)程序中傳輸數(shù)據(jù)的實(shí)際短語在第65行:
self.write_payload(j)
其中j是有效載荷列表,對(duì)于“Hello World”來說,它通常看起來像這樣:
([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100])
為了將“Hello World”轉(zhuǎn)換成該列表格式,使用了以下代碼:
importarrayasarr
importnumpyasnp
c='Hello World'g = arr.array('i',[])n=-1forhinrange(len(c)): g.extend([0])forxinc: n = n+1 y =ord(x) g[n] = yprint(g)j = np.array(g).tolist()
代碼將字符串中的每個(gè)字符轉(zhuǎn)換為整數(shù)數(shù)組中的一個(gè)整數(shù),用字母“I”表示,長度為c,對(duì)應(yīng)于字符串中字符和空格的數(shù)量。extend命令擴(kuò)展數(shù)組以接受更多的整數(shù)。接下來,對(duì)于字符串中的每個(gè)字符,“ord”命令執(zhí)行實(shí)際的字符到整數(shù)的轉(zhuǎn)換,然后“g[n] = y”將其轉(zhuǎn)儲(chǔ)到數(shù)組中的正確位置。最后一個(gè)是array to list命令,它將整個(gè)數(shù)組轉(zhuǎn)換成列表格式。簡單!
在本博客的文件部分,新的LoRa信標(biāo)文件被稱為Tegwyns_LoRa_Beacon,假設(shè)它與原始信標(biāo)文件位于同一位置,它將從命令行運(yùn)行:
cd/home/pi/Desktop/dragonino_python_fix/pySX127x-master/ && python3 Tegwyns_LoRa_Beacon.py -f 869 -s 7-
在這一階段,使用SDR-RTL USB加密狗通過Cubic SDR等軟件及其頻譜分析儀功能來檢測和分析傳輸信號(hào)是一個(gè)好主意,但不是必需的。

y
第四步:使用神經(jīng)計(jì)算棒實(shí)現(xiàn)“人物檢測”

開始之前需要注意幾個(gè)關(guān)鍵事項(xiàng):
樹莓派的正確神經(jīng)計(jì)算棒是NCSM2450。DK1,目前(2018年)沒有其他英特爾棒將在樹莓派上工作。注意下載的是stick SDK還是APi的哪個(gè)版本——V2及以上版本不是針對(duì)Raspbian stretch的,僅支持Ubuntu 16.04。
說明:
1.安裝SDK 1.0完整版和API(耗時(shí)較短):
$sudo apt-get update$sudo apt-get install$gitclonehttps://github.com/movidius/ncsdk.git$cd/home/pi/ncsdk && sudo make install$cd/home/pi/ncsdk && sudo make examples
2.測試計(jì)算棒是否正常工作:
$gitclonehttps://github.com/movidius/ncappzoo$cd/home/pi/ncappzoo/apps/hello_ncs_py$python3 hello_ncs.py
3.下載文件: https://cdn.hackaday.io/files/1626676959544928/graph 并粘貼到 /home/pi/ncappzoo/caffe/SSD_MobileNet文件夾.不要改變名字和擴(kuò)展名.
4. 編譯并運(yùn)行演示:
$cd/home/pi/ncappzoo/apps/security-cam$make run
需使用攝像頭(如USB Logitech,即插即用)。
第五步:整合LoRa與安全攝像頭

這有點(diǎn)像一場戰(zhàn)斗,Python的學(xué)習(xí)曲線很陡,但是最后,我創(chuàng)建了一個(gè)Python文件,可以將時(shí)間戳、檢測類別、置信度和邊界框坐標(biāo)發(fā)送到Arduino基站。顯然,在不同的目錄中仍然有大量的依賴關(guān)系——一些就在附近,而另一些則深深地嵌入在Python系統(tǒng)的某個(gè)地方,此處是我的“棧頂”代碼:
第六步:升級(jí)攝像頭至樹莓派NoIR V2

顯然,我們想在黑暗中用紅外線燈使用這個(gè)小工具,所以我們需要一個(gè)有紅外線功能的像樣的相機(jī),既沒有紅外線過濾器的相機(jī)。幸運(yùn)的是,這些相機(jī)比羅技USB便宜得多,也更緊湊,而且安裝也很容易:
首先,檢查樹莓派設(shè)置中的攝像頭是否已啟用,然后,在將其插入主板后,檢查它是否能與以下設(shè)備一起工作:
$raspistill -o image.jpg
接下來安裝以下 Python 依賴項(xiàng)
$sudo apt-get install python3-picamera$pip3 install"picamera[array]"$pip3 install imutils
最后,使用樹莓派cam版本的security_cam文件
用以下命令運(yùn)行文件
$cd&&cd/home/pi/ncappzoo/apps/securityCam && python3 security_camPiCam.py
安全攝像頭現(xiàn)在可以在野外測試了,顯然不是在雨中!如果有一個(gè)像樣的天線,可以看看發(fā)射機(jī)的范圍會(huì)很有趣:)
需要注意的一點(diǎn)是,Noire相機(jī)給出的色彩平衡結(jié)果與USB相機(jī)非常不同,這是完全正常的,因?yàn)殓R頭上沒有紅外濾光片。
除了防水之外,另一個(gè)問題是當(dāng)設(shè)備發(fā)現(xiàn)一個(gè)人時(shí),在哪里收集拍攝的照片-也許是一個(gè)u盤,以防止填滿樹莓派SD卡?
第七步:將攝像頭快照保存到USB驅(qū)動(dòng)器

通過將第235行修改為類似下面的內(nèi)容,可以很容易地修改安全cam Python文件,以保存檢測到的人的重復(fù)快照,其中我的USB驅(qū)動(dòng)器稱為“KINSTON”:
photo= ("/media/pi/KINGSTON"+"/captures/photo_"+ cur_time +".jpg")
實(shí)際上,使用這個(gè)u盤大大降低了程序的運(yùn)行速度!部署后,如果使用另一臺(tái)PC通過SSH連接到樹莓派,則可以輕松地從樹莓派傳輸/刪除圖像。一個(gè)更好的解決方案可能是在micro SD卡上創(chuàng)建一個(gè)分區(qū),這樣如果它充滿了圖像,它就不會(huì)阻塞操作系統(tǒng)和相機(jī)python腳本。
第八步:接收器PCB組裝



除了Arduino MKRWAN 1300之外,PCB還具有一個(gè)L293E芯片,用于提高報(bào)警系統(tǒng)所需的電壓和電流,該系統(tǒng)本身是一個(gè)由8個(gè)led和3個(gè)蜂鳴器芯片組成的模塊。如果直接在Arduino上運(yùn)行這些設(shè)備會(huì)立刻讓設(shè)備崩潰!在組裝和測試后,整個(gè)系統(tǒng)運(yùn)行良好,經(jīng)過實(shí)驗(yàn),紅色發(fā)光二極管的最佳電阻是39歐姆。
雖然大多數(shù)元件都是表面貼裝,但它們都非常大,不需要模板。檢查完led的極性后,用焊料將PCB粘好,安裝表面貼裝元件,然后夾在烤箱中加熱至260攝氏度。可以使用熱風(fēng)槍,但不建議使用。
第九步:部署攝像頭


可以看出,這種裝置非常容易組裝,只需要放在一個(gè)前面透明的防水盒中。使用厚紙板和一點(diǎn)折紙將上述組件緊緊地楔入盒子中。
注意:攝像頭必須在正確的方向上,神經(jīng)網(wǎng)絡(luò)才能正常工作。
第十步:Arduino MKRWAN 1300代碼

代碼沒什么特別的,除了可以讓蜂鳴器的音調(diào)根據(jù)被檢測的人離攝像機(jī)的距離而改變。這將有助于辨別在郵箱里寄信的人和真正走上車道的人之間的區(qū)別。該代碼使用字符串分析函數(shù),首先通過搜索單詞“Box”來確認(rèn)數(shù)據(jù)是一致的,然后找到代表檢測框的兩對(duì)坐標(biāo)。如果檢測到的人靠近攝像機(jī),檢測框的面積會(huì)更大,產(chǎn)生的報(bào)警音頻率會(huì)更高:
#include#includeString myString =" ";String myStringReversed =" ";voidsetup(){ pinMode(4, OUTPUT); pinMode(LED_BUILTIN, OUTPUT); tone(5,1000,1000); digitalWrite(LED_BUILTIN, HIGH); digitalWrite(4, HIGH); delay(1000); digitalWrite(LED_BUILTIN, LOW); digitalWrite(4, LOW); Serial.begin(9600);
// while (!Serial); Serial.println("LoRa Receiver"); if(!LoRa.begin(8690E5)) { Serial.println("Starting LoRa failed!"); while(1); }}voidloop(){ //delay (1000);
// try to parse packet intpacketSize = LoRa.parsePacket(); if(packetSize)
{ // received a packet Serial.print("Received packet '"); digitalWrite(LED_BUILTIN, HIGH); digitalWrite(4, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); digitalWrite(4, LOW); // read packet myString =" "; myStringReversed =" "; inti =0; charc; while(LoRa.available())
{ //c[i] = (char)LoRa.read(); //Serial.print((char)LoRa.read()); myString = (char)LoRa.read() + myString; i++; //Reverse the string: c = myString.charAt(0); myStringReversed = myStringReversed + c; } processString(); //Serial.print("My string:
");Serial.print(myString); // print RSSI of packet //Serial.print("' with RSSI "); //Serial.println(LoRa.packetRssi());
}}voidprocessString(){ Serial.print("My string reversed:");Serial.print(myStringReversed); // print RSSI of packet Serial.print("' with RSSI "); Serial.println(LoRa.packetRssi());
intlen = myStringReversed.length(); intj=0; chara,b,c,d; String coord1 =" "; String coord2 =" "; String coord3 =" "; String coord4 =" ";
intk =0; charx =',';
intz=1; inty=1; intr=1; ints=1; intv=0; while(j < len)?? ?
{ a = myStringReversed.charAt(j); b = myStringReversed.charAt(j+1);
c = myStringReversed.charAt(j+2);
if((a=='B')&&(b=='o')&&(c=='x')) // The word 'box' has been identified in the string - k is now greater than 0. { k = j+5; Serial.print("Character B was found at: ");Serial.println(j); } j++; } if(k>0) { v =0;
// int V stops perpetual loops occurring. while((z==1)&&(v<200))? ? ? {? ? ? ? if(myStringReversed.charAt(k)==x) ? ??
// Build up string 'coord' until a comma is reached. { Serial.print("k");Serial.println(k);
z=0; }
else
{ coord1 = coord1 + myStringReversed.charAt(k); k++; v++; //Serial.print("coord1: ");Serial.println(coord1); } } v =0; k++; while((y==1)&&(v<200))?
{ if(myStringReversed.charAt(k)==')')
// Build up string 'coord' until a comma is reached. { Serial.print("k");Serial.println(k); y=0; } else {
coord2 = coord2 + myStringReversed.charAt(k); k++; v++; //Serial.print("coord2: ");Serial.println(coord2); } } v =0; k=k+3;
// Takes account of two brackets and a comma. while((r==1)&&(v<200))? ? ? {? ? ? ? if(myStringReversed.charAt(k)==x) ? ? ? ?
// Build up string 'coord' until a comma is reached.
{ Serial.print("k");Serial.println(k); r=0; } else {
coord3 = coord3 + myStringReversed.charAt(k);
k++; v++; //Serial.print("coord3: ");Serial.println(coord3); } } v =0; k++; while((s==1)&&(v<200))? ? ? {? ? ?
if(myStringReversed.charAt(k)==')') // Build up string 'coord' until a comma is reached. {
Serial.print("k");Serial.println(k); s=0;
} else
{ coord4 = coord4 + myStringReversed.charAt(k); k++; v++; //Serial.print("coord4: ");Serial.println(coord4);
} } } Serial.print("coord1: ");Serial.println(coord1); Serial.print("coord2: ");Serial.println(coord2); Serial.print("coord3: ");Serial.println(coord3); Serial.print("coord4: ");Serial.println(coord4); intcoord10 = coord1.toInt(); intcoord20 = coord2.toInt(); intcoord30 = coord3.toInt(); intcoord40 = coord4.toInt(); intarea = (coord40 - coord20) * (coord30 - coord10); tone(5,(area/100)+200,100); Serial.print("Box area: ");Serial.println(area);}
第十一步:檢測其他對(duì)象和動(dòng)物

“security_cam.py”文件是一個(gè)通用的“活體檢測”文件腳本,可以很容易地修改,以檢測總共20個(gè)不同的對(duì)象。
如果我們看第119行:
# "Class of interest" - Display detections only if they match this class IDCLASS_PERSON =15
要檢測狗,只需將其更改為:
# "Class of interest" - Display detections only if they match this class IDCLASS_DOG =12
此外,第200行也需要更改:
# Filter a specific class/category if( output_dict.get('detection_classes_'+str(i) ) == CLASS_PERSON ):
雖然person類工作得非常好,給人留下了深刻的印象,但是dog類就有點(diǎn)令人印象不深,遠(yuǎn)不如我測試過的其他一些模型。盡管如此,這是這種模型可用的全部類列表:飛機(jī) 自行車 鳥 船 瓶子 公共汽車 貓 椅子 牛 餐桌 狗 馬 摩托車人 盆栽 植物 羊 沙發(fā) 火車 電視監(jiān)視器
第十二步:系統(tǒng)測試

在將系統(tǒng)置于headless模式并使用SSH通過筆記本電腦登錄后,我能夠在“現(xiàn)場”測試系統(tǒng)。最初,有一個(gè)錯(cuò)誤導(dǎo)致相機(jī)在15分鐘后關(guān)閉,這是通過在樹莓派上安裝“screen”并在啟動(dòng)python文件之前在命令行中鍵入“screen”來解決的。screen所做的是打開樹莓派上的另一個(gè)終端,因此它有自己的活動(dòng)終端,當(dāng)我的筆記本電腦終端關(guān)閉時(shí),它不會(huì)關(guān)閉。這是一個(gè)非常好的解決方案,避免了與其他“啟動(dòng)時(shí)運(yùn)行”解決方案的混亂,而且后者可能會(huì)破壞整個(gè)系統(tǒng)。
一臺(tái)獨(dú)立的攝像機(jī)安裝在我的辦公室里,在200米外,與主攝像機(jī)同步,聚焦在接收器上(視頻右下角)。在測試中,系統(tǒng)對(duì)相機(jī)畫面中的狗沒有反應(yīng),但對(duì)我(一個(gè)人)有反應(yīng)…..成功!
我打算在某個(gè)階段將整個(gè)系統(tǒng)升級(jí)到Movidius neural stick 2,并使用一個(gè)更大的帶分區(qū)的micro SD卡,來防止拍攝的圖像堵塞。
原文地址:
https://www.instructables.com/LoRa-Neural-Network-Security-System/
-
神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
42文章
4820瀏覽量
106338 -
安防系統(tǒng)
+關(guān)注
關(guān)注
2文章
258瀏覽量
34191 -
樹莓派
+關(guān)注
關(guān)注
122文章
2067瀏覽量
109128 -
LoRa
+關(guān)注
關(guān)注
353文章
1822瀏覽量
236749
發(fā)布評(píng)論請先 登錄
芯品#MAX78002 新型AI MCU,能夠使神經(jīng)網(wǎng)絡(luò)以超低功耗運(yùn)行

低功耗+AI識(shí)別:基于樹莓派的 LoRa 神經(jīng)網(wǎng)絡(luò)安防系統(tǒng)!
評(píng)論