这篇博客展示了如何使用树莓派上的神经网络USB插件来检测或“推断”一个人的位置,从而构建一个安全系统。Arduino型接收器从零开始构建,通过远程LoRa射频协议从树莓派发射器获取数据,并显示和发出警报。我试着展示了这个项目背后的一些想法,展示的是一整套python,arduino和PCB等等以便实施。
难度级别:需要具备一定的树莓派技能但是并非专家级,焊接技能简单。
网络上关于LoRa的大部分信息似乎都指向“Things Network”,但如果我们只需要在两个设备之间进行基本数据传输,而不希望全世界都能看到我们的数据,该怎么办呢?那就需要点对点通信了。
在本例中,树莓派搭配Dragonino LoRa/GPS扩展板,将远程位置(如农场大门)的安全状态数据发送出去,以告知我们是否有人进入,甚至是否有人偷走了我们的牛。接收器是Arduino MKRWAN 1300,上面焊接了专用的LoRa芯片。注意:这款Arduino是3.3V设备,如果向任何(或大多数)引脚施加5V电压,设备将被烧毁。此外,在未连接天线的情况下,切勿操作Dragino扩展板或Arduino设备!就代码而言,两者都非常简单,尽管我花了一段时间才弄清楚需要为Arduino刷入固件升级才能使其正常工作。插入Dragino扩展板后,树莓派的处理步骤如下:
$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
此数据不安全,但如有需要,可以使用Python脚本。
重要提示:RPi必须配备合适的电源,并在设置中启用SPI。使用的操作系统是Raspian Stretch。Arduino的设置同样简单,但需注意以下几点:
首先,在我的案例中,RPi尝试每3秒在868.1 MHz频率上发送“HELLO”,因此Arduino需相应配置……868.1 MHz = 8681 x 105 = 8681E5。其他地区(如美国)使用不同频率。然后在从此处下载Arduino LoRa库(两者均需安装)
以正常方式安装库后,打开MKWAN示例集,将“MKRWANFWUpdate _ standalone”加载到Arduino并打开串行控制台。观察更新进度,接下来,找到“LoRa”示例集,选择“LoRaReceiver”并上传。不要忘记像前面提到的那样编辑频率!打开串行控制台,您应该会看到从RPI发送的HELLO。

