Introduction
Over the holiday break I developed a new Azure Sphere demo that uses Laird Connectivity BT510 BLE sensors to capture temperature, movement, magnet close/far, battery level and a few more things as well. The solution uses the Avnet Azure Sphere Starter Kit (or a qiio cellular guardian), Avnet BLE PMOD and from 1 - 10 Laird Connectivity BT510 devices.
To learn more about the Laird Connectivity BT510 solution, please follow this link.
Difficulty Level
I would mark this project at difficulty level medium/high. The blog assumes that you know how to develop Azure Sphere applications and use the Azure Portal to create an Azure IoT Hub and DPS. If you need help getting started with Azure Sphere, I recommend that you begin with our Starter Kit Out of Box Blog Series. This series of blogs will walk you through all the bits you need to start Azure Sphere development and includes detailed instructions on configuring Azure resources so your device can connect to Azure or IoT Central.
This blog assumes that the user can . . .
- Open, build, and run an Azure Sphere application from either Visual Studio or Visual Studio Code
- Configure Azure resources
- Navigate the Azure Portal to modify device twins
Design Goals
I wanted the solution to be flexible; I can imagine multiple Azure Sphere devices and a large array of BT510 devices all co-located, as if in a store or warehouse. This requires a methodology to pair/associate BT510s with specific Azure Sphere devices and a method to uniquely tag device twin and telemetry data for each BT510. The other requirement is that since this is an Azure Sphere deployment, we want to be able to leverage the Azure Sphere Over the Air (OTA) deployment strategy. This implies that all Azure Sphere devices in the solution run the same firmware, not unique firmware builds for each device. We want to be able to update thousands of devices OTA using a single firmware build and leveraging the Azure Sphere OTA infrastructure.
Additional build time options . . .
- The code base supports deploying the solution on a qiio cellular enabled Azure Sphere Guardian device
- The code base supports connecting to Avnet's IoT Connect Cloud Solution
- The code base supports using an optional Eth Click board for ethernet connections
- Azure Sphere Starter Kit Rev2 only
Requirements
The list below captures some high level requirements for the solution.
- The system shall allow the user to pair or associate specific BT510 devices with specific Azure Sphere devices
- The system shall allow each BT510 device to define its identity (name)
- The system shall use each BT510's name to uniquely generate device twin and telemetry "keys"
- The system shall use a single firmware load for all devices
- The application shall use the user RGB led to inform the user of the connected state of the device (Starter Kit only)
- Red: No wifi connection
- Green: wifi connection
- Blue: Connected and authenticated to Azure
Pictures of the Solution
Potential Use Cases
This project could be applied across various industry use-cases
- Restaurant: Monitor multiple hot and cold buffet tables, or food handling locations
- Retail: Monitor environmental conditions and count how many times a door opens/closes
- Door monitors: Monitor how often and how long doors are opened
- Movement monitor: Monitor if/when something moves, maybe a high value fixed object
- Temperature monitor: Monitor temperatures and set temperature alarms
- Your idea here, add a comment and let me know what it is . . .
Bill of Materials
- Avnet Azure Sphere Starter Kit
- qiio PoC in a Box (cellular enabled Azure Sphere Guardian, optional)
- Avnet BLE PMOD add-on board
- Laird Connectivity BT510 BLE Sensor Puck
- Eth Click (Optional)
- Only compatible with Avnet Azure Sphere Starter Kit Rev2
- Must be installed in Click Site #1 on the Starter Kit
Demo Build
Update the BLE PMOD firmware
The BLE PMOD firmware needs to be updated with the latest firmware from Laird Connectivity and then loaded with the SmartBasic Application. One of the things that made this project simple was leveraging the Laird Connectivity SmartBasic application. I did not have to do any development work with the BLE PMOD. I used the Laird application without any changes.
- Update the PMOD's onboard BL654 module to FW Version 29.4.6.0 or newer
- Load the $autorun$.BT510.gateway.sb SmartBasic application onto the BLE PMOD's BL654 module
- This application listens for BLE BT510 broadcast messages and passes them to the Avnet Starter Kit over the PMOD UART interface
- Laird Connectivity Github Repo
BLE PMOD Wiring
Wiring for the Avnet Azure Sphere Starter Kit
- Solder a 2x6 right angle header onto the Starter Kit
- Find the unpopulated header location between the Click Socket #2 headers
- Face the connector to the edge of the Starter Kit
- With the Starter Kit powered down, Insert the BLE PMOD into the new 2x6 connector
Wiring for the qiio PoC in a Box
The graphic below shows where to connect signals between the qiio device and the BLE PMOD. The Pin #s on the graphic refer to the BLE PMOD Pin numbers for each signal.
Signal | qiio device (Header Pin) | BLE PMOD |
---|---|---|
GPIO 47 | X10+X9 Pin 1 | Pin 9 |
GPIO 48 | X10+X9 Pin 2 | Pin 8 |
RTS/CTS | X7 Pin 1 (ISU3 RTS) | Pin 1 (CTS) |
TX/RX | X7 Pin 2 (ISU3 TX) | Pin 2 (RX) |
3V3 | X7 Pin 3 | Pin 6 |
RTS/CTS | X7 Pin 4 (ISU3 CTS) | Pin 4 (RTS) |
TX/RX | X7 Pin5 (ISU3 RX) | Pin 3 (TX) |
GND | X7 Pin 7 | Pin 5 |
Software
Software Design
The Azure Sphere Application follows a common Azure Sphere design using events to drive the application. This is the preferred pattern as demonstrated in the Microsoft AzureIoT example application. I use the AzureIoT example application as a starting point for all my connected Azure Sphere applications.
I can break the architecture into three main parts: the main loop, events, and Azure handlers.
Azure Sphere Main Loop
The main() function is a simple loop that initializes the hardware and handlers, then monitors a global variable: exitCode. The rest of the Azure Sphere application will update the exitCode variable if/when any issues are encountered. At that time code execution leaves the main loop to perform some cleanup activities and exits. Inside the main loop the EventLoop_Run() method is called that will pass control to any handler that the scheduler has deemed ready to run.
When an application error is encountered, the exitCode variable is updated with the reason enumeration and the application exits. When the application exits, it will return the exitCode value to the OS so that the developer can determine which exit case the application encountered. See the ExitCode enumerations in exit_codes.h to map the exit code value to the exit enumeration/reason.
Event Handlers
The events handlers are shown and described below. Event handlers can be triggered by timers (repeating or one-shot) or I/O events from hardware interfaces.
- AzureTimerEventHandler
- Manages the connection to Azure
- Runs at different intervals depending on the IoT Hub connected state
- UartEventHandler
- Responsible for reading data from the BLE PMOD UART
- Collects UART data until a complete message is received, then calls method parseAndSendToAzure() to process the message
- Runs when the UART receives data
- SendTelemetryTimerEventHandler
- Sends the latest sensor readings (from variables) to Azure as JSON telemetry
- Runs every 360 seconds (default), can be dynamically configured using the device twin key "telemetryPollTime"
- IoTCTimerEventHandler (Only for the IoT Connect build option)
- Manages the initial communications to the IoT Connect platform
- Runs every 15 seconds
Azure Callbacks
The Azure Sphere SDK implements all the Azure IoT pieces we need to interact with the Azure IoT Hub. This application uses a couple of the Azure IoT callbacks to facilitate Cloud to Device (C2D) communications.
- DeviceTwinCallback
- This method gets called when the Azure IoT Hub sends updated device twin desired properties
- ReceiveMethodCallback (Only for the IoT Connect build option)
- This method gets called when a direct method is called on the remote device from the IoT Hub
- This method expects a response message from Avnet's IoT Connect that includes specific data fields that the IoTConnect interface expects when the device sends telemetry data
Device Twins
The application implements the following device twins. Where the key contains <BT510DeviceName> the application will insert the BT510 name into the key name.
Device Twin Key | Read Only or Read/Write | Description |
---|---|---|
manufacturer | Read Only | The manufacturer of the device |
model | Read Only | The model number/name of the device |
authorizedMac1 | Read/Write | The MAC address of a BT510 device authorized to associate with this device |
authorizedMac<2-10> | Read/Write | The MAC address of a BT510 device authorized to associate with this device. One key for each authorized device. |
mac<BT510DeviceName> one instance for each BT510 | Read Only | The reported MAC address of the device, note that this MAC must also be one of the authorizedMac<n> entries. One key for each authorized device. |
fwVersion<BT510DeviceName> one instance for each BT510 | Read Only | The reported BT510 firmware version for this device. One key for each authorized device. |
bootloaderVersion<BT510DeviceName> one instance for each BT510 | Read Only | The reported BT510 bootloader version for this device. One key for each authorized device. |
telemetryPollTime | Read/Write | The time in seconds between the device sending telemetry data to the Azure IoT Hub. Note that if any of the BT510 "Alarm" events are received by the device, then the telemetry is sent up immediately. See the BT510 documentation for Alarm events. |
Telemetry Data
The application will send the following telemetry data. Where the key contains <BT510DeviceName> whatever name the BT510 defines/reports will be used in the key name. After each telemetry item is sent, the local variable is set to NaN. The NaN value will be overwritten if/when the application receives an update. Only non-NaN values are sent up as telemetry data.
Telemetry Key | Units | Description |
---|---|---|
temp<BT510DeviceName> | Degrees C | The temperature reported by this BT510. One key for each authorized device. |
rsii<BT510DeviceName> | The last reported rsii by this BT510. One key for each authorized device. | |
bat<BT510DeviceName> | Volts | The last reported battery level for this BT510. One key for each authorized device. |
movement<BT510DeviceName> | Event sent when this BT510 detects movement. | |
magnet<BT510DeviceName> | Event sent when this BT510 detects a magnet state change, 0 if close, 1 if far. One key for each authorized device. | |
reset<BT510DeviceName> | Event sent when the BT510 experiences a reset event, see the BT510 documentation for enumerations. One key for each authorized device. |
Build the Application
Pull the project from GitHub
- Pull the Avnet Azure Sphere Repo from here
Open and configure the application
- Open the project in the folder called "AvnetBT510BtSensor"
Update CMakeLists.txt to identify your hardware platform
- Define the development kit you're using in the CMakeLists.txt file. Modify line #16 to match one of the following options
- Avnet Starter Kit Rev1
azsphere_target_hardware_definition(${PROJECT_NAME} TARGET_DIRECTORY "../../HardwareDefinitions/avnet_mt3620_sk" TARGET_DEFINITION "sample_appliance.json")
- Avnet Starter Kit Rev2
azsphere_target_hardware_definition(${PROJECT_NAME} TARGET_DIRECTORY "../../HardwareDefinitions/avnet_mt3620_sk_rev2" TARGET_DEFINITION "sample_appliance.json")
- qiio PoC in a Box
azsphere_target_hardware_definition(${PROJECT_NAME} TARGET_DIRECTORY "../../HardwareDefinitions/qiio-200-dev" TARGET_DEFINITION "sample_appliance.json")
- Avnet Starter Kit Rev1
Update app_manifest.json
This is a connected application. There is not a non-connected build option, so you must have an IoT Hub, IoT Central application, or IoT Connect instance to connect your device. If you need help configuring Azure resources and updating your app_manifest.json file, you can use the following links to get help.
- Microsoft AzureIoT Example: Link
- Since this application started life as the Azure IoT Example, all the instructions for configuring Azure resources and updating the app_manifest.json file apply to this application
- Avnet Starter Kit Out of Box Blog Series: Link
- This series of blogs will walk the user through all the steps necessary to get started with Azure Sphere development and includes details on configuring Azure resources and IoT Central application
Build Options
Open the build_options.h file to review the different build options. Note: If you're using one of the Avnet Starter Kits without an Eth Click or IoT Connect, you don't need to make any changes to this file.
Build Option | Description |
---|---|
USE_ETH_0 | Define if you want to use the optional Eth Click board. Make sure to install the Eth Click board in Click Socket #1. This option is only available for the Avnet Starter Kit Rev2 hardware. |
TARGET_QIIO_200 | Define if you're using the qiio PoC in a Box development Kit |
USE_IOT_CONNECT | Define if you want to connect your device to Avnet's IoT Connect Platform. Note that the application will connect to Azure IoT Hub or Azure IoT Central by default. |
Configure your BT510 device(s)
As mentioned earlier in this blog, the application uses the Laird Connectivity BT510 device name to uniquely identify data from each device to the Azure Cloud resources. This requires that the user configure each BT510 with a unique name. If you have more than one Azure Sphere Device, you can configure multiple BT510s with the same name, but for any one Azure Sphere device, any authorized BT510 must have a unique name different from the other BT510s authorized for that Azure Sphere Device.
To configure your BT510 you need to download the mobile application, and update the device name.
- Search your mobile device app store for "Sentrius BT510"
- Install the application and follow the instructions for connecting your BT510 device to the mobile app
- On the "Settings" tab change the Device Name field for your application. In the graphic below, I named this BT510 "Basement"
- Be careful not to include any spaces before or after the name. These will be sent to the Azure Sphere application. Ask me how I know!
- Repeat the configuration for each BT510 in your deployment
- The "Settings" tab also allows you to configure how often measurements are read and broadcast
- To learn more about the Laird Connectivity BT510 solution, please follow this link.
Build and run the application
It's time to build and load the application onto your Azure Sphere Starter Kit (or the qiio device). Build, load, and run the application. Assuming your device has an Internet connection and your Azure resources are configured correctly, the application will connect to Azure.
You should see debug similar to the screenshot below . . .
If your device does not connect to your IoT Hub/IoT Central
- Verify that your device has an internet connection
- Verify that your app_manifest.json file is correctly updated
- Verify that your Azure resources are correctly and completely configured (did you add the enrollment group to your DPS resource?)
Add device twins for our application to your Cloud implementation
Next, update the device twin desired properties to match the device twins our application implements
- Open an interface to your Azure Sphere devices Device Twin
- I'll use the Azure Portal
- Navigate to your device and open the device twin tab
- In the desired section add the following lines . . .
"authorizedMac1": "",
"authorizedMac2": "",
"authorizedMac3": "",
"authorizedMac4": "",
"authorizedMac5": "",
"authorizedMac6": "",
"authorizedMac7": "",
"authorizedMac8": "",
"authorizedMac9": "",
"authorizedMac10": "",
"telemetryPollTime": 30,
- Click on the Save link
- Click on the Refresh link
- Scroll down to the "reported" properties section. You should see your desired properties show up as reported properties.
- If not, verify your device is connected to your IoT Hub
Power up a BT510
When your BT510 powers up, it will start to broadcast messages. Your application should see these messages and output debug similar to the debug below.
Device E7-E0-E9-02-95-A5 has not been Authorized, discarding message data To authorize the device add its MAC address as a authorizedMac<n> in the IoTHub device twin
- If you don't see this debug
- Verify you correctly configured your CMakeLists.txt file for your Avnet Starter Kit Rev1 or Rev2
- These kits use different ISUs on the PMOD interface
- Verify that you updated the BLE PMOD firmware and loaded the SmartBasic application
- Verify you correctly configured your CMakeLists.txt file for your Avnet Starter Kit Rev1 or Rev2
Authorize one or more BT510 devices
- Next find the MAC address on the back of your BT510 device or copy it from your debug
- Mine is "E7-E0-E9-02-95-A5"
- Enter the MAC as the value part of the "authorizedMac1" key: value pair
- Make sure your MAC uses UPPER CASE text and contains the '-'s
- Click the Save link
- Click the Refresh link
- You should see the "authorizedMac1" reported property updated with your MAC
- Enter the MAC as the value part of the "authorizedMac1" key: value pair
Your application will receive the device twin update and the next time a BT510 message is received the application will . . .
- Validate that the device is authorized
- Read the device static information and send it to Azure as device twins
- Add the device to a dynamic connected list for processing
- Every 30 seconds, if new BT510 data was received, a telemetry message will be constructed and sent to your Azure IoT Hub
As BT510 messages are received the application will parse out data and send it up as telemetry dynamically creating telemetry keys that use your devices name. See the sample output below for my device named "Coach". . .
Add additional BT510s
At this point you can add up to 9 more BT510s as authorized devices!
Data Visualization with Avnet's IoT Connect Platform
Below is a simple dashboard that I created with Avnet's IoT Connect Platform. The data is from a single BT510. Using the IoT Connect platform I created this dashboard in ~15 minutes.
Conclusion
I had a lot of fun developing this application. I configured my Azure IoT Device to monitor my motorhome that's sitting out in the cold environment of Costal North Carolina. I have one BT510 inside the motorhome named "Coach," and a second BT510 in the storage area called "Basement."
I really hope that you can leverage the work that I did for some real world deployment. In my opinion this is a production-ready application. It's secured with my Azure Sphere MCU (and I did not have to implement any security features!). It's scalable; one build for thousands of devices and it's fully configurable from the cloud.
If you're interested in learning more about the Laird Connectivity BT510 solution, please follow this link.
What commercial applications can you think of for this solution? Please add a comment and let me know your ideas.
Future Improvements
- Add the SmartBasic application to the imagepackage and add OTA update capabilities to update the BLE PMOD
- Handle the case where a authorizedMac<n> changes
- Determine if the old MAC is in the connected list and remove it to make room for the new device
- Test with more devices
- I've tested with two BT510s and everything worked really well
- If there are many, many BT510's broadcasting the UART RX buffer may need to be enlarged to allow for all the messages to be received and examined
- Your ideas here . . .