My intended solution is now running.
I have started from scratch and wrote new code.
First I had the same problem as before.
I was then able to slowly approach the error.
The main reason was in the readAnemometer() function.
I deactivated the function, without this call, both Nano 33 BLE were able to find the attributes.
When I activated the function again, the attributes could'nt longer found.
The additional command "if(central.connected())" solved the problem.
Result:
Everything works as expected.
The Arduino Nano 33 IoT works as a peripheral device.
The two Nano 33 BLE as central devices. Both can connect and can now also receive the changed values.
I'm happy now.
Below my code.
Thank you very much for your help and support.
Code for peripheral device
#include <Arduino.h>
#include <ArduinoBLE.h>
#define serviceUUID "181A" // Service - Environmental Sensing Service
#define charactUUID "2A70" // Characteristics - True Wind Speed
const char* d_service_Name = serviceUUID; // Service - Environmental Sensing Service
const char* d_characteristics_Name = charactUUID; // Characteristics - True Wind Speed
BLEService environmentalService(d_service_Name); // Bluetoothยฎ Low Energy Binary Sensor Service
BLECharCharacteristic wspch(d_characteristics_Name, BLERead | BLENotify);
BLEDevice central;
int oldWindSpeedLevel = 0; // last Wind Speed level reading from Anemometer
long previousMillis = 0; // last Wind Speed level was checked in before x millis
const int mds = 5; // measure duration in seconds
const float mts = 2.5; // max Anemometer turns per second
const int pinReedSensor = 8 ; // REED Sensorport (Anemometer)
const int bleConnectStatusLED = 7;
int numberOfConnectedCentral = 0;
//int pauseAfterWindMeasure = 30 * 1000; // Pause after wind measurement in millis (sec * 1000= msec)
//unsigned long startMeasurePause = millis();
//unsigned long endMeasurePause = startMeasurePause + pauseAfterWindMeasure;
//โโโโโ Function declarations โโโโโ
float readAnemometer();
String iif(bool check, String rString1, String rString2);
int iif(bool check, int value1, int value2);
void blePeripheralConnectHandler( BLEDevice central );
void blePeripheralDisconnectHandler( BLEDevice central );
void characteristicsUpdated(BLEDevice central, BLECharacteristic changedChar);
String timeSinceStart();
void setup() {
unsigned long sMillis = millis(); // sMillis = startMillis
Serial.begin(115200); // Start communication with serial interface
while (!Serial && millis() < (sMillis + 5000)); // When running on battery, serial communication is not possible
pinMode(bleConnectStatusLED,OUTPUT);
pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected
pinMode(pinReedSensor, INPUT_PULLDOWN);
Serial.println("Peripheral");
Serial.println(" ____ _ _ _ ");
Serial.println(" | _ \\ ___ _ __(_)_ __ | |__ ___ _ __ __ _| | ");
Serial.println(" | |_) / _ \\ '__| | '_ \\| '_ \\ / _ \\ '__/ _` | | ");
Serial.println(" | __/ __/ | | | |_) | | | | __/ | | (_| | | ");
Serial.println(" |_| \\___|_| |_| .__/|_| |_|\\___|_| \\__,_|_| ");
Serial.println(" |_| ");
while (!BLE.begin())
{
digitalWrite(LED_BUILTIN,HIGH); delay(200);
digitalWrite(LED_BUILTIN,LOW); delay(200);
}
BLE.setEventHandler( BLEConnected, blePeripheralConnectHandler);
BLE.setEventHandler( BLEDisconnected, blePeripheralDisconnectHandler);
BLE.setLocalName("Anemometer");
BLE.setAdvertisedService(environmentalService); // add the service UUID
environmentalService.addCharacteristic(wspch); // add the windLevel characteristic
BLE.addService(environmentalService); // Add the Enviromental service
wspch.writeValue(oldWindSpeedLevel); // set initial value for this characteristic
Serial.println("Bluetoothยฎ device active, waiting for connections...");
BLE.advertise(); // start advertising
}
void loop()
{
static int windLevel = 0;
static int oldWindLevel = 0;
BLE.advertise(); // start advertising
central = BLE.central(); // wait for a Bluetoothยฎ Low Energy central
delay(500); // important
if(central.connected())
{
delay(300);
long currentMillis = millis();
// check the wind level evey 5 seconds:
if (currentMillis - previousMillis >= 5000) {
previousMillis = currentMillis;
windLevel = readAnemometer();
if(oldWindLevel != windLevel)
{
wspch.writeValue(windLevel);
oldWindLevel = windLevel;
}
}
}
}
float readAnemometer()
{
int newState = 0;
int oldState = 0;
int windCounter = 0;
float windSpeedLevel = 0; // or HIGH
unsigned long endTime ;
endTime = millis() + (mds * 1000);
digitalWrite(LED_BUILTIN, HIGH); delay(100);
digitalWrite(LED_BUILTIN, LOW); delay(100);
digitalWrite(LED_BUILTIN, HIGH); delay(100);
digitalWrite(LED_BUILTIN, LOW); delay(100);
if(central.connected()) // <โโโโโโ after inserted the if-command, it works โโโโ
{
while (endTime > millis() ) // Query the anemometer mds seconds
{
newState = digitalRead(pinReedSensor);
if(oldState == 0 && newState == 1) // With each revolution, newState is set to HIGH when the REED sensor is activated.
{ windCounter++; }
oldState = newState;
}
windSpeedLevel = iif(windCounter > (mts * mds),1,0);
Serial.print(windCounter); Serial.print(") Wind Speed is ");Serial.println(iif(windSpeedLevel == 1,"HIGH","LOW"));
}
return windSpeedLevel;
}
String iif(bool check, String rString1, String rString2)
{
String rValue = rString2;
if (check)
{
rValue = rString1;
}
return rValue;
}
int iif(bool check, int value1, int value2)
{
int rValue = value2;
if (check)
{
rValue = value1;
}
return rValue;
}
void blePeripheralConnectHandler( BLEDevice central )
{
digitalWrite(bleConnectStatusLED,HIGH);
numberOfConnectedCentral++;
Serial.print( F ( " Connected to central: " ) );
Serial.println( central.address() );
}
void blePeripheralDisconnectHandler( BLEDevice central )
{
// digitalWrite( LED_BUILTIN, LOW );
numberOfConnectedCentral--;
if(numberOfConnectedCentral < 1)
{
digitalWrite(bleConnectStatusLED,LOW);
}
Serial.print( F( " Disconnected from central: " ) );
Serial.println( central.address() );
}
void characteristicsUpdated(BLEDevice central, BLECharacteristic changedChar)
{
Serial.print("Characteristic updated. UUID: ");
Serial.print(changedChar.uuid());
Serial.print(" value: ");
byte incoming = 0;
changedChar.readValue(incoming);
Serial.println(incoming);
}
String timeSinceStart()
{
char text[20];
unsigned int secondsSinceStart = millis()/1000;
// Serial.println("currentMillis");Serial.println(secondsSinceStart);
unsigned int seconds = secondsSinceStart % 60;
unsigned int minutes = (secondsSinceStart - seconds) / 60;
sprintf(text, "%d:%02d", minutes,seconds);
return text;
}
Code for central device
#include <Arduino.h>
#include <ArduinoBLE.h> // Bluetooth-Library laden
#include <Wire.h>
/* The Reason for adding Wire.h was this error message
* ***************************************************
* #include "Wire.h"
* ^~~~~~~~
* compilation terminated.
* *** [.pio\build\nano33ble\libd80\Arduino_BMI270_BMM150\BMI270.cpp.o] Error 1
*/
#define RGBLedOn LOW // this LED's are inverted
#define RGBLedOff HIGH // this LED's are inverted
// โโโโโ BlueTooth โโโโโโโโโโโโโโโโโโโโโโโโโ
#define serviceName BLESrvUuidBat // BLE_Service_UUID_Battery
#define charactName BLEChrUuidBatLvl // BLE_Characteristics_UUDI_BatteryLevel
#define serviceUUID "181A" // 181A Service - Environmental Sensing Service
#define charactUUID "2A70" // Characteristics - True Wind Speed
const char* serviceName = serviceUUID; // Service - Environmental Sensing Service
const char* charactName = charactUUID; // Characteristics - True Wind Speed
BLEDevice peripheral;
BLECharacteristic wspch;
//โโโโโ Function declarations โโโโโ
void startBLE();
void searchPeripheral();
void searchAttribute();
void hourGlass();
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
unsigned long sMillis = millis(); // sMillis = startMillis
Serial.begin(115200); // Start communication with serial interface
while (!Serial && millis() < (sMillis + 5000)); // When running on battery, serial communication is not possible
Serial.print("BlueTooth ");
startBLE();
searchPeripheral();
searchAttribute();
Serial.println("Arduino Nano 33 BLE (Central Device)");
}
void loop()
{
// static char oldCommand;
// byte command;
static byte oldWindState = 0;
static byte newWindState = 0;
static unsigned long isFound = 0;
if (!peripheral.connected())
{
Serial.println("NO PERIPHERAL");
BLE.stopScan();delay(1000);
startBLE();
searchPeripheral();
searchAttribute();
}
if (wspch.canRead())
{
digitalWrite(LED_GREEN,RGBLedOn);delay(400);digitalWrite(LED_GREEN,RGBLedOff);delay(400);
if (peripheral)
{
isFound = millis();
}
} else
{
digitalWrite(LED_RED,RGBLedOn) ;delay(200);digitalWrite(LED_RED,RGBLedOff) ;delay(200);
digitalWrite(LED_BLUE,RGBLedOn);delay(200);digitalWrite(LED_BLUE,RGBLedOff);delay(200);
if (millis() - isFound >= 60000) //one minute since last isFound
{
Serial.println("Timed out finding peripheral--reset central");
isFound = millis();//reset time out
BLE.end(); //reset BLE
delay(100);
startBLE();
searchPeripheral();
searchAttribute();
}
}
if (wspch.valueUpdated())
{
wspch.readValue(newWindState);
if (oldWindState != newWindState)
{
digitalWrite(LED_BUILTIN, HIGH); delay(500);
digitalWrite(LED_BUILTIN, LOW);
Serial.print(" Command Updated New Value: ");
Serial.println(newWindState);
oldWindState = newWindState;
}
}
}
void startBLE()
{
digitalWrite(LED_BLUE,RGBLedOn);delay(500);
if (!BLE.begin())
{ // Initialise Bluetooth
Serial.println("start failed!");
while (1);
} else {
Serial.println("is started");
}
digitalWrite(LED_BLUE,RGBLedOff);delay(500);
}
void searchPeripheral()
{
digitalWrite(LED_RED,RGBLedOn);delay(500);
do
{
hourGlass();
BLE.scanForUuid(serviceName);
peripheral = BLE.available();
} while (!peripheral);
Serial.println();
if (peripheral) {
Serial.print("Found . . . . . . . . . . . . . : ["); Serial.print(peripheral.address()); Serial.println("] ");
Serial.print("Local name: . . . . . . . . . . : '"); Serial.print(peripheral.localName()); Serial.println("' ");
Serial.print("Advertised service UUID:. . . . : {"); Serial.print(peripheral.advertisedServiceUuid()); Serial.println("}");
BLE.stopScan(); // stop scanning
} else {
Serial.print("โ โ โ โ โ โ Peripheral not found after ");
}
if (peripheral.connect()) {
Serial.println("+ + + + + + Connected");
} else {
Serial.println("โ โ โ โ โ โ Failed to connect! ");
}
digitalWrite(LED_RED,RGBLedOff);delay(500);
}
void searchAttribute()
{
digitalWrite(LED_RED,RGBLedOn);
digitalWrite(LED_GREEN,RGBLedOn);delay(500);
static bool attributeFound = false;
attributeFound = peripheral.discoverAttributes();
if (attributeFound)
{
Serial.println("+ + + + + + Attributes discovered");
wspch = peripheral.characteristic(charactName);
} else {
Serial.println("โ โ โ โ โ โ Attribute discovery failed!");
}
Serial.println("Wait 500 mseconds ");
delay(500);
if(wspch.subscribe())
{
Serial.println("โ โ โ โ Subscribed โ โ โ โ ");
} else
{
Serial.println(" Subscription failed ");
}
digitalWrite(LED_RED,RGBLedOff);
digitalWrite(LED_GREEN,RGBLedOff);delay(500);
}
void hourGlass()
{
static int n = 0;
String dispChar[4] = {"/","โ","\\","โ"}; // ,"/","โ","\\"
Serial.print(dispChar[n++]);
delay(50);
Serial.write(8); // -backspace
if(n > 3) n = 0;
}