- Silicon Labs Community
- Welcome and Announcements
- Silicon Labs Knowledge Base
- 8-bit MCU
- 32-bit MCU
- Bluetooth / Wi-Fi
- Other Products Category
- Optical/RH/Temp Sensor
- Other Products
- Hardware and Software Tools
- Simplicity Studio and Software
- General Discussions and Suggestions
- Chinese Forum
- Software Libraries
- Development Kits
- Reference Designs
- Third Party Tools
- White Papers
- Official Blog of Silicon Labs
- Chinese Blog
11-29-2016 01:01 PM
Few days ago I received the new Thunderboard Sense kit and I decide to make sound alarm which will notify me on telegram.
Firstly I create bot and get token. How to do this you can read here https://core.telegram.org/bots
Then I install on my raspberypi bluepy and telepot modules for python
sudo pip install telepot
sudo pip install bluepy
Ok! Now we are ready for experiments.
Firstly we need to know which characteristics are responsible for onboard LED and microphone sensor.
Let`s create simple python script and discover all present characteristics on Thunderboard Sense kit.
from bluepy.btle import * import struct def ble_micro_handle(): scanner = Scanner(0) devices = scanner.scan(3) for dev in devices: print "Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi) for (adtype, desc, value) in dev.getScanData(): print " %s = %s" % (desc, value) num_ble = len(devices) print num_ble if num_ble==0: return None ble_mic =  char_sensor = 0 non_sensor = 0 led_char = Characteristic mic_char = Characteristic led_handle =0 for i in range(num_ble): try: devices[i].getScanData() ble_mic.append(Peripheral()) ble_mic[char_sensor].connect(devices[i].addr,devices[i].addrType) char_sensor = char_sensor + 1 print "Connected %s device with addr %s " % (char_sensor, devices[i].addr) except: non_sensor = non_sensor + 1 try: for i in range(char_sensor): services = ble_mic[i].getServices() characteristics = ble_mic[i].getCharacteristics() for k in characteristics: print k if k.uuid=="fcb89c40-c603-59f3-7dc3-5ece444a401b": print "LED CONTROL FOUND" led_char = k led_handle = k.getHandle() if k.uuid == "c8546913-bf02-45eb-8dde-9f8754f4a32e": print "MIC SENSOR FOUND" mic_char = k except: return None
This is our result
Characteristic <Device Name> Characteristic <Appearance> Characteristic <Service Changed> Characteristic <Manufacturer Name String> Characteristic <Model Number String> Characteristic <Serial Number String> Characteristic <Hardware Revision String> Characteristic <Firmware Revision String> Characteristic <System ID> Characteristic <Battery Level> Characteristic <UV Index> Characteristic <Pressure> Characteristic <Temperature> Characteristic <Humidity> Characteristic <c8546913-bfd9-45eb-8dde-9f8754f4a32e> Characteristic <c8546913-bf02-45eb-8dde-9f8754f4a32e> MIC SENSOR FOUND Characteristic <c8546913-bf03-45eb-8dde-9f8754f4a32e> Characteristic <ec61a454-ed01-a5e8-b8f9-de9ec026ec51> Characteristic <efd658ae-c401-ef33-76e7-91b00019103b> Characteristic <efd658ae-c402-ef33-76e7-91b00019103b> Characteristic <efd658ae-c403-ef33-76e7-91b00019103b> Characteristic <fcb89c40-c601-59f3-7dc3-5ece444a401b> Characteristic <fcb89c40-c602-59f3-7dc3-5ece444a401b> Characteristic <fcb89c40-c603-59f3-7dc3-5ece444a401b> LED CONTROL FOUND Characteristic <fcb89c40-c604-59f3-7dc3-5ece444a401b> Characteristic <2a56> Characteristic <2a56> Characteristic <c4c1f6e2-4be5-11e5-885d-feff819cdc9f> Characteristic <b7c4b694-bee3-45dd-ba9f-f3b5e994f49a> Characteristic <71e30b8c-4131-4703-b0a0-b0bbba75856b>
Microphone Characteristic <c8546913-bf02-45eb-8dde-9f8754f4a32e> we can only READ, there is no notification or indication.We will periodically poll this characteristic in this project to get current value from microphone.
LED Control Characteristic <fcb89c40-c603-59f3-7dc3-5ece444a401b> we can READ, WRITE and INDICATE. In this project we will use only WRITE possibility. To control LEDs we must write 4 bytes into this characteristic: 0xff,0x00,0x00,0x00.
First byte 0xff are used to ON all 4 led. Other 3 bytes are RED,GREEN,BLUE colors. Any value from 0x00 to 0xff can be written for specified color. Combination of them create many pretty colors.
So if we write 0xff,0x00,0x00,0ff then we get the bright BLUE color for all four onboard LEDs.
As I mentioned above we will poll the microphone and constrain it value to the range from 0x00 to 0xff, and then write bytes array to the LED CONTROL Characteristic. But It would be bored and simple,so I add some smooth transition for our LED between values.
And finally ALARM. When obtained value from microphone will be higher than established treshold, our bot must send a message to Telegram account.
Here is a code:
from bluepy.btle import * import struct import thread import telepot from datetime import datetime print datetime.now().time() bot = telepot.Bot('HERE MUST BE YOUR TOKEN') bot_data = bot.getMe() print bot_data response = bot.getUpdates() print response bot.sendMessage(HERE_ID_WHERE_YOU_WANT_TO_SEND_MESSAGE,"HELLO MAX") def map(x, in_min, in_max, out_min, out_max): return int((x-in_min) * (out_max-out_min) / (in_max-in_min) + out_min) def SENSE_handle(): scanner = Scanner(0) devices = scanner.scan(3) for dev in devices: print "Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi) for (adtype, desc, value) in dev.getScanData(): print " %s = %s" % (desc, value) num_ble = len(devices) print num_ble if num_ble==0: return None ble_mic =  char_sensor = 0 non_sensor = 0 led_char = Characteristic mic_char = Characteristic led_handle =0 for i in range(num_ble): try: devices[i].getScanData() ble_mic.append(Peripheral()) ble_mic[char_sensor].connect(devices[i].addr,devices[i].addrType) char_sensor = char_sensor + 1 print "Connected %s device with addr %s " % (char_sensor, devices[i].addr) except: non_sensor = non_sensor + 1 try: for i in range(char_sensor): services = ble_mic[i].getServices() characteristics = ble_mic[i].getCharacteristics() for k in characteristics: print k if k.uuid=="fcb89c40-c603-59f3-7dc3-5ece444a401b": print "LED CONTROL FOUND" led_char = k led_handle = k.getHandle() if k.uuid == "c8546913-bf02-45eb-8dde-9f8754f4a32e": print "MIC SENSOR FOUND" mic_char = k except: return None led_bytes =[0xFF,0x00,0x00,0x00] last_value = 0x00 while True: mic_data = mic_char.read() mic_data_value =(ord(mic_data)<<8)+ord(mic_data) led =map(mic_data_value, 4100, 9999, 0, 0xff) print "LED :",led print "LAST VAL:",last_value if led >150: bot.sendMessage(HERE_ID_WHERE_YOU_WANT_TO_SEND_MESSAGE,"SOUND ALERT"+str(datetime.now().time())) if last_value < led: while last_value<=led: print "LAST VALUE LOWER" led_bytes=last_value # led_bytes=led led_bytes=last_value s ="" for i in led_bytes: s+=chr(i) ble_mic.writeCharacteristic(led_handle,s,True) last_value=last_value+10 if last_value > led: print "LAST VALUE HIGHER" while last_value>led: led_bytes=last_value # led_bytes=led led_bytes=last_value s ="" for i in led_bytes: s+=chr(i) ble_mic.writeCharacteristic(led_handle,s,True) last_value=last_value-10 last_value = led while True: SENSE_handle()
And now video how it works
12-16-2016 12:31 AM
Very nicely explained and interesting tutorial.
Is this using RPi 3 - Model B? On Board Bluetooth to receive the data or any external USB Bluetooth Dongle to capture data?
12-16-2016 12:37 AM
In this particular case I used RPI 3 with wifi and BLE onboard. But you can use any BLE dongle on different Raspberrys or PC with linux.
12-16-2016 12:40 AM
Thank you @Namo_Aton
Just started exploring the Sense Kit ! Coming up with some tutorial. Your this tutorial is going to be useful for sure. :-)
12-20-2016 08:29 AM
It's a great idea to use a Raspberry Pi running Python as the bluetooth client and cloud gateway. This approach opens up a ton of applications to easily get your sensor data out on the web.
Just out of curiosity, how did you figure out what each characteristic did? I'm guessing you already found it, but for others I'm attaching the XML file describing all characteristics supported by the Thunderboard Sense Bluetooth app. This is basically the API available to a Bluetooth client such as your Python script.
This XML file is used to generate C header and source files which in turn are used to configure the bluetooth stack with available characteristics.
The XML file contains all the characteristic IDs with ID, name and typically a description of the format of the data returned. You can also see which characteristics are readable, writable and support notifications.
I also recommend the following documentation on the board:
These documents and more can also be found on the Thunderboard Sense website.
12-20-2016 09:19 AM
I figured out with characteristics with android app, which can connect to any ble device. I XML file is helpful for me now. I am trying to figure out how to add one more characteristic and add one handler with interrupt and then there will be one project with android app.Of course I can make it with BGM111, and I think I will make it on this weekend. But interesting how I can make the same with Sense kit.
05-24-2017 10:56 AM
@Namo_Aton great introduction here and thanks for the time spent laying it all out. I've had some issues trying to follow through your steps (and more than likely I'm missing something out as I'm a first time RPi chap).
I get the following error -
Traceback (most recent call last): File "/home/pi/bluepy/bluepy/Sense_Mic.py", line 1, in <module> from bluepy.btle import * ImportError: No module named 'bluepy'
Do you what I've done incorrectly here? Seems it doesn't want to work at all.
I've even been through the code to adjust the print function requirement to have the code as below (with the parenthesis) -
FYI I have a RPI3 and Thunderboard Sense. Ideally would like to get some data off there and upload to the cloud. But step one is just to connect to the board with some of your example code. What version of Python do you suggest I run this in?
Any advice would be greatly appreciated.
05-24-2017 12:13 PM
I'm not sure whether it is a version problem on Python... which one should I be using Python 2 or Python 3?
As I'm new to the RPI3... I assume I'm running this code through Python in the GUI and not in Terminal?
Thought this might be an easy process, but seems to be stumping me... Thanks.
05-24-2017 12:19 PM
@neal_tommy this sample work on python2.
and this code must be runnig from terminal and with superuser rights.
sudo python test.py
05-24-2017 01:23 PM
pi@raspberrypi:~ $ sudo python test.py python: can't open file 'test.py': [Errno 2] No such file or directory
So am I doing something wrong here that I can't even get the most basic code to run? Thought I might need to be in the folder... but which one? It doesn't seem to be in the Bluepy directory.
Sorry for the lame questions here.
05-24-2017 02:10 PM
@neal_tommy test.py this must be filename that you created.
next you must be in directory where your file is located. if no result write me in private message