Arduino Nano 33 BLE Rev2 - Air Mouse

Arduino Nano 33 BLE Rev2 - Air Mouse

Air overview image

01 Overview

The BLE Air-Mouse Motion Controller (Nano 33 BLE Rev2) is a ireless Human Interface Device (HID) developed using the Arduino Nano 33 BLE Rev2.The boards utilizes the board build in gyroscope and accelerometer to detect hand movement and orientation changes, translating them into cursor movements on a paired computer through Bluetooth Low Energy (BLE).

The project demonstrates the integration of sensor fusion techniques, motion tracking, and BLE Human Interface Device (HID) communication, providing an intuitive and portable alternative input device suitable for presentations, accessibility applications, and interactive systems.

Project Use Case

Presentations and accessibility applications where users need a wireless, intuitive input device for controlling cursor movements and interacting with digital content.

02 Hardware and Software Components

Gather everything below before you start. This is your checklist to prepare for this device.

Hardware Components

Component Description
Arduino Nano 33 BLE Rev2 A compact microcontroller board based on the nRF52840 with built-in Bluetooth Low Energy (BLE), accelerometer, gyroscope, and magnetometer. It serves as the main controller of the project.
Tactile Push Button Switch with Round Cap A switch used to provide user input, such as activating gesture mode to conduct actions.
Host PC or phone A computer or smartphone used to receive BLE signals from the Arduino, program the board, or test the device.
Battery Holder/case plastic A plastic enclosure designed to securely hold lithium-ion batteries and provide convenient electrical connections.
Li-Ion Battery A rechargeable battery that supplies portable power to the system. Common examples include 18650 cells.
Micro-USB Cable Used for programming the Arduino, serial communication, and powering the board during development.
DC-DC Step Down Power Supply Module Also called a buck converter, it reduces a higher input voltage to a lower regulated voltage suitable for powering electronic components.

Software Tools

Software Version / Details
Arduino IDE 2.3.10
File Description
BLE_Airmouse.ino The main Arduino sketch for the BLE Air Mouse project.
Safety Note: Do not use voltage higher than 3.3V to power the pins except the VIN input pin which is the minimum and maximum is 4.5v-21v.

03 Application Discussion

The Arduino Nano 33 BLE Rev2 serves as the central processing unit of the system. It features an nRF52840 microcontroller with integrated Bluetooth Low Energy (BLE) capability, making it suitable for wireless HID applications.

Inertial Measurement Unit

The onboard Inertial Measurement Unit contains an accelerometer, gyroscope and magnetometer to measure the device's acceleration, rotation, and direction.

LM2596 DC-DC Step Down Power Supply Module

The LM2596 is a versatile DC-DC step-down converter that reduces a higher input voltage to a lower regulated voltage, suitable for powering electronic components.

04 Hardware Setup

Wire the components to the board using the tables below.

Air Mouse Board

Air Mouse Schematic

Air Mouse Wiring

Air Mouse Schematic

Arduino GPIO

Pin / Signal Connects To
D2 Tactile Push Button Switch with Round Cap → GND
D3 Resistor → LED → GND
D4 Resistor → LED → GND

Components Pin

Component Pin Board Pin Description
LM2596 OUT+ VIN Input voltage to the power supply module
LM2596 OUT- GND Ground connection for the power supply module
Tactile Push Button Switch with Round Cap → GND D2 Conduct an input signal
Resistor → LED → GND D3 Provide current limiting for the LED and act as a indicator for Bluetooth connection
Resistor → LED → GND D4 Provide current limiting for the LED and act as a indicator for the status of the Gesture Mode

Assembly Instructions

  1. Install Arduino Nano 33 BLE Rev2.
  2. Add Tactile Push Button Switch and connect to the digital pin.
  3. Use micro-usb cable to upload firmware.
  4. Connect the Resistor & LED to the digital pins of the Arduino.
  5. Attach LM2596 with its power supply and connect the OUT+ to the VIN and OUT- to GND.
  6. Pair device.
Note: Avoid using disconnect when you are done using the device. It may cause the device to not work properly and you have to make sure the paired device forgotten the Air Mouse.

05 Software Setup

Follow these steps in order. Do not skip any step.

Step 1 — Set Up Development Environment

  1. Run Arduino IDE
  2. Install the Arduino Mbed OS Nano Boards package
  3. Install the required libraries via the Library Manager

Step 2 — Board Settings

Use exactly these settings in your IDE. Wrong settings will cause upload failures.

Setting Value
Board Arduino Mbed OS Nano Boards: Arduino Nano 33 BLE
Port Arduino Nano 33 BLE Rev2

Step 3 — Install Libraries

Install the following libraries via the Library Manager:

  • Arduino_BMI270_BMM150 v1.2.3
  • Mbed BLE Mouse v1.3.0
  • Madgwick 1.2.0

Step 4 — Upload the Code

  1. Connect to the Arduino via micro-USB cable.
  2. Double press the reset button, if the orange LED is blinking it is in bootloader mode.
  3. Copy the code and paste to the Arduino IDE, Make sure it is in the correct port.
  4. Click Upload.

