ArduinoBLE between Nano RP2040 Connect and Nano 33 IoT

As basis I use the LED sketch:

Peripheral (LED) is Nano 33 IoT;
Central is Nano RP2040;

The devices connect successfully, and data is sent.

Nano 33 IoT has also a rotary encoder attached.

Now when the peripheral device ON/OFF receives, I want in case of ON, the central device to be notified about the status of rotary encoder (0x01 - 0xFF).

Until now I found no way to do this.
There are a lot of for ESP32 Controller, but they use eg. pCharacteristic->notify();

But for my devices the function notify() is not available.

And z.B. switchCharacteristic_TX.writeValue((byte)9) doesn’t do anything.

Do you have any suggestions to accomplish the task.

Thanks

Look for this line of code in the Peripheral example...

// BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

What properties does it have... it's Read and Write.

You need to add or change this to Notify.

Then when the central device connects it can register to be notified - you'll then need to add in a callback function in the central code, which will trigger when new data arrives.

Peripheral (LED) advertise()...

BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service
BLEByteCharacteristic switchCharacteristic_RX("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLECharCharacteristic switchCharacteristic_TX("19B10002-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify | BLEIndicate| BLEBroadcast);

Central
// retrieve the LED characteristic
...
Serial.println("Peripheral does have LED characteristic_TX!");
c_TX.setEventHandler(BLEWritten| BLENotify, rec_Written_Hnd);

void rec_Written_Hnd(BLEDevice d, BLECharacteristic c_TX) {
Serial.print("Characteristic event, written: ");
Serial.println("Characteristic received: len=" +
String(c_TX.valueLength()));
const unsigned char* uc = c_TX.value();
Serial.println(*uc);
}
callback function never triggered

Thanks

The central device first has to inform the peripheral device that it wants to be notified before the eventhandler will be triggered by any notification event. I believe this is done by subscribing (or registering) with the characteristic.

There are two functions available. First check if you can subscribe (using canSubscribe()) and if you can subsribe use the subscribe() function to enable notifications.

Please have a look at the ArduinoBLE reference. The setEventHandler is only supported on the peripheral not a central device.

https://www.arduino.cc/en/Reference/ArduinoBLEBLECharacteristicsetEventHandler

As gerrikoio stated for notification to work you need to:

  • declare characteristic on the peripheral with BLENotify
  • the central subscribe to the characteristic
  • the central check the valueUpdated()
  • central call readValue()

Note, BLE is not symmetrical. This is reflected in the function/methods names. When a central writes a characteristic, the value is written on the peripheral. When a peripheral writes a characteristic, the value is updated on the peripheral.

When a central describes to a characteristic, it can choose to read the value when it is updated by the peripheral. The central will get the notification automatically but not the updated value itself. The central needs to read the characteristic. For instance, it could chose to only read the characteristic every hour even if the value is updated every second. This will save battery life and allow a longer lifetime.

To gerrikoio:
It successfully communicates bidirectional.

Thank you very much for your helpful advise.

1 Like