The Project board is for sharing projects based on Silicon Labs' component with other community members. View Projects Guidelines ›

Projects

    Publish
     
      • Thunderboard Sense Battery Life

        Nick_W | 10/290/2017 | 03:43 AM
        I’ve been playing with this great new board for a few days now. One issue I have run into is that the battery life is very poor. I’m only getting a couple of days out of a coin cell.

        I’ve dug into the code, and a couple of things become clear. First, when running rom battery, when you connect to the board, all the sensors switch on, and stay on, until you disconnect.

        Second, when you read the sensor values, you aren’t reading the sensors directly, you are reading a cached copy of the values, which are updated every 3 seconds, continuously while you are connected - irrespective of how often you actually read the values out.

        Thirdly, on USB power, sensors are powered on all the time (OK, not a big deal).

        The conclusion is that if you connect, stay connected, and read the sensors once per minute, the sensors are live all the time, and the battery dies quickly. In fact, I’m not sure the device sleeps at all when connected.

        If you connect, read, then disconnect, you have the problem that the device times out after 30 seconds (ie goes into deep sleep, and can only be woken with a button push).

        I have changed this timeout to 1 hour, reduced the advertising cycle to 500ms (from 100ms) and reduced the led flashes (during advertising) to 20ms every 10 seconds, but the battery life is still poor when connecting, reading, disconnecting once every minute. I’m just reading the environmental sensors.

        It seems that although the sensors are off when not connected, the device does not sleep at all when advertising. (Although debug output does say BLE sleep mode enabled).

        Does anyone have any suggestions on how to reduce battery drain? Make the device sleep between advertisements? Or any other way to extend the battery life beyond a few days?

        Thanks.

      • Project Completed and Working a Treat (TB Sense and Pi)

        neal_tommy | 08/232/2017 | 04:20 PM

        All, 

         

        Whilst I've received much assistance from this community I thought it time I give back and feedback on my working project (thanks all who helped along the way). 

         

        Essentially I have a TB Sense connected up via BLE to a RPi3. I did some changing to the code on the TB Sense to make it continuously advertise and then have a Python script on the Pi to collect data once every 10 minutes. 

         

        This data is fed to Thingspeak (considering alternative options here) and graphed for viewing. I'm still in the phase of looking at some daily / weekly averages and seeing what changes it would make to general lifestyle. I'm collecting data from 6 enviromental sensors (sound, temp., humidity, pressure, TVOC and eCO2). 

         

        Board holder

        Board holder

         

        Overall 3D printed enclosure (enough to let some air in for measurement)

        Enclosure

         

        I've also got a cool 3D printed enclosure made which houses the TB Sense in a nice looking (and acceptable by the wife) designed box whilst on the table top. The Pi is sitting next to my router collecting the data. 

         

        So far I've collected a couple of days of data as shown below. It all seems to be working and is ready for a powercut and suitable reboot / reconnect if that happens (common here in South Africa). 

         

        Capture.JPG

         

        Happy to answer any questions on this, and share details. It is by no means a complex project however did keep me busy for a few weekends. There are still some areas I'd like to improve and then work from there (probably on the efficiency of the Python code). 

         

        Ciao. 

         

        from __future__ import division
        import sys
        from bluepy.btle import *
        import struct
        import thread
        from time import sleep
        import urllib2
        
        PRIVATE_KEY = 'H4HMW1TRAGNYUPBJ'
        
        # Base URL of Thingspeak
        baseURL = 'https://api.thingspeak.com/update?api_key='
        
        
        def vReadSENSE():
            scanner = Scanner(0)
            devices = scanner.scan(2)
            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_service = []
            char_sensor = 0
            non_sensor = 0
            TVOC_char = Characteristic
            eCO2_char = Characteristic
            Pressure_char = Characteristic
            Sound_char = Characteristic
            temperature_char = Characteristic
            humidity_char = Characteristic
        
            #bat_char = Characteristic
            
            count = 15
        
            for i in range(num_ble):
                try:
                    devices[i].getScanData()
                    ble_service.append(Peripheral())
                    ble_service[char_sensor].connect('00:0b:57:36:63:ff',devices[i].addrType)
                    #ble_service[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_service[i].getServices()
                    characteristics = ble_service[i].getCharacteristics()
                    for k in characteristics:
                        print k
                        if k.uuid == "efd658ae-c401-ef33-76e7-91b00019103b":
                            print "eCO2 Level"
                            TVOC_char = k
                        if k.uuid == "efd658ae-c402-ef33-76e7-91b00019103b":
                            print "TVOC Level"
                            TVOC_char = k
                        if k.uuid == "00002a6d-0000-1000-8000-00805f9b34fb":
                            print "Pressure Level"
                            Pressure_char = k
                        if k.uuid == "c8546913-bf02-45eb-8dde-9f8754f4a32e":
                            print "Sound Level"
                            Sound_char = k
                        if k.uuid == "00002a6e-0000-1000-8000-00805f9b34fb":
                            print "Temperature"
                            temperature_char = k
                        if k.uuid == "00002a6f-0000-1000-8000-00805f9b34fb":
                            print "Humidity"
                            humidity_char = k
        
                        #if k.uuid == "2a19":
                            #print "Battery Level"
                            #bat_char = k
        
            except:
                return None
            while True:
                # units of ppb
                TVOC_data = TVOC_char.read()
                TVOC_data_value = ord(TVOC_data/100)
        
                #units of ppm
                eCO2_data = eCO2_char.read()
                eCO2_data_value = ord(eCO2_data[0])
        
                # pressure is in units of 0.1Pa
                Pressure_data = Pressure_char.read()
                Pressure_data_value = (Pressure_data * 10)
        
                # units of 0.01dB
                Sound_data = Sound_char.read()
                Sound_data_value = (Sound_data * 100)
        
                #bat_data = bat_char.read()
                #bat_data_value = ord(bat_data[0])
        
                #convert from farenheit
                temperature_data = temperature_char.read()
                temperature_data_value = (ord(temperature_data[1]) << 8) + ord(temperature_data[0])
                float_temperature_data_value = (temperature_data_value / 100)
        
                humidity_data = humidity_char.read()
        	humidity_data_value =(ord(humidity_data[1])<<8)+ord(humidity_data[0])
        
        	print "TVOC: ", TVOC_data_value
        	print “eCO2: ", eCO2_data_value
        	print “Pressure: ", Pressure_data_value
        	print “Sound: ", Sound_data_value
        	print “Temperature: “, float_temperature_data_value
        	print “Humidity: “, humidity_data_value
        
        	if count > 14:
        
                	f = urllib.urlopen(baseURL + PRIVATE_KEY + "&field1=%s&field2=%s&field3=%s&field4=%s&field5=%s&field6=%s" % (TVOC_data_value, eCO2_data_value, Pressure_data_value, Sound_data_value, float_temperature_data_value, humidity_data_value))
                	print f.read()
                	f.close()
                	count = 0
                	count = count + 1
                	sleep(1)
        
        while True:
            vReadSENSE()

      • Setting BLE characteristic values – a Thunderboard Sense practical approach

        m_dobrea | 07/191/2017 | 06:45 AM

             Few months ago, I received a Thunderboard Sense kit from Silicon Labs Company. Analyzing the market for applications capable of working with this device, I noticed the existence of many applications capable of running on operating systems such as iOS, Android or Linux. But, I have not found a professional application, developed in Windows, able to work with this device. As a result, I decide to develop one - BLE SensorTags application.

             Right now, the BLE (Bluetooth Low Energy) SensorTag application – BlessTags (BLE SensorTags) can work with 2 different sensor tags from Silicon Labs Company: Thunderboard React and Thunderboard Sense.

             The BlessTags (BLE SensorTags) application has the following functionalities:

        1. To set, communicate, use and display (in graphic and numerical form) the information from all the sensors included on the SensorTags presented above. The supported sensor’s characteristics are:
          • For ThunderBoard React: accelerometer, orientation, temperature, humidity, light (ambient & UV), keys and output LEDs. 
          • For ThunderBoard Sense: accelerometer, orientation, barometer, temperature, humidity, air quality (CO2 & TVOC), light (ambient & UV), sound level, keys and output LEDs (2 x low power LEDs & 4 x power LEDs).
        2. In the developer mode the software provides the user with lots of messages obtained from the communication process with a specific SensorTag - these messages enable the user to identify the communication/configuration setbacks and some other problems.
        3. The software also gives the possibility to interrogate different types of unknown BLE devices - to be able to obtain the complete GATT attribute table for the unknown BLE device. At this link is presented the entire procedure used by me to obtain the complete GATT table for Thunderboard Sense and in the end a pdf file containing all the obtained results.
        4. To obtain and tune the optimal Kalman filter parameters;
        5. ... and the most exciting features: the gadgets. The gadgets are several practical applications that use one or more sensors from the SensorTag to achieve a concrete, fully functional and useful application. For instance, using the two buttons placed on Thunderboard React or Thunderboard Sense, these SensorTags are turning into wireless presenters for PowerPoint.

             For the development of the application I used: (a) intensively the documentation provided by Microsoft and (b) the source code (BluetoothLowEnergy.cpp) developed by Donald Ness and publicly offered at this address: https://gist.github.com/programmarchy/c9d02e22d58bfab3f8bb.

             The following code sequence, developed entirely by me, will complete the program provided by Mr. Donald Ness. With this code addition, we will not only be able to read data from the descriptors of a characteristic, but we will be able also to write characteristic values - in this way we can influence the state of the SensorTag.

             To exemplify the concepts of writing to a characteristic of a sensor, I will customize the code to be presented for the Profile User Interface service; service with the UUID: FCB89C40-C600-59F3-7DC3-5ECE444A401B. All the characteristics of this service (Profile User Interface service) are presented in the figure below. We, in this presentation, will focus only on the 0xC603 characteristic – UUID: FCB89C40-C603-59F3-7DC3-5ECE444A401B. This characteristic allow us to control the intensity and the color of the high brightness RGB LEDs placed on the SensorTag.

         

        Serviciu_C600.jpg

         

             In order to work correctly, the code below must be inserted after the code sequence from the Step 3, presented in ConnectBLEDevice() function, from the BluetoothLowEnergy.cpp file.  At this point and for the 0xC600 service pCharBuffer is a buffer with 4 elements. Each element stores a data structure related with one of the each of the 4 characteristics presented in the table above (UUID1: FCB89C40-C601-59F3-7DC3-5ECE444A401B, UUID2: FCB89C40-C602-59F3-7DC3-5ECE444A401B, UUID3: FCB89C40-C603-59F3-7DC3-5ECE444A401B and UUID4: FCB89C40-C604-59F3-7DC3-5ECE444A401B).

         

        PBTH_LE_GATT_CHARACTERISTIC pCharBuffer   = NULL;
        PBTH_LE_GATT_CHARACTERISTIC currGattCharTB;
        
        ……..
        
        if (pCharBuffer == NULL)	//step A				
        	{
        	free(pServiceBuffer);	pServiceBuffer = NULL; 		//free the service buffer
        	CloseHandle (hLEDevice); 				//close the BLE device handle
        	return -4;
        	}
        
        if (numChars > 4)		//step B				
        	{				//error we have more than 4 characteristics
        	free (pCharBuffer);	pCharBuffer = NULL; 		//free the characteristics buffer
        	free (pServiceBuffer); 	pServiceBuffer = NULL;		//free the service buffer
        	CloseHandle (hLEDevice); 				//close the BLE device handle
        	return -5;
        	}	
        
        //Get the specific characteristic from where the high brightness RGB LEDs can be controlled.
        //Here only the first 48 bits were checked - FCB89C40-C603-59F3-7DC3-5ECE444A401B – in
        //   order to identify this specific characteristic.
        currGattCharTB = NULL;		//step C
        for (i = 0; i< numChars; i++)
        	if (pCharBuffer[i].CharacteristicUuid.IsShortUuid == 0)
        		if (pCharBuffer[i].CharacteristicUuid.Value.LongUuid.Data1 == 0xFCB89C40 &&
        		     pCharBuffer[i].CharacteristicUuid.Value.LongUuid.Data2 == 0xC603)
        		    {
        currGattCharTB = &pCharBuffer[i]; break; } if (currGattCharTB == NULL) //step D { // if no such characteristic can be found: free all the data structures and return free (pCharBuffer); pCharBuffer = NULL; free(pServiceBuffer); pServiceBuffer = NULL; CloseHandle (hLEDevice); return -6; } typedef union //step E { BTH_LE_GATT_CHARACTERISTIC_VALUE newValue; struct { ULONG DataSize; UCHAR Data[4]; } myValue; } rezolvare; //step F rezolvare newValue_base; RtlZeroMemory(&newValue_base.newValue, ( sizeof(rezolvare) )); //step G //fill the structure with the required data newValue_base.newValue.DataSize = sizeof (UCHAR)*4; newValue_base.myValue.Data[0] = comLED; //which LEDs will be on newValue_base.myValue.Data[1] = valR; //red level [0, 255] newValue_base.myValue.Data[2] = valG; //green level [0, 255] newValue_base.myValue.Data[3] = valB; //blue level [0, 255] //step H hr = BluetoothGATTSetCharacteristicValue( hLEDevice, currGattCharTB, &newValue_base.newValue, 0, BLUETOOTH_GATT_FLAG_NONE); //step I if (S_OK != hr) { if (dbgMode) { InsertTextBoxLine (panelHandleDbg, PANEL_Dbg_TEXTBOX, -1, "Error at: BluetoothGATTSetDescriptorValue - impossible to set the I/O lines (LEDs) !"); HRESULTtoErrTxt (hr, buffErr); sprintf (buffDeAfisat, " - %s", buffErr); InsertTextBoxLine (panelHandleDbg, PANEL_Dbg_TEXTBOX, -1, buffDeAfisat); } free (pCharBuffer); pCharBuffer = NULL; free (pServiceBuffer); pServiceBuffer = NULL; CloseHandle (hLEDevice); return -4; } //step J //all is OK now and release all resources previously used free (pCharBuffer); pCharBuffer = NULL; free (pServiceBuffer); pServiceBuffer = NULL; CloseHandle (hLEDevice);

             The first 2 “if” instances (steps A and B) check the correctness of the service data in accordance with our previous knowledge related to this service. If everything is correct, we go to identifying the specific characteristic capable to influences the state of the LEDs – step C, this is done in the “for” loop.

             In D step, the software check if this specific characteristic (0xC603) was found. If this last test is passed, now we can dispatch data to the SensorTag via BluetoothGATTSetCharacteristicValue function - step H. But to do this a new data structure is defined, step E, a new variable (of this data specific type) is declared and initialized with 0, on the step F, and, in the end, the variable is initialized with the required data – step G.

             Analyzing steps E, F, G and H, one could say that a simpler approach can be easily found.  Yes, it is true, but this approach is perfectly functional for a compiler that would support a development in C++ (like Visual Studio). The BlessTags application has been fully developed in LabVindows/CVI, which has a compiler that only supports ANSI C. And for this compiler this was the only functional solution found up to now.

             Going further, if errors occur in the SensorTag communication process, they are treated in step I. At the end, all data structures used are released, step J.

             For the correct operation of the previous code, make sure the device is powered from the USB port, otherwise the RGB LEDS will be disabled by the Thunderboard Sense to conserve the power from the coin cell battery.

             And now a video to show BlessTags main functions:

         

         

             This application, BlessTags (BLE SensorTags) application, can be downloaded from the Windows Store Apps: https://www.microsoft.com/store/apps/9p054xsjjr1n. For more information, demo, practical applications, examples etc. please visit the following blog: https://ble-sensortag.blogspot.ro.

         

      • Sensor node network with Thunderboard Sense and MicroPython

        ThomasFK | 04/92/2017 | 08:04 PM

        I am a member of NUTS, the NTNU Student Test Satellite. The main goal is to create a CubeSat, a tiny satellite that piggybacks on the launch of a larger satellite.

         

        Another goal of NUTS is trying to promote aerospace/STEM topics among other students. Last fall we participated in "Researchers Night" at NTNU, which is used to promote STEM education among high school students. A lot of institutes and organizations show up at Researchers Night with really flashy displays, such as flamethrowers or slightly violent chemical reactions.

         

        At our disposal we had a vacuum chamber, a DC-motor, space-grade and regular solar panels, and several Thunderboard Senses. Showing off how marshmallows behave in vacuum, and how the DC motor behaves when connected to the different solar panels might be interesting enough in and of itself. However we decided to add some Thunderboards to spice it up a bit.

        Using a budding implementation of MicroPython for Thunderboard Sense (which will be released soon), we brainstormed and programmed a small sensor network for our stand, simulating logging telemetry data from our satellite. The Thunderboards were utilized as follows:

        • Glued to the DC motor, transmitting gyroscope data from the IMU.
        • Inside the vacuum chamber transmitting pressure.
        • Transmitting the light-level with the light-sensor.
        • Sampling the sound-level with the microphone.
        • A master that could tune into transmissions from either of the other Thunderboards, logging the output to screen and also showing how much the slave deviated from "normal" status by using the  RGB LEDs.

        I have embedded two video. The first one gives a short overview over the entire project, while the second shows the setup in action, logging data from the vacuum chamber.

         

        Our stand was a great success! Robot Very Happy We got several people standing around for up to half an hour discussing intricacies of satellite development as well as giving us an opportunity to talk more about the satellite radio link.

         

        At last I want to brag a bit about how neat this code turned out with MicroPython, and how MicroPython really was ideal for bringing up a project like this in such a short time.  The code for reading data from the IMU and transmitting it ended under 40 LOC.

        from tbsense import *
        from radio import *
        from math import sqrt
        
        rdio = Rail()
        i = IMU(gyro_scale = IMU.GYRO_SCALE_2000DPS, gyro_bw = IMU.GYRO_BW_12100HZ)
        
        def float_to_pkt(flt):
            integer = int(flt)
            decimal = round(flt, 3) - integer
            decimal = int(decimal*1000)
            ret = bytearray(6)
            ret[0] = (integer >> 24) & 0xFF
            ret[1] = (integer >> 16) & 0xFF
            ret[2] = (integer >> 8)  & 0xFF
            ret[3] = integer & 0xFF
            ret[4] = (decimal >> 8) & 0xFF
            ret[5] = decimal & 0xFF
            return ret
        
        def loop():
            meas = i.gyro_measurement()
            meas = sqrt((meas[0]**2)+(meas[1]**2)+(meas[2]**2))
            pkt = float_to_pkt(meas)
            rdio.tx(pkt)
            delay(200)
            
        def init():
            rdio.init()
            rdio.channel(MODE_IMU)
            i.init()
        
        delay(2000)
        init()
        while True:
            loop()

         

         

      • Thunderboard Sense with Raspberry Pi and Python

        DDB | 03/68/2017 | 01:16 AM

        The goal of this project was to make a very simple python script that runs on a Raspberry Pi and collects data from one or more Thunderboard Sense devices, using the same Google Firebase backend and web application that the official app uses.

         

        To get started, go to https://github.com/siliconlabs/thundercloud, and clone the repository. Follow the instructions and set up a firebase account and project, replacing the database name in src/main.js as instructed. For this example, I have not yet gotten authentication working, so change the database.rules.json for now to allow anyone to write (basically replacing "auth.uid === 'YsGcsiI8hkwjImSrr25uZdqlNw3Qkgi8vUWx9MU6'": with "true")

         

        {
          "rules": {
            ".read": false,
            ".write": false,
            "thunderboard":{
              ".read": true,
              ".write": true
            },
            "topCharts":{
              ".read": true,
              ".write": true
            },
            "sessions":{
              ".write": true,
              ".indexOn": ["startTime", "contactInfo/deviceName"],
              "$session":{//2592000000 is 30 days
                ".read": "data.child('startTime').val() > (now - 2992000000)",
                ".write":  true
              }
            }
          }
        }

         

        Now, deploy the app to Firebase using the firebase tools

         

         

        sudo npm install -g firebase
        firebase login
        firebase deploy --project <your firebase project id>

         

        In the Firebase console you should now see your deployed rules, as well as the application url. Following the URL should bring you to the default page:

        Screenshot 2017-03-09 01.35.43.png

        Now the next step is to log onto the Raspberry Pi, and install the necessary tools. The script uses bluepy to communicate with the sensor, and python-firebase to push data to the cloud. I did have some trouble installing python-firebase because of the specific version of the requests library, but eventually got it installed.

         

        Remember to put in your own database URL in the thundercloud.py script:

        from firebase import firebase
        import uuid
        import time
        
        class Thundercloud:
        
           def __init__(self):
        
              self.addr     = 'https://-- Your database URL --.firebaseio.com/'
              self.firebase = firebase.FirebaseApplication(self.addr, None)

         

        The tbsense_scan.py script continuously looks for advertising thunderboards, and automatically connects to the board if a new one is discovered.

         

        $ sudo python3 tbsense_scan.py 
        No Thunderboard Sense devices found!
        No Thunderboard Sense devices found!
        Starting thread <Thread(Thread-1, initial)> for 37020
        
        Thunder Sense #37020
        Ambient Light:	0.25 Lux
        Sound Level:	37.83
        tVOC:		0
        Humidity:	28.25 %RH
        Temperature:	29.86 C
        Pressure:	951.586
        UV Index:	0
        eCO2:		0
        

        When a Thunderboard Sense has been discovered and connected to, the script will print out the read data periodically. Take note of the number in "Thunder Sense #37020". We will need to give the number to the web application.

         

        The script generates a session ID for each board connected, and then continuously generates json strings for the data read from the Thunderboard Sense. The json string is then inserted into the appropriate location in the database. Firebase has a useful live database view that shows us that our data is indeed being pushed into the cloud:

        Screenshot 2017-03-09 01.20.16.png

        Finally if you go to the app url and append your Thunderboard Sense id, you should see the data being displayed https://<project id>.firebaseapp.com/#/37020

        Screenshot 2017-03-09 01.19.34.png

         Screenshot 2017-03-09 01.19.47.png

         tbsense.py simply discovers and sets up handles to the different characteristics. It also contains functions to read these characteristics:

         

         

        from bluepy.btle import *
        import struct
        from time import sleep
        
        class Thunderboard:
        
           def __init__(self, dev):
              self.dev  = dev
              self.char = dict()
              self.name = ''
              self.session = ''
              self.coinCell = False
        
              # Get device name and characteristics
        
              scanData = dev.getScanData()
        
              for (adtype, desc, value) in scanData:
                 if (desc == 'Complete Local Name'):
                    self.name = value
        
              ble_service = Peripheral()
              ble_service.connect(dev.addr, dev.addrType)
              characteristics = ble_service.getCharacteristics()
        
              for k in characteristics:
                 if k.uuid == '2a6e':
                    self.char['temperature'] = k
                    
                 elif k.uuid == '2a6f':
                    self.char['humidity'] = k
                    
                 elif k.uuid == '2a76':
                    self.char['uvIndex'] = k
                    
                 elif k.uuid == '2a6d':
                    self.char['pressure'] = k
                    
                 elif k.uuid == 'c8546913-bfd9-45eb-8dde-9f8754f4a32e':
                    self.char['ambientLight'] = k
        
                 elif k.uuid == 'c8546913-bf02-45eb-8dde-9f8754f4a32e':
                    self.char['sound'] = k
        
                 elif k.uuid == 'efd658ae-c401-ef33-76e7-91b00019103b':
                    self.char['co2'] = k
        
                 elif k.uuid == 'efd658ae-c402-ef33-76e7-91b00019103b':
                    self.char['voc'] = k
        
                 elif k.uuid == 'ec61a454-ed01-a5e8-b8f9-de9ec026ec51':
                    self.char['power_source_type'] = k
        
           
           def readTemperature(self):
              value = self.char['temperature'].read()
              value = struct.unpack('<H', value)
              value = value[0] / 100
              return value
        
           def readHumidity(self):
              value = self.char['humidity'].read()
              value = struct.unpack('<H', value)
              value = value[0] / 100
              return value
        
           def readAmbientLight(self):
              value = self.char['ambientLight'].read()
              value = struct.unpack('<L', value)
              value = value[0] / 100
              return value
        
           def readUvIndex(self):
              value = self.char['uvIndex'].read()
              value = ord(value)
              return value
        
           def readCo2(self):
              value = self.char['co2'].read()
              value = struct.unpack('<h', value)
              value = value[0]
              return value
        
           def readVoc(self):
              value = self.char['voc'].read()
              value = struct.unpack('<h', value)
              value = value[0]
              return value
        
           def readSound(self):
              value = self.char['sound'].read()
              value = struct.unpack('<h', value)
              value = value[0] / 100
              return value
        
           def readPressure(self):
              value = self.char['pressure'].read()
              value = struct.unpack('<L', value)
              value = value[0] / 1000
              return value
        

         

         

        thundercloud.py handles the connection to the Firebase database. getSession() generates a new session ID and is called once for every new Thunderboard Sense connection. putEnvironmentData() inserts the data and updates the timestamps:

         

         

        from firebase import firebase
        import uuid
        import time
        
        class Thundercloud:
        
           def __init__(self):
        
              self.addr     = 'https://'-- Firebase Database Name --'.firebaseio.com/'
              self.firebase = firebase.FirebaseApplication(self.addr, None)
        
           def getSession(self, deviceId):
        
              timestamp = int(time.time() * 1000)
              guid = str(uuid.uuid1())
        
              url = 'thunderboard/{}/sessions'.format(deviceId)
              self.firebase.put(url, timestamp, guid)
        
              
              d = {
                    "startTime" : timestamp,
                    "endTime" : timestamp,
                    "shortURL": '',
                    "contactInfo" : {
                         "fullName":"First and last name",
                         "phoneNumber":"12345678",
                         "emailAddress":"name@example.com",
                         "title":"",
                         "deviceName": 'Thunderboard #{}'.format(deviceId)
                     },
                     "temperatureUnits" : 0,
                     "measurementUnits" : 0,
                 }
        
              url = 'sessions'
              self.firebase.put(url, guid, d)
        
              return guid
        
           def putEnvironmentData(self, guid, data):
        
              timestamp = int(time.time() * 1000)
              url = 'sessions/{}/environment/data'.format(guid)
              self.firebase.put(url, timestamp, data)
        
              url = 'sessions/{}'.format(guid)
              self.firebase.put(url, 'endTime', timestamp)
        

         

        Finally, tbsense_scan.py continuously searches for new Thunderboard Sense devices, and spawns a new thread for each one successfully connected to:

         

        from bluepy.btle import *
        import struct
        from time import sleep
        from tbsense import Thunderboard
        from thundercloud import Thundercloud
        import threading
        
        def getThunderboards():
            scanner = Scanner(0)
            devices = scanner.scan(3)
            tbsense = dict()
            for dev in devices:
                scanData = dev.getScanData()
                for (adtype, desc, value) in scanData:
                    if desc == 'Complete Local Name':
                        if 'Thunder Sense #' in value:
                            deviceId = int(value.split('#')[-1])
                            tbsense[deviceId] = Thunderboard(dev)
        
            return tbsense
        
        def sensorLoop(fb, tb, devId):
        
            session = fb.getSession(devId)
            tb.session = session
            
            value = tb.char['power_source_type'].read()
            if ord(value) == 0x04:
                tb.coinCell = True
        
            while True:
        
                text = ''
        
                text += '\n' + tb.name + '\n'
                data = dict()
        
                try:
        
                    for key in tb.char.keys():
                        if key == 'temperature':
                                data['temperature'] = tb.readTemperature()
                                text += 'Temperature:\t{} C\n'.format(data['temperature'])
        
                        elif key == 'humidity':
                            data['humidity'] = tb.readHumidity()
                            text += 'Humidity:\t{} %RH\n'.format(data['humidity'])
        
                        elif key == 'ambientLight':
                            data['ambientLight'] = tb.readAmbientLight()
                            text += 'Ambient Light:\t{} Lux\n'.format(data['ambientLight'])
        
                        elif key == 'uvIndex':
                            data['uvIndex'] = tb.readUvIndex()
                            text += 'UV Index:\t{}\n'.format(data['uvIndex'])
        
                        elif key == 'co2' and tb.coinCell == False:
                            data['co2'] = tb.readCo2()
                            text += 'eCO2:\t\t{}\n'.format(data['co2'])
        
                        elif key == 'voc' and tb.coinCell == False:
                            data['voc'] = tb.readVoc()
                            text += 'tVOC:\t\t{}\n'.format(data['voc'])
        
                        elif key == 'sound':
                            data['sound'] = tb.readSound()
                            text += 'Sound Level:\t{}\n'.format(data['sound'])
        
                        elif key == 'pressure':
                            data['pressure'] = tb.readPressure()
                            text += 'Pressure:\t{}\n'.format(data['pressure'])
        
                except:
                    return
        
                print(text)
                fb.putEnvironmentData(session, data)
                sleep(1)
        
        
        def dataLoop(fb, thunderboards):
            threads = []
            for devId, tb in thunderboards.items():
                t = threading.Thread(target=sensorLoop, args=(fb, tb, devId))
                threads.append(t)
                print('Starting thread {} for {}'.format(t, devId))
                t.start()
        
        
        if __name__ == '__main__':
            
            fb = Thundercloud()
        
            while True:
                thunderboards = getThunderboards()
                if len(thunderboards) == 0:
                    print("No Thunderboard Sense devices found!")
                else:
                    dataLoop(fb, thunderboards)
        

         

      • IoT demo using Thunderboard

        HallMark | 12/352/2016 | 02:56 PM

        Hello,

         

        First of all I would like to Thank you Silicon Labs for the Thunderboard Sense Kit ! Tiny but Swiss Knife of Sensors. 

         

        Trust me it is !

        SENSE.jpg

         

         

        I have decided to go with IoT demo using this kit which sends Temperature, Humidity and Battery Level to Cloud.

         

        I choose RaspberryPi 3 Model B to collect the data from Sense Kit and then upload it to https://thingspeak.com/ portal.

         

        Thingspeak is very easy to create and use platform. I have created my channel there with three fields. It gives you unique API Key using which you can push data to cloud and on Thingspeak you can view the graph of your logged data. There is limit on it so you can push data once at every 15 seconds only.

         

        Thingspeak_Dashboard

        Thingspeak Dashboard !

         

        Thingspeak_Graph

        Thingspeak Graph !

         

        Project posted by @Namo_Aton helped me to to start things and find characteristics I want to read out and push data to cloud.

         

        As I want to read Battery Level, Temperature and Humidity I have find out those three characteristics first and then read it. It will read parameters at every 1 second but push to cloud at 15 second interval.

         

        Here is the python script to connect with Sense Kit, Read data and push to Cloud.

        from __future__ import division
        import sys
        from bluepy.btle import *
        import struct
        import thread
        from time import sleep
        import urllib2
        
        #
        PRIVATE_KEY = '2HL151HLWNJNENQD'
        
        #Base URL of Thingspeak
        baseURL = 'https://api.thingspeak.com/update?api_key='
        
        def vReadSENSE():
        	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_service = []
        	char_sensor = 0
        	non_sensor = 0
        	bat_char = Characteristic
        	temperature_char = Characteristic
        	humidity_char = Characteristic
        	count = 15
            
        	for i in range(num_ble):
        		try:
        			devices[i].getScanData()
        			ble_service.append(Peripheral())
        			ble_service[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_service[i].getServices()
        			characteristics = ble_service[i].getCharacteristics()
        			for k in characteristics:
        				print k
        				if k.uuid=="2a19":
        					print "Battery Level"
        					bat_char = k
        				if k.uuid == "2a6e":
        					print "Temperature"
        					temperature_char = k
        				if k.uuid == "2a6f":
        					print "Humidity"
        					humidity_char = k
        			
        	except:
        		return None
        	while True:
        		bat_data = bat_char.read()
        		bat_data_value = ord(bat_data[0])
        		
        		temperature_data = temperature_char.read()
        		temperature_data_value =(ord(temperature_data[1])<<8)+ord(temperature_data[0])
        		float_temperature_data_value = (temperature_data_value / 100)
        		
        		humidity_data = humidity_char.read()
        		humidity_data_value =(ord(humidity_data[1])<<8)+ord(humidity_data[0])
        
        		print "Battery: ", bat_data_value
        		print "Temperature: ", float_temperature_data_value
        		print "Humidity: ", humidity_data_value
        		if count > 14:
        			f = urllib2.urlopen(baseURL + PRIVATE_KEY +"&field1=%s&field2=%s&field3=%s" % (bat_data_value, float_temperature_data_value, humidity_data_value))
        			print f.read()
        			f.close()
        			count = 0
        		count = count + 1 
        		sleep(1)
        
        while True:
        	vReadSENSE()
        	

         

        Here is the video for the same.

         

         

        Cheers !

         

      • Thunderboard Sense kit Sound Alarm and notification in Telegram

        Namo_Aton | 11/334/2016 | 07:01 PM

        Hello everyone.

        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[1])<<8)+ord(mic_data[0])
                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[1]=last_value
                        # led_bytes[2]=led
                        led_bytes[3]=last_value
                        s =""
                        for i in led_bytes:
                            s+=chr(i)
                       
                        ble_mic[0].writeCharacteristic(led_handle,s,True)
                        last_value=last_value+10
                if last_value > led:
                    print "LAST VALUE HIGHER"
                    while last_value>led:              
                        led_bytes[1]=last_value
                        # led_bytes[2]=led
                        led_bytes[3]=last_value
                        s =""
                        for i in led_bytes:
                            s+=chr(i)                
                        ble_mic[0].writeCharacteristic(led_handle,s,True)
                        last_value=last_value-10
                last_value = led       
            
              
        while True:
            SENSE_handle()

        And now video how it works

         

      • Thunderboard Sense kit Sound Alarm and notification in Telegram

        Namo_Aton | 11/334/2016 | 07:01 PM

        Hello everyone.

        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[1])<<8)+ord(mic_data[0])
                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[1]=last_value
                        # led_bytes[2]=led
                        led_bytes[3]=last_value
                        s =""
                        for i in led_bytes:
                            s+=chr(i)
                       
                        ble_mic[0].writeCharacteristic(led_handle,s,True)
                        last_value=last_value+10
                if last_value > led:
                    print "LAST VALUE HIGHER"
                    while last_value>led:              
                        led_bytes[1]=last_value
                        # led_bytes[2]=led
                        led_bytes[3]=last_value
                        s =""
                        for i in led_bytes:
                            s+=chr(i)                
                        ble_mic[0].writeCharacteristic(led_handle,s,True)
                        last_value=last_value-10
                last_value = led       
            
              
        while True:
            SENSE_handle()

        And now video how it works

         

      • Pump Studios' Connected Pinewood Derby Car

        PumpStudios | 10/288/2016 | 05:17 PM

        We created a modern Pinewood Derby Car that could be controlled with Silicon Labs' Thunderboard React MCU and app.

         

        Objective:

         

        We wanted to utilize Silicon Labs' Thunderboard React MCU which contains a Bluetooth Low Energy module, two LEDs (green and blue), two switches, an accelerometer/gyroscope, and plenty of GPIO pins. The app can connect to the Thunderboard via Bluetooth and can display the orientation and speed of the car in real time. You can also turn the two LEDs on/off via the app. Initially we intended on using the orientation and speed data to trigger lights and sounds, i.e. when the car is accelerating a revving sound could play and when decelerating a braking sound/light could trigger. We quickly found out that accessing the real time car data was beyond our software skills, so as self respecting engineers we created a hack!

         

        Hardware:

         

        Since the only inputs we had access to via the app were turning the LEDs on/off, we decided to use those as triggers for our lights and sounds. When a LED was turned on, the respective GPIO pin would drop from 3.7 V to 0 V. This was used to send a signal to a connected Arduino that was then connected to an Adafruit Soundboard module. The Arduino would listen for either a high or low signal and send that signal to the Soundboard, which would play either the revving or braking sound file on loop. 

         Inside.jpg

         

         

         

         

        Wiring Diagram.jpg                                                                                                                                                                Software:

         

        You can check out the Arduino code and sound files on GitHub:

        https://github.com/nomanmithani/Pinewood-Derby-Car

         

         

        Derby Car Body:

         


        Both the derby frame and outer shell were 3D printed (Ultimaker 2+) so that we could secure all the electronic hardware in an organized way. The wheels were machined on a desktop CNC (Nomad 883 Pro) out of acrylic sheets. Keeping with our pickup truck theme, we added a payload to the bed of the truck body using stainless steel balls. The idea was to increase the total mass of the car so that it would have higher inertia coming off the derby ramp. The front hood of the truck has vents cut out for the speaker underneath.

         

        Outside.jpg

         

         

        Thanks to Silicon Labs for providing the Thunderboard React module and thanks to everyone at the Derby Race that helped us win Hottest Design!

      • Portable sensor logger with LCD, Bluetooth LE & cloud connection

        Yuriy | 09/269/2016 | 12:16 PM

        Started as one of hobby project for weather logging/monitoring and to get known 
        more with the Cortex-M4 core, FPU and DSP, plus driving LCD/RAM by EFM32 EBI. 

        Using different FW and change the connected/installed sensors device may 
        used for different applications, such as environment/agricultural monitoring, 
        portable weather logging, experiment control or even for SmartHome devices 
        control through mobile gateway application.

        Now I’m looking for inspiration and motivation to continue and real world 
        application ideas.

         

         device.jpg

         

        Logger built on Wonder Gecko (EFM32WG380F256) (or Leopard Gecko for lower-price version) with BGM111 Bluetooth LE module. PCB size is 50x80mm. 
        Powered by 1200mAh Li-Po rechargeable battery (50x70x3mm) with charging from USB port. 
        Depending on modes can work up to several months without recharging.

        device-top.jpg

         

         

        There are different types of internally mounted and external sensors currently supported:

        - Bosch Sensortec BME280 sensor for temperature/humidity/air pressure (I2C)

        - SiliconLabs Si1133 UV and Ambient Light sensing (I2C)

        - Avago APDS-9250 RGB, IR and Ambient Light sensor (I2C)

        - NXP FXOS8700CQ 6-axis accelerometer and magnetometer (I2C)

        - Akustica AKU143 analog HD voice MEMS microphone with audio amplifier 
        MCP6143 to ADC input

        - Dallas/Maxim DS1820/DS18S20/DS18B20 1-Wire external temperature sensors through external jack connector to GPIO/ADC input

         

        device-bottom.jpg

        Data from sensors are captured by customizable time and algorithms and stored in 
        NOR FLASH memory and/or MicroSD card shared same USART in SPI mode. 

         

        Second USART in SPI is busy by BGM111 Bluetooth LE module communication for 
        talking with smartphone’s application. Sensors data sent by BLE custom services, 
        mobile app will store it and push to the cloud storage. Also device settings, 
        modes and parameters may be adjusted from the app.

         

        Same functionality is doubled by USB port partially. Device supports USB as custom 
        HID device for controlling/data reading, and MSD device for accessing to MicroSD card. 
        FW can be updated via USB CDC bootloader. Window C# .NET application works with 
        logger via HIDSharp library.

         

        EFM32 drivers 2.8” TFT LCD display module with ILI9341 controller from buydisplay.com. 
        Display is connected via EFM32 EBI by 8080 16-bit Parallel interface and support RGB 65K color at 320x240 resolution 16-bit width.

        Same EBI interface is shared with 8Mbit Ultra Low-Power Pseudo CMOS static RAM for frame GUI buffers (ISSI IS66WV51216).

        To the top of LCD screen capacitive touch screen is attached. It’s connected to the 
        MCU via I2C bus. LCD backlight is driven by PWM channel.

         

         HW-diagram.gif

         

        For keeping device current in sleep mode as low as possible RAM, TFT screen, MicroSD card 
        and MIC power can be turned-off by load switches.

         

        Custom GUI is built around using of memory frame buffer on SRAM memory copying to 
        LCD screen by DMA. GUI supports software anti-aliasing and alfa-channel transparency, 
        some kind of custom controls and widgets. 
        Wonder Gecko Coretx-M4 core with hardware FPU significantly improves GUI performance.

         

        Firmware is based on using FreeRTOS ver.9.0, gecko emlib and emusb, 
        Gecko BGLib + MCU as host, FatFS FAT file system library + 
        custom drivers for sensors and flash memory.

         

        Things to do still:

        - support for APDS-9960 proximity and gesture sensor for GUI control

        - audio ADC conversion and spectrum analysis

        - advanced scheduling for sensors data reading

        - implement sleep modes and reduce current consumption

        - develop mobile application and improve windows app, but it’s not my favorite area

        - cloud service for data manipulations

        - test LCD direct drive mode of EMF32 EBI

         

         

        Sample GUI pictures:

         

        GUI light 2.jpg

        GUI temperature.jpg

        GUI TPH.jpg

        GUI-time.jpg

         

        I'm not sure about sharing complete project here because it's close related to HW. But some files will be attached here.