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

Projects

    Publish
     
      • Zigbee to Modbus TCP/IP Gateway

        gettogupta | 07/195/2018 | 03:43 PM

         

        Zigbee to Modbus Gateway

        Fact #1 : Industrial IoT is one of the biggest slice of the global IoT pie.

        Fact #2 : Zigbee is a popular industrial communication wireless standard

        Fact #3 :  Modbus is an indispensable part of industrial automation.

        Our technical team realized this opportunity and came up with this Zigbee to Modbus TCP/IP gateway, that can act as an interface between a industrial Zigbee network and a Modbus TCP/IP or even a general TCP/IP network and hence the internet at large. 

        Naturally, when it came to selecting a Zigbee module we decided to go with the Telegesis ETRX357-LRS module, for a host of reasons. For the TCP/IP end we used the Xpico module by Lantronix. Because the Xpico comes in a general TCP/IP stack version and also a Industrial Modbus TCP/IP stack version. 

        To make the product more versatile we decided to add a ARM Cortex M4 MCU for some custom firmware and device management. To make the product truly easy to use and deploy on field we added a PoE+ (IEEE 802.3at) power option. 

        Look forward to comments and suggestions from experts here on potential use cases and opportunities with the product. 

      • How to create your own BLE Mobile App in 10 minutes

        Juan Benavides | 01/29/2018 | 10:43 PM

        Hackathon Project by Juan Benavides

         

         

        Introduction

        Have you ever wanted to get into mobile apps development but didn't have the time to learn other programming languages?

        In this blog I will show you how to create your own mobile app that connects to your Bluetooth Low Energy device.

        As part of a Hackathon project, I was interested in creating my own mobile app to connect to a Zigbee-based Light that doubles as a BLE Device. In other words, it is a Light that supports two protocols; Zigbee and BLE over the same radio.

        I wanted to support Android and iOS and I only had a background in Embedded Systems and a couple of days to get it done. So, after a quick Google search I was lucky to find a solution that only takes 10 minutes to develop (that's including the time spent installing the tools).

        The solution is called Evothings Studio and it offers a way to develop your mobile app using familiar web technologies such as HTML, CSS and JavaScript.

        One of the most amazing things is that the mobile app runs live on mobile devices while you develop and you can instantly see code changes on your apps.

        The process of developing the mobile app can be summarized as follows:

        1. Get a Bluetooth Device running.
        2. Install Evothings Tools in your PC and your phone.
        3. Select an example from the Evothings list of examples.
        4. Modify the example by using the UUIDs from your BLE Device. 
        5. Connect your phone to your BLE Device to control it.

         

         

        Step-by-step guide to reproduce the project

         

        Getting a Bluetooth Device running

        If you already have a BLE Device running, then the only thing you need to do in this step is make note of the following Unique Identifiers (UUID):

        • BLE Unique Service Indentifier: this is the UUID of the BLE Device Service you want to control (e.g. bae55b96-7d19-458d-970c-50613d801bc9).
        • BLE Characteristic Unique Identifier: this is the UUID of the BLE Device Characteristic you want to control (e.g. 76e137ac-b15f-49d7-9c4c-e278e6492ad9).

        If you don't have your BLE Device ready to go, then you can use the same one that I used from the Dynamic Multiprotocol (DMP) Light/Switch Demo. Click here and follow steps 1-5 to get it running.

        Once you get it running, open the Light Project in Simplicity Studio, open the file DynamicMultiprotocolDemoLightSoc.isc, select the Bluetooth GATT tab and make note of the BLE Unique Service Identifier and the BLE Characteristic Unique Identifier as illustrated in the image below:

        Figure 1
        Finding your BLE Device's UUIDs in Simplicity Studio

         

         

        Installing the Evothings Tools

        In this step you need to install both, the Evothings Studio application in your PC and the Evothings Mobile App in your phone. Click here to install the Evothings tools and verify that everything is operational by running their Hello World example.

         

         

        Select a Mobile App BLE example as a starting point

        Once you verified that you can run their Hello World example, locate the example Arduino101 LED On/Off BLE and click the button Copy as shown in Figure 2:

        Figure 2
        Selecting one of the BLE Examples as a starting point

         

         

        A window will be displayed for you to edit the project's name. You can call it dmp-light as shown in the following image:

        Figure 3
        Customizing the example with your own project name

         

         

        Modifying the Mobile App BLE example with your own UUIDs

        The next step is to edit the code. Select the tab MyApps in Evothings Studio to display your newly created example and click the button Edit and your text editor will open the folder where your example is located.

        First edit the file evothings.json and replace the property uuid with your own BLE Device Service UUID as shown in Figure 4:

        Figure 4
        Customizing the example with your own BLE device's service UUID

         

         

        Similarly, open the file index.html and replace the uuids in the functions to turn the LED On and Off, with your own BLE Device Characteristic UUID as shown in the image below:

        Figure 5
        Customizing the example with your own BLE device's characteristic UUID

         

         

        Finally, find out what's the advertised name of your BLE Device by scanning all the BLE devices within range from your phone as shown in Figure 6:

        Figure 6
        Scanning BLE devices within range from your phone

         

         

        Open the file index.html, locate the function app.connect and replace the advertised name of the BLE device with your own name as illustrated in Figure 7:

        Figure 7
        Customizing the example with your own BLE device name

         

         

        Connecting your new mobile app to your BLE device

        To connect to your BLE device you need to follow the same steps you made when trying their Hello World example; Start Evothings Workbench and under the Connect tab paste your Cloud Token and get a connect key using the GET KEY button. Launch Evothings Viewer on your phone, enter the connect key to hook up with your Workbench. On your computer, click the RUN button on your new DMP Light example in the Workbench.

        Now you can turn the Light On/Off from your phone as shown in the image below:

        Figure 8
        Your new mobile app

         

         

         

        Conclusion

        The Evothings Studio platform is a fast and easy way to develop mobile applications for Android and iOS while supporting one single code base through the use of the three most basic web technologies (HTML, JavaScript and CSS).

        For more information on how to deploy your mobile app to an app store check the following page: https://evothings.com/doc/build/build-overview.html

        For more information on how to get started developing your own Bluetooth Low Energy devices visit our website at: https://www.silabs.com/products/wireless/bluetooth

         

      • How to control a Zigbee-based Light with an Occupancy Sensor, Alexa and your Phone

        Juan Benavides | 01/22/2018 | 08:05 PM

        Hackathon project by Manasa Rao, Stephen To and Juan Benavides

         

         

        Introduction

        Would you like to learn an easy way to control a Zigbee-based Light with Alexa voice commands?

        Or how about controlling a Zigbee-based Light automatically with an Occupancy Sensor?

        Furthermore, how would you like to learn how to easily create your own Bluetooth mobile application to control a Zigbee-based Light and access the Internet?

        In this Hackathon project we demonstrate how to easily accomplish all of these cool features.

        Figure 1
        Project Presentation

         

         

        Background

        Silicon Labs released on November 2017 the new Dynamic Multiprotocol Software (DMP) for our Wireless Geckos. In summary, the DMP software enables the simultaneous operation of Zigbee and Bluetooh Low Energy (BLE) on a single radio chip.

        The best example to showcase this technology is by controlling and monitoring a Zigbee-based Light directly over Bluetooth with a smartphone mobile application. This example is actually available with the DMP SDK and our Hackathon project is based on it. 

         

         

         

        Project Overview

        The following image illustrates the scope of this blog:

        Project Overview
        Figure 2
        Project Block Diagram

         

        The Demo featured in this blog is based on the official DMP Light/Switch Demo that consists of two devices:

        Light: it runs Micrium OS to switch between Zigbee and Bluetooth on a single radio. 

        Switch: it supports Zigbee to provide wireless control of the Light.

        Click here to get started with this demo.

        In the original demo, users press a push button on the wireless Switch device, which in turn, sends a Zigbee Light Link (ZLL) command to toggle the Light On or Off.

        The Light device runs Micrium OS to switch between Zigbee and Bluetooth while sharing the same radio. This allows a mobile application to connect to the Light via Bluetooth.

        Users tap the mobile application to toggle the Light On/Off. 
        The Light device receives the Bluetooth notification and not only toggles the Light On/Off  but also updates the corresponding ZLL Cluster Attribute so the Switch remains in sync.

        This blog shows you how to add an Occupancy Sensor to the Switch device by connecting the Silicon Labs Optical Sensor Expansion Board (Si1133/Si1153) to the Switch's EXP Header (I2C).

        The Optical Sensor Expansion Board has a series of optical sensors to detect the presence of a person in the room. The occupancy sensor is used by the embedded application to control the light automatically. 

        Click here to see Stephen's blog on how to add this occupancy sensor to the DMP Light/Switch Demo.

        This blog is also going to show you how to control the Light with Alexa Voice Commands.

        To enable Alexa Voice Commands, we are also going to show you an easy way to create your own Bluetooth Mobile Application. This mobile application will use the smartphone as a gateway to access the Internet.

        Click here to see Juan's blog on how to create your own BLE mobile app to control the DMP Light/Switch Demo.

        Users will get to control the Light with Voice Commands and this blog will describe how to setup the system in Amazon Web Services (AWS).

        Click here to see Manasa's blog on how to add Alexa capabilities to the DMP Light/Switch Demo.

         

         

         

        Useful Links

         

         

         

      • 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.

      • Simple WGM110 programming fixture

        madsci | 10/289/2017 | 03:29 PM

        This project isn't really an end in itself, just a simple tool for working with the WGM110 Wi-Fi module, but it was suggested that I share it here, so I'm re-posting.

         

        Sometimes it's useful to be able to pre-program modules before they're installed on a board, particularly if your board doesn't have space for a SWD header.  The earliest versions of the WGM110 also had a defective DFU bootloader (stop bits were 1/2 bit time) that wouldn't work with some hosts, which made in-circuit programming difficult without SWD.

         

        To address this I made a quick and dirty programming fixture for about $15.  The components are a Mill-Max 854-22-010-40-001101 0.050" pitch 10-position pogo pin header to connect to the WGM110, a Samtec SFSD-10-28-H-05.00-SR cable with 20-pin 0.050" pitch plug for the JTAG side, some heat shrink tubing, and a 3D printed holder that I whipped up in Alibre.

         

        This is not really the right JTAG connector - its polarity key is in the wrong place and it's latching - but it's the closest thing that Digi-Key happened to have in stock that had discrete wires.  It fits on the dev board as is, and it'll fit on a P&E Cyclone's shrouded header if you snip off the key.

         

        In the orientation shown in the top view photo, the pogo pins are wired to the following JTAG pins:

         

         

        • 3 (ground)
        • (nc) 
        • 1 (VDD) 
        • 10 (Reset) 
        • (nc)
        • 2 (SWDIO)
        • 4 (SWCLK)
        • (nc)
        • (nc)
        • (nc)

         

        If I was going to be using this much I'd have machined mine from Delrin or anti-static ABS, but for only doing a few dozen units at most it didn't seem worth firing up a milling machine.

         

        Without the holder piece, I can use the pogo pin plug to re-flash modules in circuit that have been bricked by DFU failures.  This depends on having the PCB lands extend far enough beyond the periphery of the module to make contact.  If you followed the recommended layout in the datasheet, it ought to work. I wouldn't want to have to do many boards this way without an alignment jig to hold it in place, but it works fine to just hold it in place if you're just fixing an occasional mistake and not doing production quantities.

         

        Top view:

         

        2017-10-14 12.34.07.jpg

        Bottom view, with wiring to pogo pins:

        2017-10-14 12.34.19.jpg

        The STL file and original model in Alibre format are attached.  Keep in mind that I set the dimensions to make it work with my own 3D printer and the fit may require tweaking on yours.

         

        It's no substitute for a proper in-circuit programming setup for production, but it's handy for prototyping and I figured I'd share it here in case anyone else needs such a gadget.

         

        Scott

      • Simple WGM110 programming fixture

        madsci | 10/289/2017 | 03:29 PM

        This project isn't really an end in itself, just a simple tool for working with the WGM110 Wi-Fi module, but it was suggested that I share it here, so I'm re-posting.

         

        Sometimes it's useful to be able to pre-program modules before they're installed on a board, particularly if your board doesn't have space for a SWD header.  The earliest versions of the WGM110 also had a defective DFU bootloader (stop bits were 1/2 bit time) that wouldn't work with some hosts, which made in-circuit programming difficult without SWD.

         

        To address this I made a quick and dirty programming fixture for about $15.  The components are a Mill-Max 854-22-010-40-001101 0.050" pitch 10-position pogo pin header to connect to the WGM110, a Samtec SFSD-10-28-H-05.00-SR cable with 20-pin 0.050" pitch plug for the JTAG side, some heat shrink tubing, and a 3D printed holder that I whipped up in Alibre.

         

        This is not really the right JTAG connector - its polarity key is in the wrong place and it's latching - but it's the closest thing that Digi-Key happened to have in stock that had discrete wires.  It fits on the dev board as is, and it'll fit on a P&E Cyclone's shrouded header if you snip off the key.

         

        In the orientation shown in the top view photo, the pogo pins are wired to the following JTAG pins:

         

         

        • 3 (ground)
        • (nc) 
        • 1 (VDD) 
        • 10 (Reset) 
        • (nc)
        • 2 (SWDIO)
        • 4 (SWCLK)
        • (nc)
        • (nc)
        • (nc)

         

        If I was going to be using this much I'd have machined mine from Delrin or anti-static ABS, but for only doing a few dozen units at most it didn't seem worth firing up a milling machine.

         

        Without the holder piece, I can use the pogo pin plug to re-flash modules in circuit that have been bricked by DFU failures.  This depends on having the PCB lands extend far enough beyond the periphery of the module to make contact.  If you followed the recommended layout in the datasheet, it ought to work. I wouldn't want to have to do many boards this way without an alignment jig to hold it in place, but it works fine to just hold it in place if you're just fixing an occasional mistake and not doing production quantities.

         

        Top view:

         

        2017-10-14 12.34.07.jpg

        Bottom view, with wiring to pogo pins:

        2017-10-14 12.34.19.jpg

        The STL file and original model in Alibre format are attached.  Keep in mind that I set the dimensions to make it work with my own 3D printer and the fit may require tweaking on yours.

         

        It's no substitute for a proper in-circuit programming setup for production, but it's handy for prototyping and I figured I'd share it here in case anyone else needs such a gadget.

         

        Scott

      • 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)
        

         

      • Big red button on Thunderboard Sense and Samsung Artik 5

        DanilBorchevkin | 02/32/2017 | 12:19 AM

        As a weekend project, I decided to select an implementation of a big red button based on Thunderboard Sense and Samsung Artik 5. Why a big red button? Because everybody likes red buttons. About it even make films (The Box, 2009).

         

        Sorry for any possible mistakes - I am not a native English speaker/writer. By the way this article there is in russian language.

         

        What is needed for the project

         

        1. Big red button - for this all was conceived. The button should to be normally open
        2. Thunderboard Sense Kit
        3. Samsung Artik 5
        4. Seeed Studio Arduino Base Shield
        5. Seeed Studio Grove Buzzer

         

         

        Setup Thunderboard Sense

         

        Fortunately, we do not need to change anything in the code of the Thunderboard Sense, otherwise it would become a headache - Bluetooth SDK to this device requires an IAR ARM 7.80 compiler, that for many would be a big problem.

         

        As an actuator will act SW1 button - on this button will be tied up all logic of own project.

         

         

        Default firmware do not need any changes because it have following logic:

        1. Board sleep in inactive state and can't accept incoming connections. For change it mode to connectable mode need to push SW1.
        2. After push on SW1 green led start blink there is a possibility for connect to it.
        3. When disconnect is happened Thunderboard Sense again going to sleep.

        Thunderboard Sense provides various BLE services and characteristics (full list available in Android App repository). For us interested only one characteristic - CHARACTERISTIC_PUSH_BUTTONS, which have UUID fcb89c40-c601-59f3-7dc3-5ece444a401b and constist from one value uint8_t, with following states:

        1. Zero (=0) if no buttons was pressed;
        2. One (=1) if SW1 was pressed;
        3. Two (=2) if SW2 was pressed;
        4. Three (=3) if was pressed both SW1 and SW2;

        It is noteworthy that this characteristic has only read property which leads us to the solution of a periodic value reading.

         

        Setup Artik 5

        If it a first-time work with Artik 5 then you need to basic setup according to Quick Start Guide. For start developing you should upgrade to latest firmware and setup internet connection.

         

        Pre-installed packet manager for OS Fedora on Artik is dnf so all following instructions will be for it.

         

        First install all software needed for Bluetooth:

         

        dnf install bluez bluez-libs bluez-libs-devel

        Besides install Git:

        dnf install git

        Futher install Node.JS and npm:

        dnf install nodejs npm

        After this we need to install main module for work with BLE - noble - this module allows to serve BLE connections in case when controller have to do a central role.(for inverse situation there is the bleno module):

        npm install noble

        Now we ready for coding!

         

        Pairing

         

        For pairing devices we need to use the interactive util bluetoothctl. First start it:

         

        bluetoothctl

        After starting we need to switch on a pairing possibility:

         

        pairable on

        Then we should activate Thunderboard sense by pressing on SW1 and start scanning:

         

        scan on

        Target device we can determine by friendly name or by address.

         

         

        When the needed device is finding we should stop the scanning:

        scan off

        The most important for us - remember the address of own Thunderboard Sense and execute following commands:

        pair 00:0B:57:36:71:82
        trust 00:0B:57:36:71:82
        connect 00:0B:57:36:71:82

        At this stage we get message "Connection successful" and now we can request information about connected device:

        info 00:0B:57:36:71:82

        Output will be similar to my:

         

         

        Now input:

        exit

        and ... we ready to write code on Node.JS!

         

        Work with Bluetooth on Artik 5

         

        noble allows develop code for central device. So we have to implement following logic for work with Thunderboard Sense:

        1. Scanning for finding connectable Thunderboard Sense.
        2. Connect to device with a known address.
        3. Gettings lists of services and characteristics.
        4. Read the buttons characteristic's value.

        If you need only working code - go to https://bitbucket.org/sithings/app_thunderboardtoartik

         

        For start scanning we must make sure that Bluetooth controller is power up and only after that we can start scanning:

        /* Event of the state change of the BLE controller on board */
        noble.on('stateChange', function(state) {
        	if (state === "poweredOn") {
        		/*
        		 * If BLE normally started start scanning with duplicates with any UUIDs services
        		 */
        		console.log("\x1b[36m", "\nBLE is poweredOn. Start scanning", "\x1b[0m");
        		noble.startScanning([], false);
        	} else {
        		console.log("\nStopScanning. Status is %s", state);
        		noble.stopScanning();
        	}
        });

        After start scanning we must push SW1 on the Thunderboard Sense for wake up it. Once the device will be available script will be attempt connect to it:

        noble.on("discover", function(peripheral) {
        	
                ...
        
        	/* If founded device is own big red button */
        	if(config.bigRedButton.deviceAddress === peripheral.address) {
        		peripheral.connect( function(error) {
                        
                        ...
        
        		});
        	}
        });

        After successful connect we need to get all services and characteristics:

        peripheral.connect( function(error) {
        	peripheral.discoverAllServicesAndCharacteristics(function(error, services, characteristics) {
        		...
        	});

        In my code I define the desired characteristic by enumeration method:

         

        for(i = 0; i < characteristics.length; i++) {
        	/* If we find characteristic with button state when color it */
        	if (characteristics[i].uuid === config.bigRedButton.characteristicUUID) {
        		buttonStateChar = characteristics[i];
        	}
        	...

        Desired characteristic which contaits value with button state have only one property - read. For acquiring button states we need implement peridical reading of desired value. Afrter define the desired characteristic we need to set a polling interval.

         

        readingInterval = setInterval(readButtonCallback, config.bigRedButton.pollingInterval);

        Listing of the callback:

         

        /* Button callback started by setInterval */
        function readButtonCallback() {
        	buttonStateChar.read(function(error, data) {
        		buf = data[0];
        		console.log("\nData: %d", buf);
        		if (buf === 1) {
        			console.log("SW1 was pressed");
        			/* Enable buzzer */
        			config.buzzer.set();
        		}
        		else if (buf === 2) {
        			console.log("SW2 was pressed");
        		}
        		else if (buf === 0) {
        			console.log("No button pressed");
        			/* Disable buzzer */
        			config.buzzer.clear();
        		} 
        	});
        }

         

        Make buzz

         

        Unfortunately, I could not get to work with GPIO over artik-sdk module and I decided work with GPIO over sysfs. Grove Buzzer in my solution connected over Seeed Studio Base shield to pin gpio121 (2 pin of Arduino expansion).

         

        After starting the script a desired pin must to init as "out":

         

        exec("echo 121 > /sys/class/gpio/export");
        exec('echo "out" > /sys/class/gpio/gpio121/direction');

        To buzzer squeaked the pin must be pulled up:

         

        exec('echo "1" > /sys/class/gpio/gpio121/value');

        To silence buzzer the pin must be pulled down:

         

        exec('echo "0" > /sys/class/gpio/gpio121/value');

        Then exiting the script the buzzer's pins must be released:

         

        exec("121 > /sys/class/gpio/unexport");

        All of this was implemented in config.js of the project. Link to repository.

         

        Connect big red button to Thunderboard Sense.

         

        I have this kind of the button:

         

         

        Interesting fact - the button is more expensive than Thunderboard Sense Kit.

         

        Connect the button by soldering as described on a following scheme:

         

         

        In my case, it looks like this:

         

         

        Testing

         

        Video with test:

         

         

         

         

        But it isn't serous because buzzer too weak. I change the buzzer to relay with signal lamp:

         

         

         

         

        Now the big red button is really cool!

         

        Results

         

        It works. Repository with project - https://bitbucket.org/sithings/app_thunderboardtoartik

         

        Links