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?
-
what is your question?jsotola– jsotola02/19/2025 22:35:05Commented Feb 19 at 22:35
-
Did you make a serial connection to both at the same time during your tests?timemage– timemage02/19/2025 23:26:35Commented 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.Anwar Elhadad– Anwar Elhadad02/20/2025 01:48:01Commented Feb 20 at 1:48
-
By default, the ArduinoBLE library uses random private addresses. This may cause devices not to detect each other consistently.liaifat85– liaifat8502/20/2025 20:44:24Commented Feb 20 at 20:44
1 Answer 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.
-
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?Anwar Elhadad– Anwar Elhadad02/20/2025 03:40:11Commented 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.timemage– timemage02/20/2025 03:42:36Commented Feb 20 at 3:42
Explore related questions
See similar questions with these tags.