用Raspberry Pi和传感器制作“可自动营造舒适空间的装置” (二)

我们这次要创作一款让家中更舒适、让在家办公更高效的设备,本文是第二部分。第一部分介绍了制作纲要和所需部件。这次我们将实际连接Bluetooth传感器和Raspberry Pi。使用罗姆SensorMedal,您甚至可以远程轻松地将传感器值共享给Raspberry Pi!

 

 

本部分所需部件

 

Raspberry Pi 3 B+ 或 Raspberry Pi 4 Model B

 

 

Raspberry Pi 3 B+

 

 

Raspberry Pi 4 Model B:罗姆SensorMedal(SensorMedal-EVK-002)

 

 

手机电池

 

 

USB设备:使用100日元商店就能买到的USB迷你灯和迷你风扇等物件

 

 

1、罗姆SensorMedal与Raspberry Pi的BLE连接

 

在第一部分中,笔者将罗姆SensorMedal连接到我的智能手机上并显示了结果。在本项目中,Raspberry Pi将作为接收数据的航空母舰使用,所以在第二部分中,我们将通过Raspberry Pi的Bluetooth功能连接SensorMedal。

 

首先,安装的Python程序bluepy,以便进行Raspberry Pi的Bluetooth连接。

 

pi@raspberrypi:~ $ sudo pip3 install bluepy

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Collecting bluepy

 Downloading https://www.piwheels.org/simple/bluepy/bluepy-1.3.0-cp37-cp37m-linux_armv7l.whl (560kB)

   100% |████████████████████████████████| 563kB 608kB/s

Installing collected packages: bluepy

Successfully installed bluepy-1.3.0

 

然后,开启SensorMedal和Raspberry Pi的电源,并将它们放在附近。

 

 

通过Bluetooth将SensorMedal连接到Raspberry Pi。有一个可以显示来自SensorMedal的数值的方便程序,我们直接下载这个程序即可(我使用的是这里的Github)。

 

pi@raspberrypi:~ $  sudo mkdir Programs

pi@raspberrypi:~ $  cd Programs

pi@raspberrypi:~ $  sudo git clone http://github.com/bokunimowakaru/SensorMedal2

 

打开已下载的SensorMedal2文件夹,并执行以下示例程序。这个需要在Python 3中使用sudo权限执行。

 

pi@raspberrypi:~ $  cd SensorMedal2

pi@raspberrypi:~ $  sudo python3 ble_logger_SensorMedal2.py

 

怎么样?是不是很简单?如下图所示,从Raspberry Pi能够很轻松地看到SensorMedal传来的测量值。

 

 

SensorMedal中共内置6种传感器。每种传感器的含义如下,使用这些传感器可以测量并获取相应的数值。

 

Temperature: 温度(℃)

 

Humidity: 湿度(%)

 

Pressure: 气压(hPa)

 

Illuminance: 亮度(lx)

 

Accelerometer: 加速度(x轴、y轴、z轴)(g)

 

Geomagnetic: 陀螺仪传感器值(x轴、y轴、z轴)(uT)

 

Magnetic: 霍尔传感器值(磁铁在附近通过为1,否则为0)

 

Steps: 步数(步)

 

Battery Level: 电池电量

 

 

 

2. Raspberry Pi的USB控制

 

我们已经非常轻松地获得了传感器的值,现在,让我们使用这些值来控制与Raspberry Pi连接的硬件吧。

 

先来实现第一部分中提到的“要是能自动搞定就好了(要是有这些功能就好了)”列表中的以下两项。

 

 

亮度会因天气变化和房间情况而发生变化。如果亮度不够还继续工作的话,眼睛会很疲劳,所以我们使用SensorMedal的亮度值——Illiminance(lx)。亮度(光照强度)的单位是“勒克斯”。白天房间的亮度约为200〜300(lx)。

 

测好亮度后,我们用一个USB迷你灯来实现亮度不足时自动开灯的功能。如下图所示,将迷你灯插入Raspberry Pi的USB端口。

 

 

安装一个库来控制USB,让它可以根据亮度开灯和关灯。如下所示,下载并安装库文件。

 

pi@raspberrypi:~ $  wget https://www.gniibe.org/oitoite/ac-power-control-by-USB-hub/hub-ctrl.c

pi@raspberrypi:~ $  sudo apt-get install libusb-dev

pi@raspberrypi:~ $  gcc -o hub-ctrl hub-ctrl.c -lusb

 

现在,就可以通过命令打开和关闭插入USB端口的设备啦。这个“hub-ctrl”的使用方法为“hub-ctrl -b [Bus Num] -d [Device Num] -P [Port Num] -p [On:1 / Off:0] ”。使用“lsusb -t”命令获取设备连接信息。在这里,Bus num: 1, Device num: 2, USB端口的Port num为2。

 

pi@raspberrypi:~ $  hub-ctrl

