Tuesday, December 13, 2022

Sending Inertia Motion Unit Data of Arduino Nano BLE 33 over Bluetooth BLE

This Arduino sketch and Max patch takes the inertia motion unit data of the Nano BLE 33 and sends it via Bluetooth BLE using the ArduinoBLE library. The data is transferred as a set of BLE Characteristics as a BLE Service. The Max patch scans for the BLE device, connects to it and then subscribes to the data streams. The output can be normalised, smoothed and then routed via MIDI to music software such as Ableton. The Max patch uses the max-ble external. 

Get the Arduino code here, the Max patch here and the 4bf subpatch here

With Bluetooth Low Energy (BLE), devices do not need to pair in order to communicate data. Instead, a paradigm of central and peripheral devices is used. Central devices scan for Peripheral devices and initiate connections. Peripheral devices advertise their BLE Services and wait for a Central device to connect. In this example, the computer running the Max patch is the Central and the Arduino Nano BLE 33 is the Peripheral. 

A given Service on a Peripheral device is made up of one or more Characteristics. A Characteristic contains one or more bytes of data and may be part of a standard profile or a generic type with customised data length. Each Service and Characteristic has a UUID unique identifier that is either a 16-bit or 128-bit string. The Arduino BLE library contains a number of functions to create a BLE Service and Characteristic

This setup combines the following: 

  • In Arduino, start the BLE radio as a Peripheral device, create a Service with a UUID for the IMU data and then create three Characteristics each with a UUID - one each for the accelerometer, gyroscopic and magnetometer
  • Read the accelerometer, gyroscopic and magnetometer values using the 9-axis LSM9DS1 inertia motion unit
  • Then, using a data struct for the x, y and z axes the current values from the 9-axis IMU are stored as floats (if there are new readings available) 
  • The data struct for each inertia type is stored in a data union that is also addressable by a byte array
  • This byte array from the union, which now contains the updated float values from the IMU, is then read and written to the BLE Characteristic which automatically Notifies the Central device
  • The Max patch acts as the Central device and can scan for devices with the correct UUID
  • Once the correct UUID is found from the scan, a connection can be made
  • Once the connection has been made, each of the three characteristics can be Subscribed to
  • Every time a new value is written to the Characteristic, the Central device is Notified and if the Max patch is Subscribed to this Characteristic, the new data values are received in Max by the max-ble object
  • In this case, each Characteristic contains a float value for the x, y and z components for the accelerometer, gyroscopic and magnetometer - making for a total of 3 floats per Characteristic and 3 Characteristics 
  • Each of these floats arrives in Max as a set of four bytes. These four bytes are then converted back to a floating value within Max using the subpatch 4bf. 
  • This data is then scaled and normalised, so as to be visualised via multisliders
  • The data is also smoothed with a user defined ramp time
  • Finally, the data can be muted by x, y, z channel and then sent via MIDI CC to other music software