第一步:组件清单
Arduino MKRWAN 1300
树莓派3
RS PRO 5V表面贴装电磁蜂鸣器,97dB(3个)
PCB滑动开关(单刀双掷,锁存型,3A @ 120V AC)
L293E电机驱动IC(STMicroelectronics,36V 1A)
Draganino Seeed Studio Raspberry Pi LoRa/GPS HAT(支持868MHz)
Arduino PCB天线
树莓派PiNoir相机V2模块(CSI-2,3280×2464分辨率)
Logitech C930e全高清摄像头
Movidius神经网络计算棒NCSM2450.DK1
USB延长线(12CM USB 2.0 AM AF BLK EXT)
带透明盖的机箱
39Ω电阻
第二步:将代码移植到Python
由于神经网络模块使用Python 3,我认为让树莓派的LoRa发射器HAT(Dragonino)也通过Python控制更合理。
但需补充几个步骤,此处详细说明:
1.从RPi取出SD卡,插入合适的PC。
2.将/boot文件夹中的config.txt复制到桌面。
3.使用chmod 777修改权限,编辑文件并添加:
dtoverlay=spi0-cs,cs0_pin=25
到文件顶部。
4.保存后将文件复制回SD卡的boot文件夹。这是唯一快捷的编辑方式!
5.下载Python文件:https://github.com/mayeranalytics/pySX127x , 解压后用文本编辑器打开 'board_config.py'。
6.在board_config中设置以下值:
DIO0=4 DIO1=23 DIO2=24 DIO3=21 LED=18 SWITCH=7
注意:若在欧洲,使用868 MHz频段,需将low_band = true改为false(根据注释说明)。
low_band=true
7.修改constants.py文件,添加以下内容(注意用4个空格缩进以兼容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.打开终端,进入包含tx_beacon.py的目录(如cd /home/pi/Desktop/dragonino/psySX127x-master/)。
10.其中,“869”是以MHz为单位的频率,“7”是扩频因子,使用python tx_beacon.py -f 869 -s 7运行信标程序
11.将Arduino调至8690E5,串口控制台应显示类似以下内容:
Receivedpacket' 'withRSSI-33Receivedpacket' 'withRSSI-23Receivedpacket' 'withRSSI-33Receivedpacket' 'withRSSI-26Receivedpacket' 'withRSSI-25
成功!
12.如需显示更有意义的内容,用文本编辑器打开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])
第三步:准备Python传输数据
我以前没有用Python编程过,但是与C++相比,它已经看起来简单多了,也直观多了。
我发现Lora信标可能是起点,它需要一个代表ANSII字符的数字“列表”,这些数字可以是十进制或十六进制值。信标程序中传输数据的实际短语在第65行:
self.write_payload(j)
其中j是有效载荷列表,对于“Hello World”来说,它通常看起来像这样:
([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100])
为了将“Hello World”转换成该列表格式,使用了以下代码:
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()
代码将字符串中的每个字符转换为整数数组中的一个整数,用字母“I”表示,长度为c,对应于字符串中字符和空格的数量。extend命令扩展数组以接受更多的整数。接下来,对于字符串中的每个字符,“ord”命令执行实际的字符到整数的转换,然后“g[n] = y”将其转储到数组中的正确位置。最后一个是array to list命令,它将整个数组转换成列表格式。简单!
在本博客的文件部分,新的LoRa信标文件被称为Tegwyns_LoRa_Beacon,假设它与原始信标文件位于同一位置,它将从命令行运行:
cd/home/pi/Desktop/dragonino_python_fix/pySX127x-master/ && python3 Tegwyns_LoRa_Beacon.py -f 869 -s 7-
在这一阶段,使用SDR-RTL USB加密狗通过Cubic SDR等软件及其频谱分析仪功能来检测和分析传输信号是一个好主意,但不是必需的。
y
第四步:使用神经计算棒实现“人物检测”
开始之前需要注意几个关键事项:
树莓派的正确神经计算棒是NCSM2450。DK1,目前(2018年)没有其他英特尔棒将在树莓派上工作。注意下载的是stick SDK还是APi的哪个版本——V2及以上版本不是针对Raspbian stretch的,仅支持Ubuntu 16.04。
说明:
1.安装SDK 1.0完整版和API(耗时较短):
$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.测试计算棒是否正常工作:
$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文件夹.不要改变名字和扩展名.
4. 编译并运行演示:
$cd/home/pi/ncappzoo/apps/security-cam$make run
需使用摄像头(如USB Logitech,即插即用)。
第五步:整合LoRa与安全摄像头
这有点像一场战斗,Python的学习曲线很陡,但是最后,我创建了一个Python文件,可以将时间戳、检测类别、置信度和边界框坐标发送到Arduino基站。显然,在不同的目录中仍然有大量的依赖关系——一些就在附近,而另一些则深深地嵌入在Python系统的某个地方,此处是我的“栈顶”代码:
第六步:升级摄像头至树莓派NoIR V2
显然,我们想在黑暗中用红外线灯使用这个小工具,所以我们需要一个有红外线功能的像样的相机,既没有红外线过滤器的相机。幸运的是,这些相机比罗技USB便宜得多,也更紧凑,而且安装也很容易:
首先,检查树莓派设置中的摄像头是否已启用,然后,在将其插入主板后,检查它是否能与以下设备一起工作:
$raspistill -o image.jpg
接下来安装以下 Python 依赖项
$sudo apt-get install python3-picamera$pip3 install"picamera[array]"$pip3 install imutils
最后,使用树莓派cam版本的security_cam文件
用以下命令运行文件
$cd&&cd/home/pi/ncappzoo/apps/securityCam && python3 security_camPiCam.py
安全摄像头现在可以在野外测试了,显然不是在雨中!如果有一个像样的天线,可以看看发射机的范围会很有趣:)
需要注意的一点是,Noire相机给出的色彩平衡结果与USB相机非常不同,这是完全正常的,因为镜头上没有红外滤光片。
除了防水之外,另一个问题是当设备发现一个人时,在哪里收集拍摄的照片-也许是一个u盘,以防止填满树莓派SD卡?
第七步:将摄像头快照保存到USB驱动器