06 Code

Copy the code and prepare to upload to the device.

Arduino / C++

#include <Arduino_BMI270_BMM150.h> #include <HIDMouse.h> #include <MadgwickAHRS.h> #define MOUSE_BUTTON_LEFT 1 #define MOUSE_BUTTON_RIGHT 2 #define MOUSE_BUTTON_MIDDLE 4 HIDMouse bleMouse; Madgwick filter; const float DEADZONE = 3.0; const float SENSITIVITY = 0.20; const int MAX_SPEED = 35; float gx, gy, gz, ax, ay, az, pitch, roll, yaw; float gx_offset=0; float gy_offset=0; int Movx = 0; int Movy = 0; const float SENSOR_RATE = 104.0; float centerPitch; float centerRoll; const float NOD_ANGLE = 18.0; const float NOD_RETURN_ANGLE = 7.0; const float NOD_DIRECTION = -1.0; const float ROLL_ANGLE = 18.0; const float ROLL_RETURN_ANGLE = 7.0; const float ROLL_DIRECTION = 1.0; const unsigned long GESTURE_COOLDOWN = 600; enum GestureState { GESTURE_NONE, CHIN_DOWN, CHIN_UP, ROLL_RIGHT, ROLL_LEFT }; GestureState activeGesture = GESTURE_NONE; bool nodClickLocked = false; bool gestureStarted = false; bool leftlock = false; unsigned long lastNodTime = 0; float angleDifference(float angle, float reference) { float difference = angle - reference; while (difference > 180.0) difference -= 360.0; while (difference < -180.0) difference += 360.0; return difference; } void setup() { Serial.begin(115200); pinMode(LED_BUILTIN, OUTPUT); pinMode(2, INPUT_PULLUP); pinMode(3, OUTPUT); pinMode(4, OUTPUT); if (!IMU.begin()) { Serial.println("IMU Failed"); while (1); } filter.begin(SENSOR_RATE); bleMouse.setDeviceName("Air Mouse"); bleMouse.begin(); for(int i=0;i<500;i++) { IMU.readGyroscope(gx,gy,gz); gx_offset+=gx; gy_offset+=gy; delay(2); } gx_offset/=500; gy_offset/=500; } void detectGesture() { digitalWrite(4, HIGH); if (nodClickLocked) return; float pitchChange = angleDifference(pitch, centerPitch) * NOD_DIRECTION; float rollChange = angleDifference(roll, centerRoll) * ROLL_DIRECTION; if (activeGesture == GESTURE_NONE) { if (millis() - lastNodTime < GESTURE_COOLDOWN) return; if (pitchChange > NOD_ANGLE) { activeGesture = CHIN_DOWN; Serial.println("Chin down started"); } else if (pitchChange < -NOD_ANGLE) { activeGesture = CHIN_UP; Serial.println("Chin up started"); } else if (rollChange > ROLL_ANGLE) { activeGesture = ROLL_RIGHT; Serial.println("Roll right started"); } else if (rollChange < -ROLL_ANGLE) { activeGesture = ROLL_LEFT; Serial.println("Roll left started"); } return; } uint8_t mouseButton = 0; bool gestureComplete = false; if (activeGesture == CHIN_DOWN && fabsf(pitchChange) < NOD_RETURN_ANGLE) { mouseButton = MOUSE_BUTTON_LEFT; gestureComplete = true; Serial.println("Chin down: Left Click"); } else if (activeGesture == CHIN_UP && fabsf(pitchChange) < NOD_RETURN_ANGLE) { mouseButton = MOUSE_BUTTON_RIGHT; gestureComplete = true; Serial.println("Chin up: Right Click"); } else if (activeGesture == ROLL_RIGHT && fabsf(rollChange) < ROLL_RETURN_ANGLE) { mouseButton = MOUSE_BUTTON_MIDDLE; gestureComplete = true; Serial.println("Roll right: Middle"); } else if (activeGesture == ROLL_LEFT && fabsf(rollChange) < ROLL_RETURN_ANGLE) { if (!leftlock) { bleMouse.press(MOUSE_BUTTON_LEFT); leftlock = true; Serial.println("Left Locked"); } else { bleMouse.release(MOUSE_BUTTON_LEFT); leftlock = false; Serial.println("Left Unlocked"); } activeGesture = GESTURE_NONE; nodClickLocked = true; lastNodTime = millis(); } if (gestureComplete) { bleMouse.press(mouseButton); delay(20); bleMouse.release(mouseButton); activeGesture = GESTURE_NONE; nodClickLocked = true; lastNodTime = millis(); } } void loop() { if (!bleMouse.isConnected()) { digitalWrite(LED_BUILTIN, LOW); digitalWrite(3, LOW); bleMouse.release(MOUSE_BUTTON_LEFT); leftlock = false; gestureStarted = false; activeGesture = GESTURE_NONE; nodClickLocked = false; delay(5); return; } else { digitalWrite(3, HIGH); } digitalWrite(LED_BUILTIN, HIGH); IMU.readGyroscope(gx, gy, gz); IMU.readAcceleration(ax, ay, az); filter.updateIMU(gx, gy, gz, ax, ay, az); pitch = filter.getPitch(); roll = filter.getRoll(); yaw = filter.getYaw(); Movx = 0; Movy = 0; if (digitalRead(2) == LOW) { if (!gestureStarted) { centerPitch = pitch; centerRoll = roll; activeGesture = GESTURE_NONE; nodClickLocked = false; gestureStarted = true; Serial.println("Gesture mode started"); } detectGesture(); } else { digitalWrite(4, LOW); gestureStarted = false; activeGesture = GESTURE_NONE; nodClickLocked = false; gx -= gx_offset; gy -= gy_offset; if (fabsf(gx) > DEADZONE) { Movx = gx * SENSITIVITY; } if (fabsf(gy) > DEADZONE) { Movy = gy * SENSITIVITY; } Movx = constrain(Movx, -MAX_SPEED, MAX_SPEED); Movy = constrain(Movy, -MAX_SPEED, MAX_SPEED); } if (Movx != 0 || Movy != 0) { bleMouse.move(Movx, -Movy); } delay(5); }

