T-vK / ESP32-BLE-Mouse

Bluetooth LE Mouse library for the ESP32 (Arduino IDE compatible)
681 stars 133 forks source link

Mac OS X Pair Workaround #42

Open dsaul opened 2 years ago

dsaul commented 2 years ago

In case it is relevant for anyone else, I was able to work around Mac OS X not pairing by not sending any commands for 5-10 seconds after it connected. This could likely be tuned lower, but is good for my use case.

Example:

unsigned long connectedMillis = 0; // delay actions until after connected for 10 seconds, because apple is dumb
// ...
BleMouse bleMouse;

void setup()
{
  // ...
}

void loop()
{
  // Start, apple is dumb.
  if(bleMouse.isConnected()) {
    if (connectedMillis == 0) {
      connectedMillis = millis();
    }

  }

  if (millis() < connectedMillis + (10 * 1000)) {
    return;
  }
  // End, apple is dumb.

  // ... 
}

Regards, Dan

jslay88 commented 1 year ago

Doesn't seem to work for me. Sadly, because I had this working (not with the delay, just the library in general), for over a year with this Mac. Now, today out of no where, I cannot seem to get it to pair, no matter what I do.

#include <Arduino.h>
#include <BleMouse.h>

BleMouse bleMouse("Apple Magic Mouse", "Apple, Inc.", 74);
bool enable = true;
unsigned long lastMove = millis();
unsigned long currentTime = millis();
unsigned long connectedTime = 0;
unsigned long moveDelay = 5000;
signed int moveDirection = 1;

void setup() {
    Serial.begin(115200);
    Serial.println("Booting...");
    Serial.println("Starting BLE...");
    bleMouse.begin();
}

void loop() {
    currentTime = millis();

    if (!bleMouse.isConnected()) {
        connectedTime = 0;
    }
    if (enable && bleMouse.isConnected() && currentTime - lastMove >= moveDelay) {
        if (connectedTime == 0) {
            connectedTime = currentTime;
        }
        if (currentTime > connectedTime + (10 * 1000)) {
            bleMouse.move(0, moveDirection, 0);
            moveDirection = moveDirection * -1;
            lastMove = currentTime;
            Serial.println("Move Mouse!");
        }
    }
}
dsaul commented 1 year ago

I found the Mac pairing screen had to be open as well. shrug

jslay88 commented 1 year ago

Yeah, I’ve been trying all day :P

On Wed, Jan 4, 2023 at 14:46 Dan Saul @.***> wrote:

I found the Mac pairing screen had to be open as well. shrug

— Reply to this email directly, view it on GitHub https://github.com/T-vK/ESP32-BLE-Mouse/issues/42#issuecomment-1371466153, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABO7UUNULLNUNJV7JDGA5ILWQXVUXANCNFSM53Z6KSKQ . You are receiving this because you commented.Message ID: @.***>

dsaul commented 1 year ago

Looks like you're making a mouse jiggler, here is the one I made: https://github.com/dsaul/ESP32-BLE-ScreenWakeSentinel maybe it'll help.

jslay88 commented 1 year ago

Yeah, I don't know what changed with this laptop today. Works with every other device I have except this one Mac, which it has been paired with exclusively for over a year. Cleared all connected devices, no dice still. Ordered some more boards just in case something weird has gone wrong with this one (even though it connects to everything else just fine).

Anyway, here is what I have been running for a while now, with your wait added in today (will need to use full partition to compile this. Ergo, no OTA).

image

#include <Arduino.h>
#include <BleMouse.h>
#include <WiFi.h>

BleMouse bleMouse("Apple Magic Mouse", "Apple, Inc.", 74);
const char* ssid = "your-ssid";
const char* password = "your-wpa-passcode";

bool enable = true;
unsigned long lastMove = millis();
unsigned long currentTime = millis();
unsigned long connectedTime = 0;
unsigned long moveDelay = 5000;
signed int moveDirection = 1;

