ITPNYU / p5.ble.js

A Javascript library that enables communication between BLE devices and a p5 sketch using Web Bluetooth API. https://itpnyu.github.io/p5ble-website.
MIT License
41 stars 29 forks source link

Connecting on ESP32 #5

Open bigrig2212 opened 4 years ago

bigrig2212 commented 4 years ago

Hi there. Love this library!! Just trying to get it to work with ESP32. No luck connecting to advertised service UUID.

On my phone using the BLE Scanner app, I can see and connect to my service. But don't see the service listed from browser using myBLE.connect(serviceUuid, gotCharacteristics). Just hangs and says "no compatible devices found."

The code for ESP32 is quite different from your sample code for Arduino, but at the end of the day, it advertises a serviceUUID and that's confirmed working... so don't think there's too much to go wrong.

Bug? Or am I doing something wrong? Does it need something else in that ArduinoBLE.h library? (I'm not using that library). I'm using:

include

include

include

bigrig2212 commented 4 years ago

here's the esp32 code running on the device. ble.esp32.txt

bigrig2212 commented 4 years ago

Was hoping it might be an SSL issue... but just set up Ngrok and hit it via https and no luck seeing the service with that approach either.

bigrig2212 commented 4 years ago

I do see it using the device using the code here: https://googlechrome.github.io/samples/web-bluetooth/device-info.html?allDevices=true

bigrig2212 commented 4 years ago

Ok, figured it out. Maybe the spec changed but in your connect function on line 21, you're filtering by by "services" - which is not the same as a UUID. It's expecting the name of a service there like 'battery_service'...

Seems like you want to filter by name instead - and pass that in as a param as well. like:

  connect(serviceUuid, serviceName, callback) {
    const options = {
      filters: [{
        namePrefix: [serviceName],
      }],
    };
bigrig2212 commented 4 years ago

oh, interestingly, now that i've connected successfully, i can also connect successfully from your example at https://itpnyu.github.io/p5ble-website/docs/connect-disconnect (i used your same UUID). I wonder if this is why you may not have noticed that it wasn't working??... maybe it gets cached in some way... and then bypasses the filters?

bigrig2212 commented 4 years ago

Nope, scratch that - it only shows up on https://itpnyu.github.io/p5ble-website/docs/connect-disconnect if I'm currently paired with it using my modified connect script. If I disconnect there, it doesn't work again on your example site.

bigrig2212 commented 4 years ago

On further experimentation, the UUID still needs to be in the options as so:

  connect(serviceUuid, serviceName, callback) {
    const options = {
      filters: [{
        namePrefix: [serviceName],
      }],
      optionalServices: [serviceUuid]
    };
yining1023 commented 4 years ago

Hi @bigrig2212, thank you for reporting the issue! I'd love to make it working with ESP32.

I think passing serviceUuid as services intofilters should also work. In this Web Bluetooth example, it's checking if serviceUuid.startsWith('0x'), then it will read it as an integer, and then pass it to filters:

navigator.bluetooth.requestDevice({filters: [{services: [serviceUuid]}]})

If on your phone in the BLE Scanner app, you can see and connect to your service, then p5 sketch should be able to find your device. When you are running the p5 sketch, you just need to change the serviceUuid here. What is your service uuid? Does it have same format like:

const serviceUuid = "e1132322-a39d-45be-8db0-16983b2a4fe3";
const serviceUuid = "19b10010-e8f2-537e-4f6c-d104768a1214";
krdarrah commented 4 years ago

Not sure if it applies or not, but one thing I had to do was add this to the ESP32 example:
// Create the BLE Service BLEService *pService = pServer->createService(SERVICE_UUID); pServer->getAdvertising()->addServiceUUID(SERVICE_UUID);

mjvo commented 4 years ago

I've successfully been able to get p5.ble to read a characteristic using an ESP32. Here's the Arduino code:

/*
    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleWrite.cpp
    Ported to Arduino ESP32 by Evandro Copercini
*/

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID        "19b10000-e8f2-537e-4f6c-d104768a1214"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();
      if (value == "on"){
        digitalWrite(LED_BUILTIN, HIGH);
      }
      else {
        digitalWrite(LED_BUILTIN, LOW);
      }
      if (value.length() > 0) {
        Serial.println("*********");
        Serial.print("New value: ");
        for (int i = 0; i < value.length(); i++)
          Serial.print(value[i]);

        Serial.println();
        Serial.println("*********");
      }
    }
};

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println("1- Download and install an BLE scanner app in your phone");
  Serial.println("2- Scan for BLE devices in the app");
  Serial.println("3- Connect to MyESP32");
  Serial.println("4- Go to CUSTOM CHARACTERISTIC in CUSTOM SERVICE and write something");
  Serial.println("5- See the magic =)");

  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->setValue("water");
  pService->start();
  // BLEAdvertising *pAdvertising = pServer->getAdvertising();  // this still is working for backward compatibility
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);
}

However, I cannot get p5.ble to successfully write to the same characteristic. The ESP32 triggers the callback but the value is empty (?). The serial monitor writes:

*********
New value: 
*********

I can connect to the ESP32 with an app like nRF Connect on my Android phone and successfully write a text string to the characteristic.

Any ideas welcome.

FilippoCinotti commented 3 years ago

Hey, I am having the same issue with ESP32 connection with chrome... have you found a solution? Can you provide a solution for the web app?

todocono commented 3 years ago

@FilippoCinotti , @mjvo the incoming information will be interpreted as ASCII. Try sending a number 65 and you should see a letter 'A'.

UNIST-Interactions commented 3 years ago

FWIW, I was only to successfully write bytes from p5.ble to an Adafruit Bluefruit LE SPI Friend. In order to write strings, I modified lines 104-106 of p5.ble.js (in the write function) as follows:

const bufferToSend = Uint8Array.of(inputValue);
console.log(`Writing ${inputValue} to Characteristic...`);
return characteristic.writeValue(bufferToSend);

to

let encoder = new TextEncoder('utf-8');
console.log(`Writing ${inputValue} to Characteristic...`);
characteristic.writeValueWithoutResponse(encoder.encode(inputValue));

Great lib!

Kei1yn commented 3 years ago

The strange thing is it works on Android. It runs perfectly. But once I do try it on PC (OS does not matter) it will not find the ESP32.

vanminh0910 commented 2 years ago

I have same issue. The p5.ble.js cannot find my ESP32 BLE device but other mobile apps like Bluefruit BLE Connect can find and connect without any issue.