07 Code Breakdown

Here is what each part of the code does. Read this after uploading.

Libraries

Library Purpose
Arduino_BMI270_BMM150 The Arduino_BMI270_BMM150 library is used to access the built-in gyroscope, accelerometer, and magnetometer of the Arduino Nano 33 BLE Rev2 for motion sensing, orientation tracking, and gesture recognition.
Mbed BLE Mouse The Mbed BLE Mouse library is used to simulate mouse movements and clicks over a BLE connection.
Madgwick The Madgwick library is used for sensor fusion to estimate orientation from IMU data.

Key Functions

angleDifference

Used to calculate the difference between new angles and center angles.

setup

Checks the hardware and initializes the offset of the gyroscope, for smoother movement.

detectGesture

Detected gestures based on the orientation data from the IMU, and conduct actions accordingly.

loop

The main execution loop that continuously reads sensor data and updates the system state.

General Program Workflow

  1. default state: detecting Bluetooth connection
  2. Connection occurred LED turns on
  3. Read gyroscope data then sent to cursor movement
  4. Hold Tactile button switch to activate gesture mode
  5. Detect orientation direction and lock
  6. Detect orientation return to previous state
  7. Use the initial direction detection to conduct actions accordingly
  8. No more orientation detection data until gesture mode reactivated
  9. Release Tactile button switch to exit gesture mode
  10. Return to cursor movement

08 Testing and Calibration

After uploading, verify each of the following to confirm the system is working correctly.

Cursor movement drifting

It tends to use the earliest detected gyroscope data, causing the cursor to drift over time. To fix go to your Bluetooth remove the Air Mouse, lay down the device on a flat surface, then press reset button on the Arduino then reconnect.

Bluetooth Connected but no response

The library Mbed BLE Mouse has issues on it's Bluetooth service, simply go to your Bluetooth then select remove device on the Air Mouse then reconnect.

Common Issue: Gesture mode not doing actions, make sure to hold the tactile button switch until the action is done, then release it.

09 System Demonstration

The images below show the working system. Use these to verify your output matches what is expected.

Air Mouse Code

Air Mouse Code

If you connect the Arduino to your computer via micro-usb please set the following.

  • Open serial monitor and set baud rate to 115200
  • Connect the device to the Bluetooth either the computer or other external device
  • Press and hold the push button, expected serial output: "Gesture mode started"

Once you have received it expect of the following actions depending on whether your roll or pitch and they can only appear once or until the push button is release:

  • Nod down: "Chin down started"
  • Nod up: "Chin up started"
  • Roll right: "Roll right started"
  • Roll left: "Roll left started"

Only one will appear the other text will not on which you will need to return the original orientation to complete its action and conduct the following depending on its initial orientation expect the following serial output:

  • Chin down: Left Click
  • Chin up: Right Click
  • Roll right: Middle (It is a toggle)
  • The left roll will conduct an act similar on holding the left mouse button:
    • Left Locked
    • Left Unlocked

Air Mouse Device

Air Mouse Device

Video Demonstration

10 Conclusion

The BLE Air-Mouse Motion Controller project successfully demonstrates the integration of motion sensing, gesture recognition, and Bluetooth Low Energy (BLE) communication using the Arduino Nano 33 BLE Rev2. The system provides an intuitive and portable alternative input device suitable for various applications, including presentations and accessibility solutions.

Possible Improvements and Future Enhancements

  • Have a BLE HID Joystick Service due to the lack of its library.
  • Utilize the Magnetometer for the inclusion of direction base on north, east, west and, south.
  • Improve or create a better BLE service implementation.

11 References

  • https://github.com/
  • https://www.arduino.cc/
  • https://openai.com/index/previewing-gpt-5-6-sol/

12 Project Authors

  • Russel Jon C. Recapente
  • Cristel Jade B. Oribe
Arduino Nano 33 BLE Rev2 - Air Mouse – CreateLabz
#codingArduino ideArduino nano 33 ble rev2

Leave a comment

All comments are moderated before being published