Overview: Using IMU & Microphone on Seeed XIAO BLE Sense
In this tutorial we will learn how to use LSM6DS3 IMU Sensor & PDM Microphone on Seeed XIAO BLE nRF52840 Sense. This is the continuation article of the previous tutorial, i.e. Getting Started with Seeed XIAO BLE nRF52840 Sense.
This is the advanced tutorial using Seeed XIAO BLE nRF52840 Sense. In this tutorial, we will read the accelerometer, gyroscope, and temperature sensor data from the internal LSM6DS3 IMU Sensor. Then using the IMU Sensor we will design a pedometer. A pedometer is an instrument for estimating the distance traveled on foot by recording the number of steps taken. Regarding the mic part, we will learn how to use PDM Microphone to detect audio and sound.
In the end you will be able to learn how to use IMU & Microphone on XIAO BLE nRF52840 Sense to do some Machine Learning and Artificial Intelligence projects.
Seeed XIAO BLE nRF52840 Sense
First, let’s have a short overview of these boards. These boards are based on Nordic nRF52840 BLE 5.0 Chip from Nordic Semiconductor. One of the boards is called Seeed XIAO BLE nRF52840 and the other is Seeed XIAO BLE nRF52840 Sense.
p>These boards are small-sized, ultra-low-power Bluetooth development boards. One of the boards features an onboard Bluetooth antenna, and onboard battery charging chip which makes it ideal for IoT projects. The other board called the XIAO Sense board has additional features like 6 DOF IMU and a PDM microphone which make it an ideal board to run AI using TinyML and TensorFlow Lite.
The topside of the board has a reset button, 6 DOF IMU LSM6DS3TR-C, Bluetooth Antenna, PDM Microphone, RGB LED & power LED. On the backside of the board, there are SWD Pins for Debugging and Reflashing Bootloader using JLink. There are pair of pins to connect the NFC Antenna & also a 3.7V Lithium-Ion Battery.
There are 11 digital I/O that can be used as PWM pins and 6 analog I/O that can be used as ADC pins. It supports UART, IIC, and SPI all three common serial ports.
Reading LSM6DS3 IMU Sensor Value
XIAO BLE Sense is equipped with a high-precision 6-Axis Inertial Measurement Unit (IMU) which includes a 3-axis accelerometer and a 3-axis gyroscope. There is also an embedded temperature sensor on this module.
Now, let’s move to the practical part. First, we will read the value of the LSM6DS3 IMU Sensor from Seeed XIAO BLE nRF52840 Sense. Connect the Type C USB Cable to the XIAO BLE Board. Then connect the other end of the cable to your PC. Hence the Serial communication with PC will establish.
To use the IMU Sensor, we need the LSM6DS3 library. You can download the library from the GitHub repository: LSM6DS3 Library.
Once the library is downloaded, open your Arduino IDE. Then add the library through add zip folder.
Source Code/Program
Now copy the following code and paste it into your Arduino IDE.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include "LSM6DS3.h" #include "Wire.h" //Create an instance of class LSM6DS3 LSM6DS3 myIMU(I2C_MODE, 0x6A); //I2C device address 0x6A void setup() { // put your setup code here, to run once: Serial.begin(9600); while (!Serial); //Call .begin() to configure the IMUs if (myIMU.begin() != 0) { Serial.println("Device error"); } else { Serial.println("Device OK!"); } } void loop() { //Accelerometer Serial.print("\nAccelerometer:\n"); Serial.print(" X1 = "); Serial.println(myIMU.readFloatAccelX(), 4); Serial.print(" Y1 = "); Serial.println(myIMU.readFloatAccelY(), 4); Serial.print(" Z1 = "); Serial.println(myIMU.readFloatAccelZ(), 4); //Gyroscope Serial.print("\nGyroscope:\n"); Serial.print(" X1 = "); Serial.println(myIMU.readFloatGyroX(), 4); Serial.print(" Y1 = "); Serial.println(myIMU.readFloatGyroY(), 4); Serial.print(" Z1 = "); Serial.println(myIMU.readFloatGyroZ(), 4); //Thermometer Serial.print("\nThermometer:\n"); Serial.print(" Degrees C1 = "); Serial.println(myIMU.readTempC(), 4); Serial.print(" Degrees F1 = "); Serial.println(myIMU.readTempF(), 4); delay(1000); } |
Now go to tools and Select Seeed XIAO BLE Sense – nRF52840 as a board.
Also select the COM port.
Now you can upload the code to your XIA BLE Sense Board.
Testing IMU Sensor
After the code is uploaded, open the Serial Monitor.
You can see the accelerometer, gyroscope, and thermometer reading on the Serial Monitor. The X, Y, and Z values for both accelerometer and gyroscope are in raw format. Similarly, the temperature value is displayed in both Celsius and Fahrenheit.
DIY Pedometer using IMU
In this 2nd example, we will use the LSM6DS3 IMU Sensor of Seeed XIAO BLE nRF52840 Sense to make a Pedometer. A pedometer, or step-counter, is a device, usually portable and electronic or electromechanical, that counts each step a person takes by detecting the motion of the person’s hands or hips.
The pedometer code for XIAO BLE Sense is available in the example part. You can copy the example code or use the code below.
Source Code/Program
Copy the following code and paste it into your Arduino IDE.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
#include "LSM6DS3.h" #include "Wire.h" #define CLEAR_STEP true #define NOT_CLEAR_STEP false //Create a instance of class LSM6DS3 LSM6DS3 pedometer(I2C_MODE, 0x6A); //I2C device address 0x6A void setup() { Serial.begin(9600); while (!Serial); if (pedometer.begin() != 0) { Serial.println("Device error"); } else { Serial.println("Device OK!"); } //Configure LSM6DS3 as pedometer if (0 != config_pedometer(NOT_CLEAR_STEP)) { Serial.println("Configure pedometer fail!"); } Serial.println("Success to Configure pedometer!"); } void loop() { uint8_t dataByte = 0; uint16_t stepCount = 0; pedometer.readRegister(&dataByte, LSM6DS3_ACC_GYRO_STEP_COUNTER_H); stepCount = (dataByte << 8) & 0xFFFF; pedometer.readRegister(&dataByte, LSM6DS3_ACC_GYRO_STEP_COUNTER_L); stepCount |= dataByte; Serial.print("Step: "); Serial.println(stepCount); delay(500); } //Setup pedometer mode int config_pedometer(bool clearStep) { uint8_t errorAccumulator = 0; uint8_t dataToWrite = 0; //Temporary variable //Setup the accelerometer****************************** dataToWrite = 0; // dataToWrite |= LSM6DS3_ACC_GYRO_BW_XL_200Hz; dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_2g; dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_26Hz; // Step 1: Configure ODR-26Hz and FS-2g errorAccumulator += pedometer.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, dataToWrite); // Step 2: Set bit Zen_G, Yen_G, Xen_G, FUNC_EN, PEDO_RST_STEP(1 or 0) if (clearStep) { errorAccumulator += pedometer.writeRegister(LSM6DS3_ACC_GYRO_CTRL10_C, 0x3E); } else { errorAccumulator += pedometer.writeRegister(LSM6DS3_ACC_GYRO_CTRL10_C, 0x3C); } // Step 3: Enable pedometer algorithm errorAccumulator += pedometer.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x40); //Step 4: Step Detector interrupt driven to INT1 pin, set bit INT1_FIFO_OVR errorAccumulator += pedometer.writeRegister(LSM6DS3_ACC_GYRO_INT1_CTRL, 0x10); return errorAccumulator; } |
You can upload this code to your XIAO BLE Sense Board.
Testing the IMU Based Pedometer
After the code is uploaded, open the Serial Monitor.
Initially, the Serial Monitor will show steps as zero. Now in order to measure the steps properly, you need to put this device in your pocket and start walking. In my case, I will shake this module so that the calculation of the step will be done based on the shaking motion. Therefore the more the shaking moment, the steps will be added to the previous count.
So this is how you can make your own pedometer using this IMU Sensor on XIAO BLE nRF52840 Sense. There is another way to make a Pedometer as well which can be done using BMI160 & ESP32 Module.
Using PDM Microphone of BLE Sense
XIAO BLE Sense is equipped with a PDM (Pulse Density Modulation) Microphone which can receive audio data in real-time and can be used for audio recognition. With the wireless connection and fine performance in processing audio data because of the FPU, it can be used for more interesting TinyML projects like remote voice controlling of devices.
In this tutorial, we will check whether the voice is detected or not. We will visualize the raw data from the PDM Microphone on a Serial Monitor and Serial Plotter in real-time. The voice detection magnitude is based on the loudness of sound detected by the microphone.
For coding part, you need to download Arduino Mic Library. This library is used for interfacing Arduino-compatible hardware devices with microphone sensors for sound recording and further processing, e.g. calculating FFT, MFCC.
Source Code/Program
Copy the following code and paste it into your Arduino IDE.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
#include <mic.h> #if defined(WIO_TERMINAL) #include "processing/filters.h" #endif // Settings #if defined(WIO_TERMINAL) #define DEBUG 1 // Enable pin pulse during ISR #define SAMPLES 16000*3 #elif defined(ARDUINO_ARCH_NRF52840) #define DEBUG 1 // Enable pin pulse during ISR #define SAMPLES 800 #endif mic_config_t mic_config{ .channel_cnt = 1, .sampling_rate = 16000, .buf_size = 1600, #if defined(WIO_TERMINAL) .debug_pin = 1 // Toggles each DAC ISR (if DEBUG is set to 1) #elif defined(ARDUINO_ARCH_NRF52840) .debug_pin = LED_BUILTIN // Toggles each DAC ISR (if DEBUG is set to 1) #endif }; #if defined(WIO_TERMINAL) DMA_ADC_Class Mic(&mic_config); #elif defined(ARDUINO_ARCH_NRF52840) NRF52840_ADC_Class Mic(&mic_config); #endif int16_t recording_buf[SAMPLES]; volatile uint8_t recording = 0; volatile static bool record_ready = false; #if defined(WIO_TERMINAL) FilterBuHp filter; #endif void setup() { Serial.begin(115200); while (!Serial) {delay(10);} #if defined(WIO_TERMINAL) pinMode(WIO_KEY_A, INPUT_PULLUP); #endif Mic.set_callback(audio_rec_callback); if (!Mic.begin()) { Serial.println("Mic initialization failed"); while (1); } Serial.println("Mic initialization done."); } void loop() { #if defined(WIO_TERMINAL) if (digitalRead(WIO_KEY_A) == LOW && !recording) { Serial.println("Starting sampling"); recording = 1; record_ready = false; } #endif #if defined(WIO_TERMINAL) if (!recording && record_ready) #elif defined(ARDUINO_ARCH_NRF52840) if (record_ready) #endif { Serial.println("Finished sampling"); for (int i = 0; i < SAMPLES; i++) { //int16_t sample = filter.step(recording_buf[i]); int16_t sample = recording_buf[i]; Serial.println(sample); } record_ready = false; } } static void audio_rec_callback(uint16_t *buf, uint32_t buf_len) { static uint32_t idx = 0; // Copy samples from DMA buffer to inference buffer #if defined(WIO_TERMINAL) if (recording) #endif { for (uint32_t i = 0; i < buf_len; i++) { // Convert 12-bit unsigned ADC value to 16-bit PCM (signed) audio value #if defined(WIO_TERMINAL) recording_buf[idx++] = filter.step((int16_t)(buf[i] - 1024) * 16); //recording_buf[idx++] = (int16_t)(buf[i] - 1024) * 16; #elif defined(ARDUINO_ARCH_NRF52840) recording_buf[idx++] = buf[i]; #endif if (idx >= SAMPLES){ idx = 0; recording = 0; record_ready = true; break; } } } } |
You can upload this code to your XIAO BLE Sense Board.
Testing the PDM Microphone
Open the Serial Monitor again after uploading the code. In the serial monitor, there is a random value displayed based on voice input detected. In order to visualize the audio graph go to tools and open the serial plotter.
In the serial plotter, you can see the rising and falling graph based on voice. You can test the mic by speaking something.
So this is how the PDM microphone works on Seeed XIAO BLE nRF52840 Sense.
















2 Comments
PDM example seems to give the error message:
#error “This library targets only Wio Terminal boards at the moment”
download the latest lib instead
https://github.com/Seeed-Studio/Seeed_Arduino_Mic