0

I have this issue where I'm transmitting sensor data from Nano Sense Rev 2 (transmitter) board to Nano 33 BLE rev 2 (receiver). The receiver keep failing to detect and connect to the transmitter and is giving me a scan timeout reached stopping scan after scanning for few seconds. Note that I was able to connect to my transmitter using my phone app. This is my transmitter code :

#include <Arduino_LPS22HB.h>
#include <Arduino_HS300x.h>
#include <Arduino_APDS9960.h>
#include <ArduinoBLE.h>
// Custom 128-bit UUIDs for the service and characteristics
BLEService sensorService("12345678-1234-5678-1234-56789abcdef0"); // Custom Service UUID
BLECharacteristic pressureCharacteristic("12345678-1234-5678-1234-56789abcdef1", BLERead | BLENotify, sizeof(float)); // Custom Pressure Characteristic UUID
BLECharacteristic temperatureCharacteristic("12345678-1234-5678-1234-56789abcdef2", BLERead | BLENotify, sizeof(float)); // Custom Temperature Characteristic UUID
BLECharacteristic humidityCharacteristic("12345678-1234-5678-1234-56789abcdef3", BLERead | BLENotify, sizeof(float)); // Custom Humidity Characteristic UUID
BLECharacteristic lightIntensityCharacteristic("12345678-1234-5678-1234-56789abcdef4", BLERead | BLENotify, sizeof(int)); // Custom Light Intensity Characteristic UUID
void setup() {
 // Start Serial Monitor
 Serial.begin(9600);
 while (!Serial);
 // Initialize Sensors
 if (!BARO.begin()) {
 Serial.println("Failed to initialize pressure sensor!");
 while (1);
 }
 if (!HS300x.begin()) {
 Serial.println("Failed to initialize humidity temperature sensor!");
 while (1);
 }
 if (!APDS.begin()) {
 Serial.println("Error initializing APDS9960 sensor.");
 }
 // Initialize BLE
 if (!BLE.begin()) {
 Serial.println("BLE initialization failed!");
 while (1);
 }
 BLE.setLocalName("Nano33BLESense");
 // Add characteristics to the custom service
 sensorService.addCharacteristic(pressureCharacteristic);
 sensorService.addCharacteristic(temperatureCharacteristic);
 sensorService.addCharacteristic(humidityCharacteristic);
 sensorService.addCharacteristic(lightIntensityCharacteristic);
 // Add the service to the BLE peripheral
 BLE.addService(sensorService);
 // Start advertising the BLE service (and repeat to keep it active)
 BLE.advertise();
 Serial.println("BLE Peripheral started advertising.");
}
void loop() {
 // Read sensor data
 float pressure = BARO.readPressure();
 float temperature = HS300x.readTemperature();
 float humidity = HS300x.readHumidity();
 int r, g, b;
 while (!APDS.colorAvailable()) {
 delay(5);
 }
 APDS.readColor(r, g, b);
 int lightIntensity = r + g + b;
 // Print sensor values to the Serial Monitor (for debugging)
 Serial.print("Pressure: ");
 Serial.println(pressure);
 Serial.print("Temperature: ");
 Serial.println(temperature);
 Serial.print("Humidity: ");
 Serial.println(humidity);
 Serial.print("Light Intensity: ");
 Serial.println(lightIntensity);
 // Convert float values to byte arrays
 byte pressureBytes[sizeof(float)];
 memcpy(pressureBytes, &pressure, sizeof(float));
 byte temperatureBytes[sizeof(float)];
 memcpy(temperatureBytes, &temperature, sizeof(float));
 byte humidityBytes[sizeof(float)];
 memcpy(humidityBytes, &humidity, sizeof(float));
 byte lightIntensityBytes[sizeof(int)];
 memcpy(lightIntensityBytes, &lightIntensity, sizeof(int));
 // Update BLE characteristics with the latest sensor data
 pressureCharacteristic.setValue(pressureBytes, sizeof(pressureBytes));
 temperatureCharacteristic.setValue(temperatureBytes, sizeof(temperatureBytes));
 humidityCharacteristic.setValue(humidityBytes, sizeof(humidityBytes));
 lightIntensityCharacteristic.setValue(lightIntensityBytes, sizeof(lightIntensityBytes));
 // The BLE library will automatically handle notifications when `setValue` is called
 // since BLENotify is enabled on the characteristics.
 // Keep advertising to make sure the BLE service stays visible
 BLE.advertise();
 
 delay(1000); // Wait for 1 second before sending the next data
}

