I welcome you to this part of my review about Arduino Nano 33 BLE Sense. My review is split into multiple blog posts. You can find all my thoughts about this Arduino and related parts in chapters with name beginning with "Review". There are also articles describing test projects like this one which I have done for gathering experiences with board and some tutorials. Main page of review contains summary and final score. Following Table of Contents contains links to other parts of my roadtest review.
Table of Contents
- Introduction
- Review of Development Board
- Review of Onboard Sensors
- Review of Microcontroller and BLE Module
- Review of Software
- Review of Documentation
- Tutorial 01: Accessing Sensor Values
- Tutorial 02: nRF52840 Application without Arduino IDE
- Project 01: Gestures over BLE (this article)
- Project 02: Speach Reccognition and Machine Learning
- Summary and Score
Project 01: Gestures over BLE
As part of review process, I have developed application utilizing BLE and gesture sensor. The Arduino part act as peripheral and provide custom service (custom service is BLE term for service which you can completely design from scratch. There are also some predefined services). Every time when gesture sensor (APDS-9960) detect gesture it updates value of appropriate characteristic and sends notification to connected computer (or mobile, or another device. I have implemented Windows 10 Application on my laptop). I used concept of notifications. Computer registers to listening for notifications from device. When application receive notification about gesture, it executes configured command.
Arduino sketch
Arduino provides basic example showing how to use Bluetooth and there are also examples showing reading values from sensors (I also shown it in Tutorial 01: Accessing Sensor Values). Write BLE application on Arduino platform is easy in comparison with other platforms but you need to understand relations between BLE, GATT and characteristics but you can find lot of examples on the internet with explanation. I had these experiences from my previous roadtest of PSoC 62 Pioneer Kit. Because of ultra-simple interface of ArduinoBLE library it took me about hour to develop and debug this app on Arduino side.
In code there are global declaration of objects. One global object represents my custom service. BLE devices provides services. Services are defined by GUID. Some GUIDs are reserved for standard services like service providing battery status. If you do not want to use some predefined service, you can define completely your own protocol as I did. All GUIDs are random. Probability of duplications is very low because GUID is 128bit number and there are 2^128 unique GUIDs which is about 300 000 000 000 000 000 000 000 000 000 000 000 000. Random selection will (almost) always work. Probability of duplication is very low. The same GUIDs are used in desktop app. Service contains characteristics which you can consider as variables which you can remotely read or write over BLE. In setup() function you must assign characteristics to some service. Characteristics have opportunity to send notification to device when value has changed. Computer/mobile or other device connecting to device must register for receiving notifications and since that moment library will do that. You must specify BLENotify flag if you want to support this for characteristics. This concept is not shown in samples, but Arduino supports it and I have used it. I designed my own protocol in a way, that when gesture occurs, it changes value of gesture related characteristic to value 1. After about 100ms I change value to 0 again to be ready for handling another gesture later. I have designed protocol to have one characteristic per gesture. So, I have 1 service with 4 characteristics.
In loop function I check for presence of connection. If I get connected to new device, I print Bluetooth address to Serial. In loop I of course check data from sensor and change characteristics values in case of gesture detected.
Desktop app
Since my previous experiences with BLE I decided to improve desktop application resulting into more robust solution. I properly implemented discovery of devices. In last application it usually worked but it was not fully correct and under some circumstances it may crash or prevent detecting device. It also consumed lots of power because I did not stop device discovery in case when I had connected to some device. These issues I resolved in this new app. I also change format of app. In PSoC 62 roadtest I developed modern UWP Windows 10 Application. In this roadtest I developed desktop application using WPF but BLE is handled by the same API as I have used in UWP Application. This also means that my app still works only on Windows 10 and older Windows are not supported because this API is not present there.
Application window allows you to configure notifications behaviour and commands which are executed when you trigger some command. You can disable or enable notification related to connection and disconnection of device and you can enable notifications about received gesture (up, down, left, or right). Gesture notifications are useful for debugging. You can configure triggering any program in your computer and you can specify command line arguments for that command. You can for example configure program of left gesture to “mspaint” and every time when you move hand from right to left over sensor, application starts new instance of Microsoft paint program. If you want to do something different from simple execution you can write your own program which will do that and configure path to program here.
Code is written in my favourite language VB.NET. If you do not like it or do not understand VB.NET, you can copy sources to https://codeconverter.icsharpcode.net/ and convert sources to C#. C# and VB.NET are technologically similar languages. Compiler of both languages compiles into IL and binaries are compatible. You can freely translate VB.NET to C# without issues because both supports very similar APIs and features.
Code is separated to multiple classes. The most interesting classes are AnySingleDeviceConnectionManager and Device. AnySingleDeviceConnectionManager implements logic for discovering nearby devices and managing connection to one device which has required service (service is identified by GUID specified in Arduino code). If connection fail, or device get disconnect, class search for another available device. Connection to BLE device is fully autonomous. You do not need to pair devices before use. BLE devices do not need to be paired anymore. Paring is security feature which is not supported by Arduino yet. This is reason why you receive error message if you try to pair with device from settings in Windows.
Device class maintains connection with single device. It discovers services and characteristics of device. It configures characteristics to generate notifications and retrieve it.
There is also GlobalSettings class for storing configuration entered in main window and finally, there is ToastHelper class which is used for generating notification in Windows.
My final note is that application do not worry about multiple devices, pairing (which is unsupported on Arduino yet) and security at all. You may take in account some security risks like possibility to expose sensitive information (gesture which you have done) to other persons near to you and also remote execution because anyone near to you can start transmitting malformed information that some gesture was executed. In that moment app executes command which you have configured even you have did not triggered gesture. Do not configure starting some critical app here.
On the following video you can see project in action.
Summary
If you understand structure of BLE it is easy to develop application on Arduino and you can do it in minutes. If you do not have sufficient knowledge you probably spend some time with learning it. Arduino provides library which has easy to understand interface and it is very familiar to use. Unless you use some generic service, you probably will have to implement mobile/computer app yourself which may be more significant pain because very complex interfaces at this side. Also note that predefined services are not implemented in Arduino library and you must every time implements device side yourself. But usually it is not so hard and sometimes there are example with implemented standard service. For example, there is implemented battery service which is used for indicating level of remaining battery capacity.
Code of project is available to download below this text.