Category Archives: RASPBERRY PI 树莓派

【BASH SCRIPT】在树莓派上用HC-SR501红外感应器触发USB摄像头拍照

5-1假期闲的没事继续折腾树莓派。这次是尝试模拟一个防盗报警器,用HC-SR501 被动红外动作感应器 (Passive Infrared/PIR motion sensor)来触发USB camera拍照。大概的思路就是如果被动红外动作感应器被触发时,则调用USB摄像头连续拍照N次。

使用的设备:

  • 树莓派
  • HC-SR501 被动红外动作感应模块 (工作电压5V,信号输出未触发0V ,触发时3.3V)
  • USB摄像头 (我使用的是Logitech C920,其实完全不用这么高端的……)
  • LED x1
  • 470Ω 电阻 (与LED串联作为保护)
  • 杜邦线
  • 面包板

物理连线

连线之前的考虑:

  1. 许多传感器都没有电源接反的保护,接之前请务必再三确认正确再连接。
  2. 不同设备的数据输出不一定是3.3V的,有些有可能用5V表示1。我是先用万用表又验证了HC-SR501的数据输出是3.3V才敢连接树莓派的GPIO接口的。如果电压不匹配还非要去连接,则行为很可能异常,甚至损坏硬件。

线路连接:

rpi-HC-SR501-300x249
HC-SR501连接树莓派 接线示意图
gpio2_cb
HC-SR501连接树莓派 电路图
  • HC-SR501的电源连接树莓派5V输出,GND连接树莓派的GND,中间的data连接树莓派的GPIO接口,我使用的是11口 (GPIO 17)。
  • USB摄像头连接树莓派的USB接口 (我是实际是连接到USB hub上了)
  • 根据需要有可能要调整HC-SR501上的电位器来调节触发距离和延时
  • 根据需要有可能要调整HC-SR501上的跳线位置来设置允许多次重复触发

检查连线:

目视确认面包线连接正确并且牢固,使用lsusb查看系统是否识别出了USB摄像头,使用 ls /dev/video*  检验USB摄像头的编号。

实现所用的bash脚本

下面脚本其实是通过轮询的方式每间隔1秒(可调)通过sysfs方式查询一下sensor的状态,然后复制sensor状态到另外一个GPIO接口;如果sensor是被触发,则调用fswebcam来实现拍照。

脚本中我尽量将不同功能拆成函数了,尽管这样效率并不是最高的。在init_led和init_sensor函数中,尽管只有1个报警用的LED和1个sensor,我还是用循环的方式去做初始化,这也不是最优的方法。这样做主要是为了以后做多个sensor和多个LED故意预留的。

HC-SR501传感器是通过3.3V输出来表示被触发时的“1”,这个电压驱动LED也足够,我实际测试了,即使不没有树莓派,1个LED连接到HC-SR501的data输出已经可以实现灯光告警,但是在这个时候LED的光线不够亮,而且不连接树莓派也没法去调用USB摄像头拍照了 😕  ……

实验后考虑的改进

  1. 如果不想在屏幕上看到每次拍照时执行的细节,可以考虑为fswebcam加上-q参数,将脚本中的fswebcam命令修改成如下:
  2. 树莓派的SD卡空间有限,图片的贮存位置在脚本中默认写的是/tmp目录,当然通过Linux挂载NFS/Samba (NT Folder)/云端等等对这段脚本而言,都仅仅是在系统中的某个目录。因此这里就没有特别去在图片存储方面再多考虑了,利用Linux系统本身的能力即可实现将存储“网络化/云端化”。
  3. 本文是用bash脚本方式实现功能的,上面代码只是做功能演示,效率并不高。如果用C去写一段代码,当传感器被触发后,用中断的方式触发告警动作可能会是比轮询更好的选择。留待以后有时间再去琢磨。
  4. 这次我使用的HC-SR501 传感器并不足够敏感。做完所有测试之后,我故意试了试从远处以很慢的速度接近传感器,其实只要足够慢是可以不触发报警的……如果真的要用来做防盗报警器,估计还需要用更灵敏的传感器,甚至将不同种类的传感器进行结合使用。总体而言,这其实是一个非常非常简单的实验。这个实验中使用的传感器也应该是几乎最简单最入门的了,只有0(未触发)和1(触发)两个状态。写这个脚本仅是利用树莓派将传感器告警与后续动作连接起来。至于后续动作是亮个LED灯,还是拍照,甚至是打出去电话、记录日志、发短信、带动继电器做通/断电动作等都是可以实现的。等日后有更实际些的应用再看怎么做了。

