0x01 前言
我家里有一套在停电情况下给服务器供电的锂电池组,为监控电池组的健康状态,我特意购买了温湿度传感地和电压传感器,还有火焰传感器用于检测危险情况。
0x02 基本情况
据我了解,树莓派的GPIO接口需要接收数字信号,但我没找到可以直接测量电压并输出数字信号的模块,只找到一款需要串联在电路中的检测模块,可以检测电压与电流,这款模块是:INA219 GY-219,外观如下:
相关的电路图如下:
如果直接将正负极连接在电池上,则会短路,电流无限大,这将会损坏电池,甚至使电池发生爆炸。
因为我需要监测电池电压,所以这种方案是行不通的,然后找到一种模块:
该模块的电路图如下:
该模块可以检测25v以下的电压,但这个模块只能输出模拟信号,如果想通过树莓派读取数据,有两种解决办法:一种是接一个模拟/数字信号转换芯片;另一种是通过arduino读取。
因为我需要连接多个传感器,所以选择连接arduino的解决方式。
上面的电路图中,VCC接电池的正极、GND接电池的负极,S接arduino的信号pin,-接arduino的负极。
连接方式大致如下:
0x03 arduino
据我的了解,arduino是一款单片机,可以将程序通过IDE写到芯片里,与各类传感器通讯并返还数据的一款自由度很高的平台。
可是我完全没接触过arduino相关的知识,经过一周的学习了解后发现,想arduino与树莓派相互通讯并不难,只需要通过USB连接两者:
然后在树莓派中安装IDE即可完成程序在arduino中的烧录:
0x04 UUGear
解决连接的问题后,还需要解决以下问题:
arduino上有许多针脚,我想通过python脚本去读取,可我完全不知道从何处入手。在一番了解之后,发现已经有人做出了相关的库:
- GitHub:https://github.com/shawnu/UUGear
- 详细说明:http://www.uugear.com/uugear-rpi-arduino-solution/
通过USB连接上arduino与树莓派之后,在树莓派一侧只会以以下格式呈现:
/dev/ttyUSB* /dev/ttyACM*
这就带来一个问题,如果USB插拔或有多个USB设备连接在树莓派上的时候,就不知道arduino究竟在哪个接口上。
而这个库也解决了这个问题,在arduino一侧的程序中会生成一个UUGear-Arduino为前缀的设备ID,例如我的arduino:
root@raspberrypi:~/UUGear/RaspberryPi/bin# ./lsuu -------------------------------------------------- UUGear-Arduino-1029-9288 (/dev/ttyACM0) -------------------------------------------------- 1 device(s) found.
然后使用python脚本调用该库的API并带上该设备ID即可通过serial协议与arduino通讯。
更多信息请浏览上面的地址。
0x05 IDE
将程序写入arduino的流程也很简单,先通过vnc登入树莓派并打开终端,然后clone该项目的代码:
#进入桌面目录 pi@raspberrypi:~ $ cd Desktop/ #clone项目 pi@raspberrypi:~/Desktop $ git clone https://github.com/uugear/UUGear.git
然后安装IDE:
pi@raspberrypi:~ $ sudo apt-get install arduino
安装完成后,在开始菜单中打开IDE:
在开始编译烧录等操作之前需要先确认USB端口与设备型号:
然后导入一个程序,清理寄存器中的数据:
再然后点击upload,IDE会编译并上传到arduino中:
完成上面步骤后,在IDE中导入UUGear.ino,该文件在刚才clone的文件夹中:
root@raspberrypi:/home/pi/Desktop# tree ./UUGear/ ./UUGear/ ├── Arduino │ └── UUGear │ └── UUGear.ino
导入完成后同样地点击upload,即可完成编译和烧录。
0x06 应用
至此,arduino的部分已经完成,接下来需要在树莓派上编译相关文件,首先进入相关文件夹:
pi@raspberrypi:~/Desktop $ cd ./UUGear/RaspberryPi/ pi@raspberrypi:~/Desktop/UUGear/RaspberryPi $ ls -l 总用量 12 -rw-r--r-- 1 pi pi 1394 7月 8 19:04 build.sh drwxr-xr-x 4 pi pi 4096 7月 8 19:04 example drwxr-xr-x 2 pi pi 4096 7月 8 19:04 src
然后执行build.sh这个文件:
编译过程中虽然有告警,但并没有错误,可以忽略告警。然后进入bin目录,执行lsuu这个可执行文件,如果一切正常,即可列出所有arduino的设备ID:
pi@raspberrypi:~/Desktop/UUGear/RaspberryPi $ cd ./bin/ pi@raspberrypi:~/Desktop/UUGear/RaspberryPi/bin $ ls -l 总用量 212 -rwxr-xr-x 1 pi pi 8520 7月 8 19:41 AnalogWrite -rwxr-xr-x 1 pi pi 8584 7月 8 19:41 ControlServo -rw-r--r-- 1 pi pi 442 7月 8 19:41 ControlServos.py -rwxr-xr-x 1 pi pi 8724 7月 8 19:41 DigitalReadWrite -rw-r--r-- 1 pi pi 446 7月 8 19:41 DigitalReadWrite.py -rwxr-xr-x 1 pi pi 18104 7月 8 19:41 libUUGear.so -rwxr-xr-x 1 pi pi 13504 7月 8 19:41 lsuu -rwxr-xr-x 1 pi pi 8608 7月 8 19:41 ReadDHT -rw-r--r-- 1 pi pi 660 7月 8 19:41 ReadDHT.py -rwxr-xr-x 1 pi pi 8692 7月 8 19:41 ReadSpeed -rwxr-xr-x 1 pi pi 8552 7月 8 19:41 ReadSR04 -rw-r--r-- 1 pi pi 374 7月 8 19:41 ReadSR04.py -rwxr-xr-x 1 pi pi 23500 7月 8 19:41 SocketBroker -rw-r--r-- 1 pi pi 433 7月 8 19:41 TwoDevices.py -rwxr-xr-x 1 pi pi 23600 7月 8 19:41 UUGearDaemon -rw-r--r-- 1 pi pi 10580 7月 8 19:41 UUGear.o -rw-r--r-- 1 pi pi 5495 7月 8 19:41 UUGear.py -rwxr-xr-x 1 pi pi 8564 7月 8 19:41 VoltageMeasurement -rw-r--r-- 1 pi pi 343 7月 8 19:41 VoltageMeasurement.py pi@raspberrypi:~/Desktop/UUGear/RaspberryPi/bin $ ./lsuu -------------------------------------------------- UUGear-Arduino-4608-5541 (/dev/ttyACM0) -------------------------------------------------- 1 device(s) found.
确认设备工作正常后,再将传感器接入arduino:
然后到以下目录修改python脚本:
#进入目录 root@raspberrypi:/home/pi/Desktop# cd UUGear/RaspberryPi/bin/ #修改文件: root@raspberrypi:/home/pi/Desktop/UUGear/RaspberryPi/bin# vim VoltageMeasurement.py
将device中的设备ID修改为通过lsuu检索到的设备ID,然后确认第10行中的接口编号:
device.analogRead(3)
脚本中预设的是A3接口。
另外,该脚本中的数值换算并不适用于该模块,在这里需要做一些修改,根据电路图,公式如下:
v=读取到的数值 n=实际数值 R1=30000 R2=7500 公式: n=(( n * 5.0 ) / 1024.0 ) / ( R2 / ( R1 + R2 ))
然后修改脚本中的第10行为:
print "%0.2f" % ((float(device.analogRead(3)) * 5.0 / 1024.0 ) / ( 7500.0 / (30000.0 + 7500.0))), "V"
最终整个脚本如下:
root@raspberrypi:~/UUGear/RaspberryPi/bin# cat VoltageMeasurement.py from time import sleep from UUGear import * UUGearDevice.setShowLogs(0) device = UUGearDevice('UUGear-Arduino-1029-9288') if device.isValid(): for i in range(10): print "%0.2f" % ((float(device.analogRead(3)) * 5.0 / 1024.0 ) / ( 7500.0 / (30000.0 + 7500.0))), "V" sleep(0.2) device.detach() device.stopDaemon() else: print 'UUGear device is not correctly initialized.'
然后在检测模块上接上1.5V的AA电池,并启动脚本,输出如下:
root@raspberrypi:~/UUGear/RaspberryPi/bin# python VoltageMeasurement.py 1.68 V 1.68 V 1.68 V 1.68 V 1.66 V 1.66 V 1.68 V 1.68 V 1.66 V 1.68 V
用万能表再次检查该电池的电压后发现,arduino检测的结果比万能表检测的高了0.1v。
接下来接上一块24v的电池组,再运行脚本:
root@raspberrypi:~/UUGear/RaspberryPi/bin# python VoltageMeasurement.py 24.98 V 24.98 V 24.98 V 24.98 V 24.98 V 24.98 V 24.98 V 24.98 V 24.98 V 24.98 V
而万能表检测的数值为26v,比arduino检测到的结果高了1v。
0x07 结语
接下来我需要编写脚本以适配所有传感器,经过测试后再部署到机柜里。
虽然arduino的电压传感器检测到的数值有小许误差,但还在可以接受的范围之内。