Hello guys, i am using two NANO 33 SENSE to communicate each other with BLE, followed by the tutorial https://docs.arduino.cc/tutorials/nano-33-ble-sense/ble-device-to-device it is easy to have the gesture monitored, I then have the peripheral device get an analog signal from an IR sensor, and I add an IR characteristic under the gesture service.
I use bleCharacteristic.writeValue() to update IR sensor value on peripheral device and bleCharacteristic.valueUpdated() on cnetral device. I can see from peripheral device serial print that the data is always updating, but on cnetral device the bleCharacteristic.valueUpdated() just doesn't work.
Can anyone see what's going on here? THX.
/*
BLE_Peripheral.ino
This program uses the ArduinoBLE library to set-up an Arduino Nano 33 BLE
as a peripheral device and specifies a service and a characteristic. Depending
of the value of the specified characteristic, an on-board LED gets on.
The circuit:
- Arduino Nano 33 BLE.
This example code is in the public domain.
*/
#include <ArduinoBLE.h>
#include <Servo.h>
#include <SharpIR.h>
// Define IR model and input pin:
#define IRPin A0
#define model 1080 // not use, use SharpIR myIRSensor(SharpIR::GP2Y0A21YK0F, IRPin); instead
Servo myservo;
// Create a new instance of the SharpIR class:
SharpIR myIRSensor(SharpIR::GP2Y0A21YK0F, IRPin);
const char* deviceServiceUuid_1 = "ecef0000-8671-4730-a18d-dc6262f78a27";
const char* deviceServiceCharacteristicUuid_1 = "ecef0001-8671-4730-a18d-dc6262f78a27";
const char* deviceServiceCharacteristicUuid_2 = "ecef0002-8671-4730-a18d-dc6262f78a27";
BLEService gestureService(deviceServiceUuid_1);
BLEByteCharacteristic gestureCharacteristic(deviceServiceCharacteristicUuid_1, BLERead | BLEWrite);
BLEUnsignedCharCharacteristic IR_distance_Characteristic(deviceServiceCharacteristicUuid_2, BLERead | BLENotify | BLEBroadcast);
int gesture = -1;
int old_IR_Distance = 10; // last distance reading from analog input
long previousMillis = 0; // last time the distance was checked, in ms
int servo_position_1 = 96;
int servo_position_2 = 136;
int i = 1;
enum {
GESTURE_NONE = -1,
GESTURE_UP = 0,
GESTURE_DOWN = 1,
GESTURE_LEFT = 2,
GESTURE_RIGHT = 3
};
void setup() {
Serial.begin(9600);
while (!Serial);
// Use D12 pin of [NANO 33 SENSE BLE] as servo drive pin;
myservo.attach(D12);
for (i = 90; i < 180; i++) {
myservo.write(i);
delay(100);
}
pinMode(LEDR, OUTPUT);
pinMode(LEDG, OUTPUT);
pinMode(LEDB, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LEDR, HIGH);
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, HIGH);
digitalWrite(LED_BUILTIN, LOW);
if (!BLE.begin()) {
Serial.println("- Starting Bluetooth® Low Energy module failed!");
while (1);
}
BLE.setLocalName("Range Detect on Arduino Nano 33 BLE (Peripheral)");
BLE.setAdvertisedService(gestureService);
gestureService.addCharacteristic(gestureCharacteristic);
gestureService.addCharacteristic(IR_distance_Characteristic);
BLE.addService(gestureService);
gestureCharacteristic.writeValue(-1); // set initial value for this characteristic
IR_distance_Characteristic.writeValue(old_IR_Distance); // set initial value for this characteristic
// start advertising
BLE.advertise();
Serial.println("Nano 33 BLE (Peripheral Device)");
Serial.println(" ");
}
void loop() {
// wait for a Bluetooth® Low Energy central
BLEDevice central = BLE.central();
Serial.println("- Discovering central device...");
delay(500);
// if a central is connected to the peripheral:
if (central) {
Serial.println("* Connected to central device!");
Serial.print("* Device MAC address: ");
Serial.println(central.address());
Serial.println(" ");
while (central.connected()) {
if (gestureCharacteristic.written()) {
gesture = gestureCharacteristic.value();
writeGesture(gesture);
}
long currentMillis = millis();
// if 200ms have passed, check the distance:
if (currentMillis - previousMillis >= 1000) {
previousMillis = currentMillis;
updateDistance();
}
}
Serial.print("* Disconnected to central device: ");
Serial.println(central.address());
}
}
void writeGesture(int gesture) {
Serial.println("- Characteristic <gesture_type> has changed!");
switch (gesture) {
case GESTURE_UP:
Serial.println("* Actual value: UP (red LED on)");
Serial.println(" ");
digitalWrite(LEDR, LOW);
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, HIGH);
digitalWrite(LED_BUILTIN, LOW);
myservo.write(servo_position_1);
break;
case GESTURE_DOWN:
Serial.println("* Actual value: DOWN (green LED on)");
Serial.println(" ");
digitalWrite(LEDR, HIGH);
digitalWrite(LEDG, LOW);
digitalWrite(LEDB, HIGH);
digitalWrite(LED_BUILTIN, LOW);
myservo.write(servo_position_1);
break;
case GESTURE_LEFT:
Serial.println("* Actual value: LEFT (blue LED on)");
Serial.println(" ");
digitalWrite(LEDR, HIGH);
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, LOW);
digitalWrite(LED_BUILTIN, LOW);
myservo.write(servo_position_2);
break;
case GESTURE_RIGHT:
Serial.println("* Actual value: RIGHT (built-in LED on)");
Serial.println(" ");
digitalWrite(LEDR, HIGH);
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, HIGH);
digitalWrite(LED_BUILTIN, HIGH);
myservo.write(servo_position_2);
break;
default:
digitalWrite(LEDR, HIGH);
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, HIGH);
digitalWrite(LED_BUILTIN, LOW);
myservo.write(servo_position_1);
break;
}
}
void updateDistance() {
/* Read the current range distance on the A0 analog input pin.
This is used here to simulate the charge level of a battery.
*/
int range = myIRSensor.getDistance();
if (range != old_IR_Distance) { // if the distance has changed
Serial.print("Distance is now: "); // print it
Serial.println(range);
IR_distance_Characteristic.writeValue(range); // and update the battery level characteristic
IR_distance_Characteristic.broadcast();
old_IR_Distance = range; // save the level for next comparison
}
}
/*
BLE_Central_Device.ino
This program uses the ArduinoBLE library to set-up an Arduino Nano 33 BLE Sense
as a central device and looks for a specified service and characteristic in a
peripheral device. If the specified service and characteristic is found in a
peripheral device, the last detected value of the on-board gesture sensor of
the Nano 33 BLE Sense, the APDS9960, is written in the specified characteristic.
The circuit:
- Arduino Nano 33 BLE Sense.
This example code is in the public domain.
*/
#include <ArduinoBLE.h>
#include <Arduino_APDS9960.h>
const char* deviceServiceUuid_1 = "ecef0000-8671-4730-a18d-dc6262f78a27";
const char* deviceServiceCharacteristicUuid_1 = "ecef0001-8671-4730-a18d-dc6262f78a27";
const char* deviceServiceCharacteristicUuid_2 = "ecef0002-8671-4730-a18d-dc6262f78a27";
int gesture = -1;
int oldGestureValue = -1;
const uint8_t* IR_distance;
void setup() {
Serial.begin(9600);
while (!Serial);
if (!APDS.begin()) {
Serial.println("* Error initializing APDS9960 sensor!");
}
APDS.setGestureSensitivity(80);
if (!BLE.begin()) {
Serial.println("* Starting Bluetooth® Low Energy module failed!");
while (1);
}
BLE.setLocalName("Nano 33 BLE (Central)");
BLE.advertise();
Serial.println("Arduino Nano 33 BLE Sense (Central Device)");
Serial.println(" ");
BLE.scan();
}
void loop() {
connectToPeripheral();
}
void connectToPeripheral() {
BLEDevice peripheral;
Serial.println("- Discovering peripheral device...");
do
{
BLE.scanForUuid(deviceServiceUuid_1);
peripheral = BLE.available();
} while (!peripheral);
if (peripheral) {
Serial.println("* Peripheral device found!");
Serial.print("* Device MAC address: ");
Serial.println(peripheral.address());
Serial.print("* Has local name? ");
Serial.println(peripheral.hasLocalName());
Serial.print("* Device name: ");
Serial.println(peripheral.localName());
Serial.print("* Advertised service UUID: ");
Serial.println(peripheral.advertisedServiceUuid());
Serial.println(" ");
//if (peripheral.localName() == "Range Detect on Arduino Nano 33 BLE (Peripheral)") {
if (peripheral.advertisedServiceUuid() == deviceServiceUuid_1) {
// stop scanning
BLE.stopScan();
controlPeripheral(peripheral);
}
}
}
void controlPeripheral(BLEDevice peripheral) {
// connect to the peripheral
Serial.println("- Connecting to peripheral device...");
if (peripheral.connect()) {
Serial.println("* Connected to peripheral device!");
Serial.println(" ");
} else {
Serial.println("* Connection to peripheral device failed!");
Serial.println(" ");
return;
}
// discover peripheral attributes
Serial.println("- Discovering peripheral device attributes...");
if (peripheral.discoverService(deviceServiceUuid_1)) {
Serial.println("* Peripheral device attributes discovered!");
Serial.println(" ");
} else {
Serial.println("* Peripheral device attributes discovery failed!");
Serial.println(" ");
peripheral.disconnect();
while (1);
return;
}
// retrieve the characteristics
BLECharacteristic gestureCharacteristic = peripheral.characteristic(deviceServiceCharacteristicUuid_1);
BLECharacteristic IR_distance_Characteristic = peripheral.characteristic(deviceServiceCharacteristicUuid_2);
if (!gestureCharacteristic) {
Serial.println("* Peripheral device does not have gesture_type characteristic!");
peripheral.disconnect();
return;
} else if (!gestureCharacteristic.canWrite()) {
Serial.println("* Peripheral does not have a writable gesture_type characteristic!");
peripheral.disconnect();
return;
}
if (!IR_distance_Characteristic) {
Serial.println("* Peripheral device does not have IR_distance_type characteristic!");
peripheral.disconnect();
return;
}
else if (!IR_distance_Characteristic.canSubscribe()) {
Serial.println("* IR_distance_Characteristic is not subscribable!");
peripheral.disconnect();
return;
}
else if (!IR_distance_Characteristic.subscribe()) {
Serial.println("subscription failed!");
peripheral.disconnect();
return;
}
else {
Serial.println("Subscribed");
Serial.println("Press the right and left buttons on your SensorTag.");
}
while (peripheral.connected()) {
gesture = gestureDetectection();
if (oldGestureValue != gesture) {
oldGestureValue = gesture;
Serial.print("* Writing value to gesture_type characteristic: ");
Serial.println(gesture);
gestureCharacteristic.writeValue((byte)gesture);
Serial.println("* Writing value to gesture_type characteristic done!");
Serial.println(" ");
}
if (IR_distance_Characteristic.valueUpdated()) {
byte IR_distance = 0;
IR_distance_Characteristic.readValue(IR_distance);
Serial.print("incoming data is : ");
Serial.println(IR_distance);
}
}
Serial.println(" - Peripheral device disconnected!");
}
int gestureDetectection() {
if (APDS.gestureAvailable()) {
gesture = APDS.readGesture();
switch (gesture) {
case GESTURE_UP:
Serial.println(" - UP gesture detected");
break;
case GESTURE_DOWN:
Serial.println(" - DOWN gesture detected");
break;
case GESTURE_LEFT:
Serial.println(" - LEFT gesture detected");
break;
case GESTURE_RIGHT:
Serial.println(" - RIGHT gesture detected");
break;
default:
Serial.println(" - No gesture detected");
break;
}
}
return gesture;
}