大家好,我是吉田!
我們這次要創作一款讓家中更舒適、讓在家辦公更高效的設備,本文是第三部分。
在第二部分中,我們用BLE連接了羅姆SensorMedal並測量了各種資料。在第三部分,我希望通過安裝人體感測器等器件,實現檢查主人是否久坐不動或過度工作的功能!
第二部分中,我們通過羅姆SensorMedal測量了亮度,並根據亮度值成功控制了USB燈。在第二部分的基礎上,還可以檢測溫度和濕度,當檢測到室溫過高時,可以通過同樣的方法讓風扇轉起來。
但是,僅僅這樣的功能可能還不夠,我還希望它只在裝有這款Raspberry Pi設備的工作臺周圍有人時才工作!う。
另外,正如我在第一部分中提到的,我還希望它能起到防止主人在家辦公期間因久坐不動而過於疲勞的作用。
編號 | 檢測功能 | 檢測後希望具備的功能 |
5 | 檢測坐在椅子上的時間 | 檢測到坐的時間太久(久坐不動),督促主人站起來活動活動 |
所以,這次我們來實現上述功能,這也是第一部分中列舉的“要是有這樣的功能就好了”的項目之一。具體來講,需要添加一個能夠讓Raspberry Pi知道是否有人的感測器,以便確認工作臺周圍的活動狀態。為此,我們將在Raspberry Pi上安裝下面這種熱釋電紅外線感測器。
感測器側(從照片左邊開始) | Raspberry Pi側 |
+(黃色) | 5V |
OUT(紅色) | GPIO13 |
ー(黑色) | GND |
與Raspberry Pi的連接如表中所示。實際安裝的照片如下所示:
在這裡,需要創建一個簡單的程式human.py,來確認人體感測器是否正常發揮作用,在運行該程式時,如果周圍有人,將顯示為“1”,否則顯示為“0”。
[human.py]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import RPi.GPIO as GPIO from time import sleep human_pin = 13 GPIO.setmode(GPIO.BCM) GPIO.setup(human_pin, GPIO.IN) try: while True: human = GPIO.input(human_pin) print(human) sleep(1) except KeyboardInterrupt: pass GPIO.cleanup() |
運行human.py。僅當您坐在Raspberry Pi前面或將手靠近它時才會顯示“1”。
現在,我們來給Raspberry Pi加一個液晶顯示器,使之能夠顯示前面添加的SensorMedal和人體感測器的值。
市場上有很多種液晶顯示器,我選用的是只需將其插入Raspberry Pi的GPIO引腳即可使用的DISPLAYOTRON HAT,它也有一個可以連接人體感測器的GPIO引腳。
如照片所示,將顯示器插入Raspberry Pi的 GPIO引腳。
這個顯示器的資料庫來自 Adafruit,所以可以參考其Github頁面:
https://github.com/pimoroni/displayotron
運行頁面中的安裝腳本。這樣將會在Home下創建一個名為“pimoroni”的目錄,並在其中的下述位置保存示例程式。
Dot3000和DotHat都有類似的功能,但是這次我使用的是DotHat,所以我們會使用DotHat對應的資料庫。這裡有一些示例程式,您可以嘗試運行一下。
1 2 3 4 |
$ curl -sS get.pimoroni.com/displayotron | bash $ cd /home/pi/Pimoroni/displayotron/dothat $ python3 basic/hello_world.py $ python3 basic/backlight.py |
下面,讓我們修改一下連接SensorMedal和Raspberry Pi的程式,以實現在這個液晶顯示器上顯示測量值。下麵的第4行、第22〜27行、第45〜50行和第91〜115行是對第二部分中ble程式的補充。
[ble_lcd.py]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
#!/usr/bin/env python3 # coding: utf-8 import dothat.lcd as lcd from datetime import datetime 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 import RPi.GPIO as GPIO human_pin = 13 GPIO.setmode(GPIO.BCM) GPIO.setup(human_pin, GPIO.IN) human_count = 0 human_check = 3 interval = 10 # 工作間隔 scanner = btle.Scanner() while True: now = datetime.now() d = '{0:0>4d}/{1:0>2d}/{2:0>2d}({3})'.format(now.year, now.month, now.day, now.strftime('%a')) t = '{0:0>2d}:{1:0>2d}:{2:0>2d}'.format(now.hour, now.minute, now.second) lcd.clear() lcd.set_cursor_position(0, 0) lcd.write('PiRemote') lcd.set_cursor_position(0, 1) lcd.write('{}'.format(d)) lcd.set_cursor_position(2, 2) lcd.write('{}'.format(t)) human = GPIO.input(human_pin) print(human) if human == 1: human_count+=1 else: human_count=0 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['ID'] = hex(payval(2,2)) sensors['Temperature'] = -45 + 175 * payval(4,2) / 65536 sensors['Humidity'] = 100 * payval(6,2) / 65536 sensors['Illuminance'] = payval(25,2) / 1.2 sensors['Battery Level'] = payval(30) sensors['RSSI'] = dev.rssi print(' ID =',sensors['ID']) print(' Temperature =',round(sensors['Temperature'],2),'℃') print(' Humidity =',round(sensors['Humidity'],2),'%') 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) ''' temp = sensors['Temperature'] humid = sensors['Humidity'] if temp > 26 or humid > 60: temp_msg = "Hot!" else: temp_msg = "Not bad" illum = sensors['Illuminance'] if illum < 200: illum_msg = "Dark!" else: illum_msg = "Bright" if human_count > human_check: human_msg = "Take Rest" else: human_msg = "Work Hard!" lcd.clear() lcd.set_cursor_position(0, 0) lcd.write('Temp: {0:1.0f}C {1:1.0f}% {2}'.format(temp, humid, temp_msg)) lcd.set_cursor_position(0, 1) lcd.write('Illum: {0:1.0f}Lx {1}'.format(illum,illum_msg)) lcd.set_cursor_position(0, 2) lcd.write('{0:1.0f} Cnt {1}'.format(human_count, human_msg)) sleep(interval) |
如果您像“sudo python3 ble_lcd.py”一樣運行這個程式,那麼將會首先獲取並顯示當前的日期和時間等資訊。
一段時間後,即可通過BLE獲得SensorMedal的測量值。然後將會顯示溫度、濕度和亮度等資訊。通過人體感測器,您還可以查看人在那裡呆了多少秒。
如果室溫高於26℃、濕度高於 60%,它會發出警告。另外,在亮度為200Lx以下時,顯示消息也會發生變化。
而當人體感測器檢測到人在那裡的停留時間超過一定時間時(為便於測試,這裡設置為30秒左右),顯示資訊就會變為“該休息了!”
您可以根據房間情況和工作情況嘗試更改每種感測器的閾值。根據番茄工作法,採用工作25分鐘休息5分鐘的時間安排,工作效率會比較好,您也可以根據這類方法來設置數值。
這次我們在SensorMedal基礎上又添加了一個人體感測器,這樣就可以檢測桌子周圍是否有人了。在我們在家辦公過程中,很容易坐的時間過長,擁有一個能夠在這種情況下關心我們、提醒我們的設備,真是一個不錯的選擇。
另外,我們還添加了一個液晶顯示器,用來顯示來自感測器的值。如果是HAT型顯示器,您可以使用現有的資料庫檔輕鬆實現資料顯示。當然,您也可以自己連接液晶顯示器並自己嘗試使用。
在第四部分,我們將會嘗試實現能夠從互聯網獲取資訊、並通過各種數值提醒主人行動的機制,並最終完成整個舒適環境營造設備。
敬請期待!