and this is the receiver code:

#include <ArduinoBLE.h>
// Define the UUIDs for the custom service and characteristics
#define SENSOR_SERVICE_UUID "12345678-1234-5678-1234-56789abcdef0"
#define PRESSURE_CHAR_UUID "12345678-1234-5678-1234-56789abcdef1"
#define TEMPERATURE_CHAR_UUID "12345678-1234-5678-1234-56789abcdef2"
#define HUMIDITY_CHAR_UUID "12345678-1234-5678-1234-56789abcdef3"
#define LIGHT_INTENSITY_CHAR_UUID "12345678-1234-5678-1234-56789abcdef4"
// Declare BLE objects with proper UUIDs
BLEService sensorService(SENSOR_SERVICE_UUID);
BLECharacteristic pressureCharacteristic(PRESSURE_CHAR_UUID, BLERead | BLENotify, sizeof(float));
BLECharacteristic temperatureCharacteristic(TEMPERATURE_CHAR_UUID, BLERead | BLENotify, sizeof(float));
BLECharacteristic humidityCharacteristic(HUMIDITY_CHAR_UUID, BLERead | BLENotify, sizeof(float));
BLECharacteristic lightIntensityCharacteristic(LIGHT_INTENSITY_CHAR_UUID, BLERead | BLENotify, sizeof(int));
unsigned long scanStartTime;
bool scanInProgress = true;
int maxScanAttempts = 5; // Max number of scan attempts before stopping
int scanAttempts = 0; // Counter for scan attempts
void setup() {
 // Start Serial Monitor
 Serial.begin(9600);
 while (!Serial);
 // Initialize BLE
 if (!BLE.begin()) {
 Serial.println("BLE initialization failed!");
 while (1);
 }
 BLE.setLocalName("BLEReceiver");
 Serial.println("BLEReceiver started. Scanning for devices...");
 // Start scanning for devices advertising the sensor service
 BLE.scanForUuid(SENSOR_SERVICE_UUID); // Scan for the service
 scanStartTime = millis(); // Start the scan timer
}
void loop() {
 BLEDevice central = BLE.available();
 
 if (central) {
 // Device found, print address and attempt to connect
 Serial.print("Found BLE Device: ");
 Serial.println(central.address());
 // Stop scanning and attempt to connect
 BLE.stopScan();
 delay(100); // Small delay before attempting to connect
 if (central.connect()) {
 Serial.println("Connected to device.");
 BLEService sensorService = central.service(SENSOR_SERVICE_UUID);
 if (sensorService) {
 Serial.println("Sensor service found.");
 // Discover characteristics
 pressureCharacteristic = sensorService.characteristic(PRESSURE_CHAR_UUID);
 temperatureCharacteristic = sensorService.characteristic(TEMPERATURE_CHAR_UUID);
 humidityCharacteristic = sensorService.characteristic(HUMIDITY_CHAR_UUID);
 lightIntensityCharacteristic = sensorService.characteristic(LIGHT_INTENSITY_CHAR_UUID);
 if (pressureCharacteristic && temperatureCharacteristic && humidityCharacteristic && lightIntensityCharacteristic) {
 Serial.println("Characteristics found. Reading values...");
 while (central.connected()) {
 if (pressureCharacteristic.canRead()) {
 float pressure;
 memcpy(&pressure, pressureCharacteristic.value(), sizeof(pressure));
 Serial.print("Pressure: ");
 Serial.println(pressure);
 }
 if (temperatureCharacteristic.canRead()) {
 float temperature;
 memcpy(&temperature, temperatureCharacteristic.value(), sizeof(temperature));
 Serial.print("Temperature: ");
 Serial.println(temperature);
 }
 if (humidityCharacteristic.canRead()) {
 float humidity;
 memcpy(&humidity, humidityCharacteristic.value(), sizeof(humidity));
 Serial.print("Humidity: ");
 Serial.println(humidity);
 }
 if (lightIntensityCharacteristic.canRead()) {
 int lightIntensity;
 memcpy(&lightIntensity, lightIntensityCharacteristic.value(), sizeof(lightIntensity));
 Serial.print("Light Intensity: ");
 Serial.println(lightIntensity);
 }
 delay(1000); // Wait for 1 second before reading again
 }
 } else {
 Serial.println("Failed to find required characteristics.");
 }
 } else {
 Serial.println("Sensor service not found.");
 }
 // Disconnect once done
 central.disconnect();
 Serial.println("Disconnected from device.");
 scanAttempts = 0; // Reset scan attempts after successful connection
 } else {
 Serial.println("Failed to connect to device.");
 }
 }
 // Check scan timeout and limit scan attempts
 if (scanInProgress && millis() - scanStartTime > 10000) { // 10 seconds timeout
 Serial.println("Scan timeout reached. Stopping scan.");
 BLE.stopScan();
 scanInProgress = false;
 scanAttempts++;
 // If max scan attempts reached, stop scanning and wait for user intervention
 if (scanAttempts >= maxScanAttempts) {
 Serial.println("Max scan attempts reached. Please reset the device.");
 } else {
 Serial.println("Resuming scan...");
 BLE.scanForUuid(SENSOR_SERVICE_UUID); // Restart scanning after timeout
 scanStartTime = millis(); // Reset the scan timer
 scanInProgress = true; // Set scanInProgress back to true
 }
 }
 // Continue scanning only if it is still ongoing and hasn't timed out
 if (scanInProgress && !central) {
 BLEDevice central = BLE.available();
 }
}