对比用SHELL SCRIPT和C语言API操作RASPBERRY PI GPIO的速度

对Raspberry Pi的GPIO在shell script里面可以直接用sysfs的方式进行操作,也可以调用gpio命令来进行操作,还可以用API来进行操作。今天做了个实验对比sysfs方式、第三方gpio命令以及C语言API操作对效率的影响。

昨天写的文章里面提到了用GPIO来控制LED灯的显示,今天其实是突发奇想,想看看用第三方gpio命令来操作和直接操作sysfs的效率到底有多大的区别。

物理连线

连线和昨天写的文章里面的连线方法基本一样,只是在GPIO管脚和GND之间跨接了一个可以测频率的万用表(UNI-T UT136D)。

Shell Script 响应速度测试

测试脚本

方法1:直接调用sysfs控制通断

脚本中默认没有注释掉的就是方法1,相当于用下面命令来操作gpio实现让电路通断:

实测频率在1.1kHz左右。目测LED基本感觉不到闪烁。

测试结果照片如下,最后两位数字在不断跳动。

万用表测试GPIO接口频率 (Shell Script)

方法2:用shell脚本中的函数调用sysfs控制通断

相当于用下面命令来通过自定义函数gpio_ben操作gpio,实现电路通断:

【BASH脚本】通过LINUX SYSFS调用GPIO实现LED显示RASPBERRY PI内存占用率

这几天弄了个树莓派(Raspberry Pi)玩,装了个Linux。树莓派的GPIO其实非常容易调用,甚至可以直接通过Linux的sysfs来读写GPIO接口的状态,周末空闲的时候写了段bash Shell Script来控制LED灯来展示Linux的内存占用率。这只是个很简单的bash脚本,主要来示意一下如何通过Linux sysfs来调用GPIO来操作LED,通过修改脚本其实可以实现更多的功能,例如显示CPU的温度是否过高等。

我使用的硬件设备:

  1. Raspberry Pi
  2. LED x3 (不同颜色)
  3. 470Ω 电阻 x3 (用来为LED降压)
  4. 杜邦线 (母-公) x3 (用来连接树莓派的GPIO到面包板)
  5. 面包板 x1

第一步:用gpio命令验证物理连线

gpio命令是需要安装WiringPI之后才有的,默认系统不带。安装之后用root权限(sudo)执行 gpio readall,将得到类似下面的结果:

Phy对应的是针脚的位置, GPIO对应的是GPIO的编号。需要注意两点:

  1. 实际执行这个命令后Raspberry Pi显示的GPIO编号很可能和我的不一样,要仔细看好然后再看看要用哪个编号。
  2. GPIO的编号和物理针脚不一定是顺序对应的,比如我这次要用的是针脚11, 12, 13,对应的GPIO编号是17, 18, 27。当然如果要用wiringPi的逻辑pin的话就是0, 1, 2,但是我这次不打算用wiringPi,只用sysfs来实现对LED的控制。

第二步:连接线路

注意:连线前断电,连好之后请再三确认之后再通电!

raspberrypi-led-gpiov2
Raspberry Pi Control LED by using GPIO
gpio2_bb
GPIO LED 树莓派 面包板接线示意图

gpio_circuit_diagram-900x647
GPIO 连接LED 电路图

连接好线之后,请再次目视检查确认线没接错,特别是0v (GND)一定不要接错!再三确认之后再通电,进入Raspberry Pi的命令行界面测试接线是否正确。刚刚接好线的时候LED是不会像上图那样亮起来的,可以执行下面命令看看LED是否会亮(注意要有root权限):

修改GPIO的数字,依次测试。如果一切正常,那么三盏LED灯会依次亮起来,记住每个数字对应的LED的颜色。

第三步:编写脚本通过sysfs调用GPIO实现用LED灯展示内存占用率

我写的脚本如下,如果你愿意,你可以随意使用/修改后再使用/分发。

上面的脚本实现每10秒钟检查一次内存占用率(利用free命令),如果可用率高于60%,那么亮绿灯;如果可用率低于30%,则亮红灯。在30%到60%之间时亮橙色灯。在退出程序后,LED都会灭掉。

将上面脚本保存为.sh后缀,然后chmod +x赋予执行权限,再执行就可以了。

对上面的脚本稍加修改也可以实现用LED监控树莓派的CPU温度等等,这里就不一一列举代码了。用Shell获取树莓派的CPU/GPU温度可以参考这里:Raspberry Pi onboard temperature sensors