I'm trying to pass information between two Arduino Nano 33 BLE devices over bluetooth. I'm able to connect the two devices and see their local names and MAC addresses. I'm also able to discover the server device attributes from the client device.
bleDevice.connected()
is returning true.
When I call the method bleCharacteristic.readValue()
on the client device, it returns nothing. When I call the method bleCharacteristic.canRead()
on the same characteristic object, it returns false.
What can cause bleCharacteristic.canRead() to return false?
So I believe I'm giving it the properties BLERead and BLEWrite.
deviceServiceCharacteristicUuid is a const char* variable that I assigned the UUID I want the characteristic to have.
It turns out I was missing a line in the server device code calling the addCharacteristic() method for my medService service object.
Here is the functioning server device code:
#include <ArduinoBLE.h>
const char* deviceServiceUuid = "19b10000-e8f2-537e-4f6c-d104768a1214";
const char* deviceServiceCharacteristicUuid = "19b10001-e8f2-537e-4f6c-d104768a1214";
BLEService medService(deviceServiceUuid);
BLEByteCharacteristic medName(deviceServiceCharacteristicUuid, BLERead | BLEWrite);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
// begin initialization
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
while (1);
}
BLE.setLocalName("Remi Phone App");
BLE.setDeviceName("Remi Phone App");
BLE.setAdvertisedService(medService);
medService.addCharacteristic(medName); // this was the crit missing line
BLE.addService(medService);
medName.writeValue(1);
BLE.advertise();
Serial.println("Remi Phone App Bluetooth Initialized");
Serial.println(" ");
}
void loop() {
// put your main code here, to run repeatedly:
BLEDevice remiWatch = BLE.central();
if (remiWatch) {
Serial.println("* Connected to Remi Smartwatch!");
Serial.println("* Device MAC Address: ");
Serial.println(remiWatch.address());
Serial.println(" ");
byte med;
unsigned long lastMessage = 0;
while (remiWatch.connected()) {
unsigned long now = millis();
medName.writeValue(1);
medName.readValue(med);
if(now - lastMessage >= 1000) {
lastMessage = now;
Serial.println(med);
}
}
}
}
This outputs the MAC address of the client device it is connected to followed by a steady stream of 1's every second.
Here is the functioning client device code:
#include <ArduinoBLE.h>
const char* deviceServiceUuid = "19b10000-e8f2-537e-4f6c-d104768a1214";
const char* deviceServiceCharacteristicUuid = "19b10001-e8f2-537e-4f6c-d104768a1214";
void setup() {
Serial.begin(9600);
// begin initialization
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
while (1);
}
BLE.setLocalName("Remi Smartwatch");
BLE.setDeviceName("Remi Smartwatch");
BLE.advertise();
Serial.println("Remi Smartwatch Bluetooth Initialized");
Serial.println(" ");
}
void loop() {
// look for the "phone"
Serial.println("Looking for Peripheral Device");
BLE.scanForUuid(deviceServiceUuid);
BLEDevice phone = BLE.available();
phone.connect();
// if a peripheral is found begin communicating
if (phone) {
// confirm phone device details
Serial.println("* Phone found!");
Serial.print("* Phone MAC address: ");
Serial.println(phone.address());
Serial.print("* Phone name: ");
Serial.println(phone.localName());
Serial.print("* Advertised service UUID: ");
Serial.println(phone.advertisedServiceUuid());
Serial.println(" ");
BLE.stopScan();
// discover peripheral attributes
Serial.println("Discovering attributes ...");
if (phone.discoverAttributes()) {
Serial.println("Attributes discovered");
} else {
Serial.println("Attribute discovery failed!");
phone.disconnect();
//return;
}
byte med;
BLECharacteristic medName = phone.characteristic(deviceServiceCharacteristicUuid);
/*
if (!medName) {
Serial.println("no characteristic");
return;
} else if(!medName.canWrite()) {
Serial.println("not writeable");
return;
}
*/
unsigned long lastMessage = 0;
while (phone.connected()) {
// Request information from the peripheral
medName.readValue(med);
unsigned long now = millis();
if (now - lastMessage >= 1000) {
lastMessage = now;
if(medName) {
Serial.println("Can Read");
} else {
Serial.println("Not Reading");
}
Serial.println(med);
}
}
}
}
This, when it connects and is working properly, outputs the MAC address, local name, and advertised service UUID of the server device, then prints that it has discovered the server device attributes, and finally prints a steady alternating stream of "Can Read" and 1 every second.
These sketches can be run on two Arduino Nano 33 BLE devices to connect them and send information over bluetooth.