通过将第235行修改为类似下面的内容,可以很容易地修改安全cam Python文件,以保存检测到的人的重复快照,其中我的USB驱动器称为“KINSTON”:
photo= ("/media/pi/KINGSTON"+"/captures/photo_"+ cur_time +".jpg")
实际上,使用这个u盘大大降低了程序的运行速度!部署后,如果使用另一台PC通过SSH连接到树莓派,则可以轻松地从树莓派传输/删除图像。一个更好的解决方案可能是在micro SD卡上创建一个分区,这样如果它充满了图像,它就不会阻塞操作系统和相机python脚本。
第八步:接收器PCB组装
除了Arduino MKRWAN 1300之外,PCB还具有一个L293E芯片,用于提高报警系统所需的电压和电流,该系统本身是一个由8个led和3个蜂鸣器芯片组成的模块。如果直接在Arduino上运行这些设备会立刻让设备崩溃!在组装和测试后,整个系统运行良好,经过实验,红色发光二极管的最佳电阻是39欧姆。
虽然大多数元件都是表面贴装,但它们都非常大,不需要模板。检查完led的极性后,用焊料将PCB粘好,安装表面贴装元件,然后夹在烤箱中加热至260摄氏度。可以使用热风枪,但不建议使用。
第九步:部署摄像头
可以看出,这种装置非常容易组装,只需要放在一个前面透明的防水盒中。使用厚纸板和一点折纸将上述组件紧紧地楔入盒子中。
注意:摄像头必须在正确的方向上,神经网络才能正常工作。
第十步:Arduino MKRWAN 1300代码
代码没什么特别的,除了可以让蜂鸣器的音调根据被检测的人离摄像机的距离而改变。这将有助于辨别在邮箱里寄信的人和真正走上车道的人之间的区别。该代码使用字符串分析函数,首先通过搜索单词“Box”来确认数据是一致的,然后找到代表检测框的两对坐标。如果检测到的人靠近摄像机,检测框的面积会更大,产生的报警音频率会更高:
#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);}
第十一步:检测其他对象和动物
“security_cam.py”文件是一个通用的“活体检测”文件脚本,可以很容易地修改,以检测总共20个不同的对象。
如果我们看第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类就有点令人印象不深,远不如我测试过的其他一些模型。尽管如此,这是这种模型可用的全部类列表:飞机 自行车 鸟 船 瓶子 公共汽车 猫 椅子 牛 餐桌 狗 马 摩托车人 盆栽 植物 羊 沙发 火车 电视监视器
第十二步:系统测试
在将系统置于headless模式并使用SSH通过笔记本电脑登录后,我能够在“现场”测试系统。最初,有一个错误导致相机在15分钟后关闭,这是通过在树莓派上安装“screen”并在启动python文件之前在命令行中键入“screen”来解决的。screen所做的是打开树莓派上的另一个终端,因此它有自己的活动终端,当我的笔记本电脑终端关闭时,它不会关闭。这是一个非常好的解决方案,避免了与其他“启动时运行”解决方案的混乱,而且后者可能会破坏整个系统。
一台独立的摄像机安装在我的办公室里,在200米外,与主摄像机同步,聚焦在接收器上(视频右下角)。在测试中,系统对相机画面中的狗没有反应,但对我(一个人)有反应…..成功!
我打算在某个阶段将整个系统升级到Movidius neural stick 2,并使用一个更大的带分区的micro SD卡,来防止拍摄的图像堵塞。
原文地址:
https://www.instructables.com/LoRa-Neural-Network-Security-System/
-
神经网络
+关注
关注
42文章
4814浏览量
103444 -
安防系统
+关注
关注
2文章
254浏览量
33814 -
树莓派
+关注
关注
121文章
1995浏览量
107369 -
LoRa
+关注
关注
352文章
1778浏览量
234740
发布评论请先 登录
芯品#MAX78002 新型AI MCU,能够使神经网络以超低功耗运行

评论