Hub #0 at 001:002

INFO: individual power switching.

WARN: Port indicators are NOT supported.

Hub #1 at 001:001

INFO: ganged switching.

WARN: Port indicators are NOT supported.

 

pi@raspberrypi:~ $  lsusb -t

/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M

   |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/5p, 480M

       |__ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=smsc95xx, 480M

 

 

如下所示,在“-p”后置“0”将关闭电源,置“1”则打开电源。

 

pi@raspberrypi:~ $  sudo hub-ctrl -b 1 -d 2 -P 2 -p 0

pi@raspberrypi:~ $  sudo hub-ctrl -b 1 -d 2 -P 2 -p 1

 

 

这是指定“-p 1”时的状态。连接到USB端口的灯亮了

 

3.使用传感器值让硬件工作的程序

 

下面,我们将创建程序,把来自SensorMedal的数值与USB控制关联起来。

 

基本上,可以使用前面下载的 SensorMedal2 程序。

 

pi@raspberrypi:~ $  sudo cp ble_logger_SensorMedal2.py ble_illum.py

 

我在原程序基础上,添加了下述第9行和第78〜85行的内容。当亮度低于300lx时,让灯点亮。当亮度高于该值时,让灯熄灭。

 

#!/usr/bin/env python3

# coding: utf-8

 

from __future__ import (division, absolute_import, print_function,

                               unicode_literals)

import fcntl

import socket

import struct

import os

 

def get_addr(ifname):

   try:

       s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

       return socket.inet_ntoa(

           fcntl.ioctl(

               s.fileno(),

               0x8915,  # SIOCGIFADDR

               struct.pack('256s', ifname[:15].encode('utf-8')))[20:24])

   except IOError:

       return 'Not Found!'

 

interval = 10 # 工作间隔

 

from bluepy import btle

from sys import argv

import getpass

from time import sleep

 

def payval(num, bytes=1, sign=False):

   global val

   a = 0

   for i in range(0, bytes):

       a += (256 ** i) * int(val[(num - 2 + i) * 2 : (num - 1 + i) * 2],16)

   if sign:

       if a >= 2 ** (bytes * 8 - 1):

           a -= 2 ** (bytes * 8)

   return a

 

scanner = btle.Scanner()

while True:   

   try:

       devices = scanner.scan(interval)

   except Exception as e:

       print("ERROR",e)

       if getpass.getuser() != 'root':

           print('使用方法: sudo', argv[0])

           exit()

       sleep(interval)

       continue

 

   for dev in devices:

       print("\nDevice %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi))

       isROHMMedal = False

       sensors = dict()

       for (adtype, desc, val) in dev.getScanData():

           print("  %s = %s" % (desc, val))

           if desc == 'Short Local Name' and val[0:10] == 'ROHMMedal2':

               isRohmMedal = True

           if isRohmMedal and desc == 'Manufacturer':

 

               # 将传感器值代入字典变量sensors

               sensors['ID'] = hex(payval(2,2))

               sensors['Illuminance'] = payval(25,2) / 1.2

               sensors['Battery Level'] = payval(30)

               sensors['RSSI'] = dev.rssi

 

               # 在画面中显示

               print('    ID            =',sensors['ID'])

               print('    Illuminance   =',round(sensors['Illuminance'],1),'lx')

               print('    Battery Level =',sensors['Battery Level'],'%')

               print('    RSSI          =',sensors['RSSI'],'dB')

 

               '''

               for key, value in sorted(sensors.items(), key=lambda x:x[0]):

                   print('    ',key,'=',value)

               '''

 

               illum = sensors['Illuminance']

               if illum < 300:

                   illum_msg = "Dark!"

                   os.system(“sudo hub-ctrl -b 1 -d 2 -P 2 -p 1”)

               else:

                   illum_msg = "Bright"

                   os.system(“sudo hub-ctrl -b 1 -d 2 -P 2 -p 0”)

               print(illum_msg)

               sleep(interval)

 

通过sudo python3 ble_illum.py运行该程序。

 

 

我们测试一下,如右侧照片所示,用手遮盖SensorMedal,传感器测得的亮度变暗,USB灯能够获取传感器的值并且很听话地自动开灯!

 

 

4. 总结

 

在这部分中,我们尝试用BLE连接了罗姆SensorMedal和Raspberry Pi。我想大家已经了解到,从远处获取各种传感器数据是非常容易的事。

 

通过6种传感器,不仅可以检测亮度,还可以获取温湿度、气压和加速度等数据。测量办工桌或房间里的各种数据,可能是件很有趣的事。

 

返回顶部
跳到底部

Copyright 2011-2024 南京追名网络科技有限公司 苏ICP备2023031119号-6 乌徒帮 All Rights Reserved Powered by Z-BlogPHP Theme By open开发

请先 登录 再评论,若不是会员请先 注册