The two units are withing 1 meter of each others. and this is my serial monitor (receiver).

14:52:23.321 -> Resuming scan...
14:52:33.314 -> Scan timeout reached. Stopping scan.
14:52:33.314 -> Resuming scan...
14:52:43.338 -> Scan timeout reached. Stopping scan.
14:52:43.387 -> Resuming scan...
14:52:53.379 -> Scan timeout reached. Stopping scan.
14:52:53.425 -> Max scan attempts reached. Please reset the device.

Why can I not connect?

asked Feb 19 at 20:01
4
  • what is your question? Commented Feb 19 at 22:35
  • Did you make a serial connection to both at the same time during your tests? Commented Feb 19 at 23:26
  • @timemage Yes I connected them to a separate computer simultaneously and at different times to make sure I targeted the advertising window. Commented Feb 20 at 1:48
  • By default, the ArduinoBLE library uses random private addresses. This may cause devices not to detect each other consistently. Commented Feb 20 at 20:44

1 Answer 1

1

The lack of a BLE.setAdvertisedService(sensorService); is the thing you are immediately encountering. In testing I placed it like in the following snippet:

 // Add the service to the BLE peripheral
 BLE.addService(sensorService);
 // Include service of interest in advertising data
 // fo the other side to use with `BLE.scanForUuid(SENSOR_SERVICE_UUID);`
 BLE.setAdvertisedService(sensorService);

With this change, the receiver side now reports:

BLEReceiver started. Scanning for devices...
Found BLE Device: xx:xx:xx:xx:xx:xx
Connected to device.
Sensor service not found.
Disconnected from device.

... where xx contained my Nano BLE's OUI.

In short when you call BLE.advertise(); your device begins broadcasting its existence. It can do this with a small amount of advertising data that can include some (usually not all) of its service UUIDs. An advertised service is what BLE.scanForUuid(SENSOR_SERVICE_UUID); is looking for. Until you communicate with the device (beyond just receiving its advertising) you can't know about any services not included in the advertising data. So, without the advertised service UUID you would need to further interrogate each device found as part of a non-UUID based .scan() session. So, these advertised service UUIDs make scanning for what you want is more efficient.


In the receiver code you have BLEDevice central = BLE.available(); .available() here returns the peripheral found during the scan. Really this should be BLEDevice peripheral = . Anyway, after the call to .connect() you're using .service(). There's a step missing here which you can see in this documentation and this example. Until you .discoverAttributes() you won't have a local copy of all the services, characteristics, etc. that the peripheral has. Which is why .service() is failing.

I don't doubt there are more problems. This looks like the sort of thing an AI code generator would produce. If that is what's going on, stop and read the documentation and examples.

answered Feb 20 at 2:55
2
  • ok, I will try that tomorrow. By the way did you not implement any services? is that the reason it says "Sensor service not found" or is that a different issue? Commented Feb 20 at 3:40
  • I'm putting something in there to address that part now. But, the answer, as is, addresses "the thing you are immediately encountering". In other words, the first of potentially many problems you are having. That finding the device at all. I'm not going to fix your whole project. Commented Feb 20 at 3:42

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.