Implementing a Mouse with ESP32-S3

Today, we will only write code. Features: 1. Use the Bluetooth functionality of the ESP32-S3 chip to connect, while displaying the Bluetooth connection status. 2. The onboard RGB LED alternates flashing blue and red to indicate waiting for connection status; the green light indicates connected, and the red light indicates disconnected. 3. IO12 and IO3 serve as the left and right buttons, respectively. Another wire connects to GND as a middle line; when IO12 and IO3 are shorted to GND, it simulates left and right button clicks.

#include<BleConnectionStatus.h>

#include<BleMouse.h>

#include<Adafruit_MPU6050.h>

#include<Adafruit_Sensor.h>

#include<Wire.h>

#include<Adafruit_NeoPixel.h>

// ====== ESP32-S3 Pin Definitions ======

#defineLED_PIN 48 // ✅ Common RGB LED pin for ESP32-S3 development board

#defineLEFT_BTN_PIN 12

#defineRIGHT_BTN_PIN13

// ====== Debug Switch ======

#defineDEBUG_MOVEMENTtrue

// ====== Global Objects ======

BleMouse bleMouse(“GloveMouse”);

Adafruit_MPU6050 mpu;

Adafruit_NeoPixel pixel(1, LED_PIN, NEO_GRB + NEO_KHZ800);

// ====== MPU Calibration ======

bool mpuCalibrated = false;

float ax_offset = 0.0f, ay_offset = 0.0f;

constfloat SENSITIVITY_X = 80.0f;

constfloat SENSITIVITY_Y = 80.0f;

constfloat DEAD_ZONE = 0.15f;

// ====== LED Power Saving ======

unsignedlong lastStateChangeTime = 0;

constuint8_t BRIGHTNESS_NORMAL = 30;

constuint8_t BRIGHTNESS_DIMMED = 1;

constunsignedlong DIM_DELAY_MS = 10000;

bool isConnected = false;

#defineCOLOR_RED pixel.Color(255, 0, 0)

#defineCOLOR_GREEN pixel.Color(0, 255, 0)

#defineCOLOR_BLUE pixel.Color(0, 0, 255)

voidsetLED(uint32_t color) {

pixel.setPixelColor(0, color);

pixel.show();

}

voidupdateLED() {

unsignedlong now = millis();

bool shouldDim = (now – lastStateChangeTime) > DIM_DELAY_MS;

uint8_t brightness = shouldDim ? BRIGHTNESS_DIMMED : BRIGHTNESS_NORMAL;

pixel.setBrightness(brightness);

if (!bleMouse.isConnected()) {

staticunsignedlong lastToggle = 0;

staticbool isRed = false;

if (now – lastToggle > 500) {

isRed = !isRed;

setLED(isRed ? COLOR_RED : COLOR_BLUE);

lastToggle = now;

}

} else {

setLED(COLOR_GREEN);

}

}

voidsetup() {

// ⚠️ ESP32-S3: Serial (USB CDC) must be initialized

Serial.begin(115200);

while (!Serial); // Wait for USB serial connection (only needed for debugging, can be commented out)

Serial.println(“🚀 Glove Mouse (ESP32-S3 + MPU6500) Starting…”);

Wire.setClock(400000);

Wire.begin();

pinMode(LEFT_BTN_PIN, INPUT_PULLUP);

pinMode(RIGHT_BTN_PIN, INPUT_PULLUP);

// Initialize RGB LED

pixel.begin();

pixel.setBrightness(BRIGHTNESS_NORMAL);

setLED(COLOR_RED);

delay(500); // See red light indicates startup

// Initialize MPU6500

if (!mpu.begin()) {

Serial.println(“❌ MPU6500 not found!”);

} else {

mpu.setAccelerometerRange(MPU6050_RANGE_2_G);

mpu.setGyroRange(MPU6050_RANGE_250_DEG);

mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);

Serial.println(“✅ MPU6500 initialized.”);

Serial.println(“⏳ Calibrating… Keep hand steady for 2s!”);

setLED(COLOR_BLUE);

delay(2000);

float sum_ax = 0, sum_ay = 0;

for (int i = 0; i < 100; i++) {

sensors_event_t a, g, temp;

mpu.getEvent(&a, &g, &temp);

sum_ax += a.acceleration.x;

sum_ay += a.acceleration.y;

delay(5);

}

ax_offset = sum_ax / 100.0f;

ay_offset = sum_ay / 100.0f;

mpuCalibrated = true;

Serial.print(“OffsetTable: X=”); Serial.print(ax_offset, 2);

Serial.print(“, Y=”); Serial.println(ay_offset, 2);

}

bleMouse.begin();

lastStateChangeTime = millis();

Serial.println(“📱 BLE Mouse started. Connect to ‘GloveMouse'”);

}

voidloop() {

updateLED();

if (bleMouse.isConnected() && !isConnected) {

isConnected = true;

lastStateChangeTime = millis();

Serial.println(“✅ Bluetooth connected!”);

} elseif (!bleMouse.isConnected() && isConnected) {

isConnected = false;

lastStateChangeTime = millis();

Serial.println(“❌ Bluetooth disconnected!”);

}

// Button Presses

staticbool leftPressed = false, rightPressed = false;

bool leftNow = !digitalRead(LEFT_BTN_PIN);

bool rightNow = !digitalRead(RIGHT_BTN_PIN);

if (leftNow && !leftPressed) {

bleMouse.press(MOUSE_LEFT);

Serial.println(“🖱️ Left press”);

leftPressed = true;

} elseif (!leftNow && leftPressed) {

bleMouse.release(MOUSE_LEFT);

Serial.println(“🖱️ Left release”);

leftPressed = false;

}

if (rightNow && !rightPressed) {

bleMouse.press(MOUSE_RIGHT);

Serial.println(“🖱️ Right press”);

rightPressed = true;

} elseif (!rightNow && rightPressed) {

bleMouse.release(MOUSE_RIGHT);

Serial.println(“🖱️ Right release”);

rightPressed = false;

}

// MPU6500 Movement

if (mpuCalibrated && bleMouse.isConnected()) {

sensors_event_t a, g, temp;

mpu.getEvent(&a, &g, &temp);

float ax = a.acceleration.x – ax_offset;

float ay = a.acceleration.y – ay_offset;

int dx = (abs(ax) > DEAD_ZONE) ? (int)(ax * SENSITIVITY_X) : 0;

int dy = (abs(ay) > DEAD_ZONE) ? (int)(-ay * SENSITIVITY_Y) : 0;

if (dx != 0 || dy != 0) {

bleMouse.move(dx, dy, 0);

#ifDEBUG_MOVEMENT

Serial.print(“🖱️ Move: dx=”); Serial.print(dx);

Serial.print(“, dy=”); Serial.println(dy);

#endif

}

}

delay(15);

}

==============

Output results:

22:19:26.921 -&gt; 🚀  (ESP32-S3 + MPU6500) Starting...
22:19:26.921 -&gt; ❌ MPU6500 not found!
22:19:26.921 -&gt; 📱 BLE Mouse started. Connect to 'GloveMouse'
22:19:48.082 -&gt; ✅ Bluetooth connected!
22:20:21.318 -&gt; 🖱️ Left press
22:20:21.446 -&gt; 🖱️ Left release
22:20:28.805 -&gt; 🖱️ Right press
22:20:29.116 -&gt; 🖱️ Right release

Leave a Comment