WiFiServer server(80);
WiFiClient client;
String header;
String currentLine = "";

void setup() {
    Serial.begin(115200);
    Serial.println("Booting...");
    Serial.println("Starting BLE...");
    bleMouse.begin();
    Serial.print("Connecting WiFi...");
    WiFi.begin(ssid, password);
    server.begin();
}

void loop() {
    currentTime = millis();

    if (!bleMouse.isConnected()) {
        connectedTime = 0;
    }
    if (enable && bleMouse.isConnected() && currentTime - lastMove >= moveDelay) {
        if (connectedTime == 0) {
            connectedTime = currentTime;
        }
        if (currentTime > connectedTime + (10 * 1000)) {
            bleMouse.move(0, moveDirection, 0);
            moveDirection = moveDirection * -1;
            lastMove = currentTime;
            Serial.println("Move Mouse!");
        }
    }

    if (WiFi.status() != WL_CONNECTED) {
        Serial.println(".");
    } else if (client) {
        if (client.connected()) {
            if (client.available()) {  // Read bytes from client
                char c = client.read();
                Serial.write(c);
                header += c;
                if (c == '\n') {
                    if (currentLine.length() == 0) {
                        // Begin Server Response
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-type: text/html");
                        client.println("Connection: close");
                        client.println();

                        if (header.indexOf("POST /") >= 0) {  // Handle change request
                            enable = !enable;
                            if (enable) {
                                bleMouse.move(0, moveDirection * 100, 0);
                                delay(50);
                                bleMouse.move(0, moveDirection * -100, 0);
                            }
                            Serial.print("Enable Toggled: ");
                            Serial.println(enable);
                        }

                        String bleConnectedClass = "red";
                        String enableClass = "green";
                        if (bleMouse.isConnected()) {
                            bleConnectedClass = "green";
                        }
                        if (!enable) {
                            enableClass = "red";
                        }

                        client.println("<!DOCTYPE html><html>");
                        client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
                        client.println("<link rel=\"icon\" href=\"data:,\">"); //  Empty favicon to stop generating requests for it
                        client.println("<style>");
                        client.println("html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center; background-color: #212A2E; color: #F7F8F8; }");
                        client.println(".dot { height: 20px; width: 20px; border-radius: 50%; display: inline-block; }");
                        client.println(".green { background-color: lightgreen; }");
                        client.println(".red { background-color: red; }");
                        client.println("</style>");
                        client.println("<body><h1>Mouse Mover</h1>");
                        client.println("<div>");
                        client.println("<p>BLE Connection: <span class=\"dot " + bleConnectedClass + "\"></span></p>");
                        client.println("<p>Enabled: <span class=\"dot " + enableClass + "\"></span></p>");
                        client.println("<form action=\"\" method=\"post\"><button type=\"submit\">Toggle</button></form>");
                        client.println("</div>");
                        client.println("</body>");
                        client.println("</html>");
                        client.println();

                        // Clean up
                        header = "";
                        client.stop();
                        Serial.println("Client Disconnected!");
                        Serial.println();

                    } else {
                        currentLine = "";
                    }
                } else if (c != '\r') {
                    currentLine += c;
                }
            }
        }
    } else {
        client = server.available();
    }
}
jslay88 commented 1 year ago

I got it working! Pairs flawlessly every time.

I had to switch over to NimBLE, so clearly an issue with the built in library. Didn't need to change any of my code for the transition.

https://github.com/wakwak-koba/ESP32-NimBLE-Mouse

Hope to see this library incorporate NimBLE down the road, as I can now also do OTA updates.

rossiluis22 commented 1 year ago

I'm facing bluetooth disconnection and not able to connected until I do a reset of the ESP32, also tried in a different board, same issue. Is it working properly on your Mac? @jslay88 , could you please help me to get this sort?

this is what I have:

platformio.ini

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:esp-wrover-kit]
platform = espressif32
board = esp-wrover-kit
framework = arduino
board_build.partitions = huge_app.csv
upload_port = /dev/tty.usbserial-0001
monitor_port = /dev/tty.usbserial-0001
monitor_speed = 115200
lib_deps = 
    t-vk/ESP32 BLE Mouse@^0.3.1

src/sentinel.ino

#include <Arduino.h>
#include <BleMouse.h>
#include <WiFi.h>

BleMouse bleMouse("Apple Magic Mouse", "Apple, Inc.", 74);
const char* ssid = "ssid";
const char* password = "pass";

bool enable = true;
unsigned long lastMove = millis();
unsigned long currentTime = millis();
unsigned long connectedTime = 0;
unsigned long moveDelay = 5000;
signed int moveDirection = 1;

WiFiServer server(80);
WiFiClient client;
String header;
String currentLine = "";

void setup() {
    Serial.begin(115200);
    Serial.println("Booting...");
    Serial.println("Starting BLE...");
    bleMouse.begin();
    Serial.print("Connecting WiFi...");
    WiFi.begin(ssid, password);
    server.begin();
}

void loop() {
    currentTime = millis();

    if (!bleMouse.isConnected()) {
        connectedTime = 0;
    }
    if (enable && bleMouse.isConnected() && currentTime - lastMove >= moveDelay) {
        if (connectedTime == 0) {
            connectedTime = currentTime;
        }
        if (currentTime > connectedTime + (10 * 1000)) {
            bleMouse.move(0, moveDirection, 0);
            moveDirection = moveDirection * -1;
            lastMove = currentTime;
            Serial.println("Move Mouse!");
        }
    }

    if (WiFi.status() != WL_CONNECTED) {
        Serial.println(".");
    } else if (client) {
        if (client.connected()) {
            if (client.available()) {  // Read bytes from client
                char c = client.read();
                Serial.write(c);
                header += c;
                if (c == '\n') {
                    if (currentLine.length() == 0) {
                        // Begin Server Response
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-type: text/html");
                        client.println("Connection: close");
                        client.println();

                        if (header.indexOf("POST /") >= 0) {  // Handle change request
                            enable = !enable;
                            if (enable) {
                                bleMouse.move(0, moveDirection * 100, 0);
                                delay(50);
                                bleMouse.move(0, moveDirection * -100, 0);
                            }
                            Serial.print("Enable Toggled: ");
                            Serial.println(enable);
                        }

                        String bleConnectedClass = "red";
                        String enableClass = "green";
                        if (bleMouse.isConnected()) {
                            bleConnectedClass = "green";
                        }
                        if (!enable) {
                            enableClass = "red";
                        }

                        client.println("<!DOCTYPE html><html>");
                        client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
                        client.println("<link rel=\"icon\" href=\"data:,\">"); //  Empty favicon to stop generating requests for it
                        client.println("<style>");
                        client.println("html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center; background-color: #212A2E; color: #F7F8F8; }");
                        client.println(".dot { height: 20px; width: 20px; border-radius: 50%; display: inline-block; }");
                        client.println(".green { background-color: lightgreen; }");
                        client.println(".red { background-color: red; }");
                        client.println("</style>");
                        client.println("<body><h1>Mouse Mover</h1>");
                        client.println("<div>");
                        client.println("<p>BLE Connection: <span class=\"dot " + bleConnectedClass + "\"></span></p>");
                        client.println("<p>Enabled: <span class=\"dot " + enableClass + "\"></span></p>");
                        client.println("<form action=\"\" method=\"post\"><button type=\"submit\">Toggle</button></form>");
                        client.println("</div>");
                        client.println("</body>");
                        client.println("</html>");
                        client.println();

                        // Clean up
                        header = "";
                        client.stop();
                        Serial.println("Client Disconnected!");
                        Serial.println();

                    } else {
                        currentLine = "";
                    }
                } else if (c != '\r') {
                    currentLine += c;
                }
            }
        }
    } else {
        client = server.available();
    }
}
jslay88 commented 1 year ago

Use the NimBLE library I linked above.