179 lines
5.8 KiB
C++
179 lines
5.8 KiB
C++
#include <BleMouse.h>
|
|
#include "EspUsbHost.h"
|
|
#include <LedControl.h>
|
|
#include "BatteryMonitor.h"
|
|
|
|
#define LED_PIN 21 // GPIO пин светодиода (скорее всего 48)
|
|
#define NUM_LEDS 1 // Один RGB светодиод
|
|
|
|
|
|
// #define DISABLE_RGB_UUID // отключить управление диодои по BLE
|
|
// #define DISABLE_USB // отключить чтение реальной usb мыши
|
|
|
|
#define SHOW_REAL_BATTERY // считывать реальный уровень батареи
|
|
#define RGB_LED // включить подстветку
|
|
|
|
BleMouse bleMouse("Ball Mouse");
|
|
|
|
#ifdef RGB_LED
|
|
Adafruit_NeoPixel rgbLed(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
|
|
LedControl ledControl(rgbLed);
|
|
#endif //RGB_LED
|
|
|
|
#ifdef SHOW_REAL_BATTERY
|
|
// Параметры для считывания уровня батареи
|
|
#define BATTERY_UPDATE_INTERVAL 5000 // например, 30000 мс = 30 секунд
|
|
#define BATTERY_ADC_PIN 6
|
|
#define BATTERY_VOLTAGE_DIVIDER_RATIO 2.0f
|
|
#define BATTERY_VOLTAGE_MAX 4.2f
|
|
#define BATTERY_VOLTAGE_MIN 3.0f
|
|
BatteryMonitor battery(BATTERY_ADC_PIN, BATTERY_VOLTAGE_DIVIDER_RATIO, BATTERY_VOLTAGE_MAX, BATTERY_VOLTAGE_MIN);
|
|
#endif//SHOW_REAL_BATTERY
|
|
|
|
#ifndef DISABLE_USB
|
|
// Расширяем класс для обработки USB мыши
|
|
class MyEspUsbHost : public EspUsbHost {
|
|
void onMouseButtons(hid_mouse_report_t report, uint8_t last_buttons) {
|
|
if (!bleMouse.isConnected()) return;
|
|
|
|
// Нажатия и отпускания кнопок
|
|
if ((last_buttons & MOUSE_BUTTON_LEFT) != (report.buttons & MOUSE_BUTTON_LEFT)) {
|
|
if (report.buttons & MOUSE_BUTTON_LEFT) bleMouse.press(MOUSE_LEFT);
|
|
else bleMouse.release(MOUSE_LEFT);
|
|
}
|
|
if ((last_buttons & MOUSE_BUTTON_RIGHT) != (report.buttons & MOUSE_BUTTON_RIGHT)) {
|
|
if (report.buttons & MOUSE_BUTTON_RIGHT) bleMouse.press(MOUSE_RIGHT);
|
|
else bleMouse.release(MOUSE_RIGHT);
|
|
}
|
|
if ((last_buttons & MOUSE_BUTTON_MIDDLE) != (report.buttons & MOUSE_BUTTON_MIDDLE)) {
|
|
if (report.buttons & MOUSE_BUTTON_MIDDLE) bleMouse.press(MOUSE_MIDDLE);
|
|
else bleMouse.release(MOUSE_MIDDLE);
|
|
}
|
|
// Дополнительные кнопки (если поддерживаются)
|
|
}
|
|
|
|
void onMouseMove(hid_mouse_report_t report) {
|
|
if (!bleMouse.isConnected()) return;
|
|
|
|
// Передаём перемещения и скролл через BLE
|
|
bleMouse.move(report.x, report.y, report.wheel);
|
|
}
|
|
};
|
|
MyEspUsbHost usbHost;
|
|
#endif //DISABLE_USB
|
|
|
|
void setup() {
|
|
// Serial.begin(115200);
|
|
//-----------Запуск мыши — зелёный--------------
|
|
#ifdef RGB_LED
|
|
ledControl.begin();
|
|
ledControl.forceColor(0, 255, 0); // Зеленый
|
|
#endif//RGB_LED
|
|
delay(500);
|
|
|
|
//--------Инициализация BLE - красный-----------
|
|
#ifdef RGB_LED
|
|
ledControl.forceColor(255, 0, 0); // Красный
|
|
#endif//RGB_LED
|
|
ble_init();
|
|
|
|
//---------Инициализация USB — синий------------
|
|
#ifdef RGB_LED
|
|
ledControl.forceColor(0, 0, 255); // Синий
|
|
#endif//RGB_LED
|
|
#ifndef DISABLE_USB
|
|
usbHost.begin();
|
|
#endif
|
|
|
|
//---Мышь готова - загружаем сохранённый цвет---
|
|
#ifdef RGB_LED
|
|
ledControl.applyColor();
|
|
#endif//RGB_LED
|
|
}
|
|
|
|
void loop() {
|
|
handleBleConnection();
|
|
#ifndef DISABLE_USB
|
|
// чтение мыши
|
|
usbHost.task();
|
|
#else
|
|
// симуляция движения мыши
|
|
if (bleMouse.isConnected())
|
|
{
|
|
bleMouse.move(5, 0, 0);
|
|
delay(1000);
|
|
}
|
|
#endif //DISABLE_USB
|
|
|
|
#ifdef SHOW_REAL_BATTERY
|
|
// чтение уровня батареи
|
|
static unsigned long lastBatteryUpdate = 0;
|
|
if (bleMouse.isConnected()) {
|
|
unsigned long now = millis();
|
|
if (now - lastBatteryUpdate > BATTERY_UPDATE_INTERVAL) {
|
|
lastBatteryUpdate = now;
|
|
|
|
uint8_t batteryLevel = battery.readLevelPercent();
|
|
Serial.printf("Battery Level: %d%%\n", batteryLevel);
|
|
|
|
bleMouse.setBatteryLevel(batteryLevel);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
// --- повторный запуск BLE, если отключение ---
|
|
static bool wasConnected = false;
|
|
bool currentlyConnected = bleMouse.isConnected();
|
|
if (wasConnected && !currentlyConnected) {
|
|
Serial.println("BLE disconnected, restarting advertising...");
|
|
bleMouse.begin(); // запускаем advertising снова
|
|
}
|
|
wasConnected = currentlyConnected;
|
|
}
|
|
|
|
|
|
void ble_init()
|
|
{
|
|
// Запуск BLE мыши (HID)
|
|
bleMouse.init();
|
|
#ifdef RGB_LED
|
|
#ifndef DISABLE_RGB_UUID
|
|
// Создаём BLE-сервис для подстветки
|
|
ledControl.setupBLEService(bleMouse.server);
|
|
#endif//DISABLE_RGB_UUID
|
|
#endif//RGB_LED
|
|
// Запуск BLE мыши (HID)
|
|
bleMouse.begin();
|
|
}
|
|
|
|
bool lastBleStatus = false;
|
|
bool blinkInProgress = false;
|
|
unsigned long blinkStartTime = 0;
|
|
const unsigned long blinkDuration = 250; // длительность моргания (мс)
|
|
void handleBleConnection() {
|
|
bool currentStatus = bleMouse.isConnected();
|
|
|
|
// --- обработка изменения статуса подключения ---
|
|
if (currentStatus != lastBleStatus) {
|
|
// Визуальная вспышка
|
|
blinkInProgress = true;
|
|
blinkStartTime = millis();
|
|
ledControl.forceBrightness(100); // максимальная яркость
|
|
ledControl.forceColor(255, 255, 255); // белый
|
|
|
|
// перезапуск ble если мышка отключена
|
|
if (!currentStatus) {
|
|
BLEDevice::deinit(true); // true — полное удаление и перезапуск
|
|
ble_init();
|
|
}
|
|
}
|
|
|
|
// Завершаем вспышку
|
|
if (blinkInProgress && (millis() - blinkStartTime > blinkDuration)) {
|
|
blinkInProgress = false;
|
|
ledControl.applyColor(); // восстановить предыдущий цвет
|
|
}
|
|
|
|
lastBleStatus = currentStatus;
|
|
} |