Revision [22138]
This is an old revision of SensorPuck made by ToBo on 2015-10-17 18:26:41.
Sensor Puck
"The sensor puck demonstrates Silicon Laboratories optical sensor (Si1147M01 Si1147-M01) RH and temperature sensor
Si7021 and low power MCU (EFM32G210 Gecko). The data is broadcast using a Bluetooth Low Energy (BLE)
module and can be displayed on a mobile device (Apple iOS or Android) that supports the BLE protocol.
By using broadcast mode, a connection does not have to be established, making it possible to display the data
from several modules at the same time."
Text source: http://www.silabs.com/products/sensors/Pages/environmental-biometric-sensor-puck.aspx
Microcontroller EFM32G210
There is an App for iOS and Android, but I wanted to see the Sensor Puck data on my living room screen (Homienaut).
This python script helped me a lot to start receiving and converting the data from sensor puck: http://amperture.com/?p=23
Sensor puck sends the data in as advertising packet. This means in terms of Bluetooth Smart there is no connection required. The Sensor Puck is the broadcaster and the Homienaut is the observer.
I found this broadcast format specification very useful to determinate additional parameters of the sensor (ambient light, UV index, battery voltage and pulse rate).
http://community.silabs.com/mgrfq63796/attachments/mgrfq63796/6/10653/1/Silicon%20Labs%20Sensor%20Puck%20App.pdf
1. Terminal Application
# Code based on the implementation from http://amperture.com/?p=23
# With additions by Andreas Tobola, October 2015, http://tnotes.de/SensorPuck
import subprocess
import os
proc = subprocess.Popen(['hcidump --raw'], stdout=subprocess.PIPE, shell=True)
hrmStateStr = ['Idle', 'No Signal', 'Acquiring', 'Active', 'Invalid', 'Error']
while True:
line = proc.stdout.readline()
if ">" not in line:
hexarray = line.split()
N = len(hexarray)
os.system('clear')
if N==14:
print "== Enviromental Mode ==\n"
# Humidity uint16 deciprecent
humidity = (int(hexarray[6], 16) << 8) + int(hexarray[5], 16)
humidity = float(humidity)/10
# Temperature int16 decidegrees (can be negative -> twos complement)
temp = (int(hexarray[8], 16) << 8) + int(hexarray[7], 16)
temp = float(temp)/10
# Ambient Light uint16 lux/2
amblight = (int(hexarray[10], 16) << 8) + int(hexarray[9], 16)
amblight = float(amblight)/2
# UV Index uint8 index
uvidx = int(hexarray[11], 16)
# Battery Voltage uint8 decivolts
vbat = int(hexarray[12], 16)
vbat = float(vbat)/10
print u"Humidity: %.1f " %humidity + '%'
print u"Temperature: %.1f \xb0C" %temp
print "Ambient light: %.1f Lux" %amblight
print "UV index: %.1f" %uvidx
print "Battery voltage: %.1f V" %vbat
elif N==18:
print "== Biometric Mode ==\n"
# HRM State uint8 none
hrmState = int(hexarray[5], 16)
print "HRM state: " + hrmStateStr[hrmState]
# HRM Rate uint8 bpm
pulseRate = int(hexarray[6], 16)
print "Pulse rate: " + str(pulseRate) + " bpm"
# HRM Sample Array uint16[5] none
# ...
print " "
# With additions by Andreas Tobola, October 2015, http://tnotes.de/SensorPuck
import subprocess
import os
proc = subprocess.Popen(['hcidump --raw'], stdout=subprocess.PIPE, shell=True)
hrmStateStr = ['Idle', 'No Signal', 'Acquiring', 'Active', 'Invalid', 'Error']
while True:
line = proc.stdout.readline()
if ">" not in line:
hexarray = line.split()
N = len(hexarray)
os.system('clear')
if N==14:
print "== Enviromental Mode ==\n"
# Humidity uint16 deciprecent
humidity = (int(hexarray[6], 16) << 8) + int(hexarray[5], 16)
humidity = float(humidity)/10
# Temperature int16 decidegrees (can be negative -> twos complement)
temp = (int(hexarray[8], 16) << 8) + int(hexarray[7], 16)
temp = float(temp)/10
# Ambient Light uint16 lux/2
amblight = (int(hexarray[10], 16) << 8) + int(hexarray[9], 16)
amblight = float(amblight)/2
# UV Index uint8 index
uvidx = int(hexarray[11], 16)
# Battery Voltage uint8 decivolts
vbat = int(hexarray[12], 16)
vbat = float(vbat)/10
print u"Humidity: %.1f " %humidity + '%'
print u"Temperature: %.1f \xb0C" %temp
print "Ambient light: %.1f Lux" %amblight
print "UV index: %.1f" %uvidx
print "Battery voltage: %.1f V" %vbat
elif N==18:
print "== Biometric Mode ==\n"
# HRM State uint8 none
hrmState = int(hexarray[5], 16)
print "HRM state: " + hrmStateStr[hrmState]
# HRM Rate uint8 bpm
pulseRate = int(hexarray[6], 16)
print "Pulse rate: " + str(pulseRate) + " bpm"
# HRM Sample Array uint16[5] none
# ...
print " "
The Sensor Puck has two modes Enviromental and Biometric Mode.
If the finger is on the optical sensor, the sensor switches into Biometric Mode.
Depending on the mode the sensor broadcasts different data.
== Enviromental Mode == Humidity: 51.4 % Temperature: 20.5 C Ambient light: 1.5 Lux UV index: 0.0 Battery voltage: 3.0 V
== Biometric Mode == HRM state: Active Pulse rate: 72 bpm
2. GUI Application
#!/usr/bin/python
# Thos is a GUI version of the Sensor Puck Script at http://tnotes.de/SensorPuck
# Andreas Tobola, October 2015
from Tkinter import *
import time
import thread
import subprocess
import os
bgcolor = 'black';
fgcolor = 'light blue'
fgcolorerr = 'Orange Red'
def threadSensorDecoder():
global tTimeOutObserver
while 1:
line = proc.stdout.readline()
if ">" not in line:
hexarray = line.split()
N = len(hexarray)
tTimeOutObserver = time.time() + 5
if N==14:
# Humidity uint16 deciprecent
humidity = (int(hexarray[6], 16) << 8) + int(hexarray[5], 16)
humidity = float(humidity)/10
# Temperature int16 decidegrees (can be negative -> twos complement)
temp = (int(hexarray[8], 16) << 8) + int(hexarray[7], 16)
temp = float(temp)/10
# Ambient Light uint16 lux/2
amblight = (int(hexarray[10], 16) << 8) + int(hexarray[9], 16)
amblight = float(amblight)/2
# UV Index uint8 index
uvidx = int(hexarray[11], 16)
# Battery Voltage uint8 decivolts
vbat = int(hexarray[12], 16)
vbat = float(vbat)/10
#laSensData['text'] = u'Temperature: %.1f \xb0C \n Humidity: %.1f \x25 \n Ambient light: %.1f Lux \n UV index: %d \n Battery voltage: %.1f V' %(temp, humidity, amblight, uvidx, vbat)
laSensData['text'] = u'Temperature: %.1f \xb0C \n Humidity: %.1f ' %(temp, humidity) + '%' + ' \n Ambient light: %.1f Lux \n UV index: %d \n Battery voltage: %.1f V' %(amblight, uvidx, vbat)
txtExtra = '';
if humidity > 55.0:
txtExtra += 'Ventilate the room!\n'
if temp > 25.0:
txtExtra += 'It''s incredible hot in here!\n'
elif temp > 22.5:
txtExtra += 'It''s hot in here.\n'
elif temp < 18.0:
txtExtra += 'It''s cold in here!\n'
if vbat < 2.7:
txtExtra += 'Low sensor battery.\n'
laExtra['text'] = txtExtra;
elif N==18:
# HRM State uint8 none
hrmState = int(hexarray[5], 16)
# HRM Rate uint8 bpm
pulseRate = int(hexarray[6], 16)
# HRM Sample Array uint16[5] none
# maybe one day...
laSensData['text'] = u'Pulse Sensor Mode \n Sensor sate: %s \n Pulse rate: %d bpm' %(hrmStateStr[hrmState], pulseRate)
txtExtra = '';
if hrmState == 3:
if pulseRate > 120:
txtExtra += 'Your pulse rate is high.\n'
if pulseRate < 50:
txtExtra += 'Your pulse rate is low.\n'
laExtra['text'] = txtExtra;
def threadSensorObserver():
while 1:
time.sleep(2)
if time.time() > tTimeOutObserver:
laSensData['text'] = '';
laExtra['text'] = 'Sensor out of range.';
tTimeOutObserver = time.time() + 5
master = Tk()
master.configure(background=bgcolor)
fontSensData = ("Helvetica",30,"bold");
w = Label(master, text="Sensor Puck", font = ("Helvetica",50,"bold"), bg=bgcolor, fg=fgcolor )
w.pack()
laSensData = Label(master, text="...", font = fontSensData, bg=bgcolor, fg=fgcolor )
laSensData.pack()
laExtra = Label(master, text="", font = fontSensData, bg=bgcolor, fg=fgcolorerr )
laExtra.pack()
proc = subprocess.Popen(['sudo hcidump --raw'], stdout=subprocess.PIPE, shell=True)
hrmStateStr = ['Idle', 'No Signal', 'Acquiring', 'Active', 'Invalid', 'Error']
try:
thread.start_new_thread( threadSensorObserver, () )
thread.start_new_thread( threadSensorDecoder, () )
except:
print "Error: unable to start thread"
mainloop()
# Thos is a GUI version of the Sensor Puck Script at http://tnotes.de/SensorPuck
# Andreas Tobola, October 2015
from Tkinter import *
import time
import thread
import subprocess
import os
bgcolor = 'black';
fgcolor = 'light blue'
fgcolorerr = 'Orange Red'
def threadSensorDecoder():
global tTimeOutObserver
while 1:
line = proc.stdout.readline()
if ">" not in line:
hexarray = line.split()
N = len(hexarray)
tTimeOutObserver = time.time() + 5
if N==14:
# Humidity uint16 deciprecent
humidity = (int(hexarray[6], 16) << 8) + int(hexarray[5], 16)
humidity = float(humidity)/10
# Temperature int16 decidegrees (can be negative -> twos complement)
temp = (int(hexarray[8], 16) << 8) + int(hexarray[7], 16)
temp = float(temp)/10
# Ambient Light uint16 lux/2
amblight = (int(hexarray[10], 16) << 8) + int(hexarray[9], 16)
amblight = float(amblight)/2
# UV Index uint8 index
uvidx = int(hexarray[11], 16)
# Battery Voltage uint8 decivolts
vbat = int(hexarray[12], 16)
vbat = float(vbat)/10
#laSensData['text'] = u'Temperature: %.1f \xb0C \n Humidity: %.1f \x25 \n Ambient light: %.1f Lux \n UV index: %d \n Battery voltage: %.1f V' %(temp, humidity, amblight, uvidx, vbat)
laSensData['text'] = u'Temperature: %.1f \xb0C \n Humidity: %.1f ' %(temp, humidity) + '%' + ' \n Ambient light: %.1f Lux \n UV index: %d \n Battery voltage: %.1f V' %(amblight, uvidx, vbat)
txtExtra = '';
if humidity > 55.0:
txtExtra += 'Ventilate the room!\n'
if temp > 25.0:
txtExtra += 'It''s incredible hot in here!\n'
elif temp > 22.5:
txtExtra += 'It''s hot in here.\n'
elif temp < 18.0:
txtExtra += 'It''s cold in here!\n'
if vbat < 2.7:
txtExtra += 'Low sensor battery.\n'
laExtra['text'] = txtExtra;
elif N==18:
# HRM State uint8 none
hrmState = int(hexarray[5], 16)
# HRM Rate uint8 bpm
pulseRate = int(hexarray[6], 16)
# HRM Sample Array uint16[5] none
# maybe one day...
laSensData['text'] = u'Pulse Sensor Mode \n Sensor sate: %s \n Pulse rate: %d bpm' %(hrmStateStr[hrmState], pulseRate)
txtExtra = '';
if hrmState == 3:
if pulseRate > 120:
txtExtra += 'Your pulse rate is high.\n'
if pulseRate < 50:
txtExtra += 'Your pulse rate is low.\n'
laExtra['text'] = txtExtra;
def threadSensorObserver():
while 1:
time.sleep(2)
if time.time() > tTimeOutObserver:
laSensData['text'] = '';
laExtra['text'] = 'Sensor out of range.';
tTimeOutObserver = time.time() + 5
master = Tk()
master.configure(background=bgcolor)
fontSensData = ("Helvetica",30,"bold");
w = Label(master, text="Sensor Puck", font = ("Helvetica",50,"bold"), bg=bgcolor, fg=fgcolor )
w.pack()
laSensData = Label(master, text="...", font = fontSensData, bg=bgcolor, fg=fgcolor )
laSensData.pack()
laExtra = Label(master, text="", font = fontSensData, bg=bgcolor, fg=fgcolorerr )
laExtra.pack()
proc = subprocess.Popen(['sudo hcidump --raw'], stdout=subprocess.PIPE, shell=True)
hrmStateStr = ['Idle', 'No Signal', 'Acquiring', 'Active', 'Invalid', 'Error']
try:
thread.start_new_thread( threadSensorObserver, () )
thread.start_new_thread( threadSensorDecoder, () )
except:
print "Error: unable to start thread"
mainloop()
Siehe auch • • • • • • • •