Data from BLE are read only once

Hello, Please do you know to receive data in real time? in my case in order to receive the last data showen on my serial monitor, i have to disconnect and reconnect the BLE. PS : I am using Arduino Nano BLE 33 and here are my app inventor blocks. I don't know if I should add the Clock timer bloc, if yes where? and how to code it?


The ReadString block you have in the Connected event will be called only once when the devices connect, so you only read the data once. Instead of the ReadString block, use the RegisterForString block.

If the RegisterForString block doesn't work, then you'll have to use the ReadString block but in the timer to make the reading cyclic.

Hello @Patryk_F So I replaced ReadString with RegisterForString. It doesnt work, and i also did your second suggestion, I put all the bloc of ReadString in the timer instead of When BLE connected, it still doesnt work, have I done it wrong? can you please show me. The images show first and second try.


Show the current code for arduino. Maybe we can find something there.

'''
#include <ArduinoBLE.h>
volatile int NbTopsFan; // Nombre de tours d'hélices
float Calc; // Calculer du volume
float Q; // Calculer du débit
int hallsensor = 2; // PIN DIGITALE 2
int tsampling = 1;

BLEService dataService("19B10000-E8F2-537E-4F6C-D104768A1214"); // Random 128-bit UUID for the service
BLECharacteristic dataCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead, 20); // Random 128-bit UUID for the characteristic

void rpm() {
NbTopsFan++;}

void setup() {
Serial.begin(9600);
pinMode(hallsensor, INPUT);
attachInterrupt(digitalPinToInterrupt(hallsensor), rpm, RISING);
if (!BLE.begin()) {
Serial.println("Erreur BLE");
while (1);}
BLE.setLocalName("NanoBLE");
BLE.setAdvertisedService(dataService); // Annoncez le service personnalisé
dataService.addCharacteristic(dataCharacteristic); // Ajouter la caractéristique personnalisée au service
BLE.addService(dataService); // Ajouter le service personnalisé
// Add the BLE connection event handler here
BLE.advertise(); // Démarrez la publicité BLE
Serial.println("En attente de connexion BLE...");}

void loop() {
BLEDevice central = BLE.central();
if (central) {
Serial.print("Connecté à : ");
Serial.println(central.address());
while (central.connected()) {
NbTopsFan = 0;
delay(tsampling * 1000);
Q = float(NbTopsFan) / (20 * tsampling);
Calc = (Q / 60) + Calc;
String To_App = String(Calc, 3) + "," + String(Q, 3);
Serial.println(To_App);
dataCharacteristic.writeValue(To_App.c_str(), To_App.length());
delay(200);
Serial.print("Déconnecté de : ");
Serial.println(central.address());}
}
'''

I think it's the app inventor blocks that control the live receiving of Data.

Why do you think that data is only read once? From what I can see, you don't have a real reading from the sensor, you just send 0 (zero) all the time. Add a random number generator in the arduino code, and send different values ​​to confirm that the data is actually read only once.

No i don't see 0. Here is a proof with LightBlue.

Since the LightBlue app is receiving data, that tells me the AI2 app is being too fussy or opinionated on the input stream format.

The next step should be to log all the incoming strings to a Label, separated from previous input with \n ...

When BLE1.StringsReceived
  for each stringReceivedItem in stringsReceived
    set LabelDebugging.Text to JOIN(stringReceivedItem , '\n', LabelDebugging.Text)
  end for each

This should tell you what your data stream look like on the AI2 side.

And you should I keep my initial blocks I shared ? or change them?

I asked you for the current arduino code, you sent me some code, but it's not the code you are testing the connection with...

It is the code I am currently using, I don't have any other code. If i am asking for help, why would I send a random code?

The code you sent me 14 hours ago is different from the code I can see in the picture above...

The only difference is i removed Leds because I am using 7 leds and the code is looong with 7 outputs I controle the On/off of, and One line adding Vol: and D: for the Bluelight, That I comment it doesnt change anything, it just puts volume in front of first value and D in front of second value. If you want the 7 leds and this Line, i can provide it.

The code you show in the picture above uses the newline character to split the value. This will not work with the blocks you showed above. The previous code used commas. So please repost the current code you are using now and the current blocks.


#include <ArduinoBLE.h>
int NbTopsFan; // Nombre de tours d'hélices
float Calc; // Calculer du volume
float Q; // Calculer du débit
int hallsensor = 2; // PIN DIGITALE 2
int ledPin1 = 3;
int ledPin2 = 4;
int ledPin3 = 5;
int ledPin4 = 6;
int ledPin5 = 7;
BLEService dataService("19B10000-E8F2-537E-4F6C-D104768A1214"); // Random 128-bit UUID for the service
BLECharacteristic dataCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead, 20); // Random 128-bit UUID for the characteristic

void rpm() { NbTopsFan++;}

void setup() {
Serial.begin(9600);
pinMode(hallsensor, INPUT);
attachInterrupt(digitalPinToInterrupt(hallsensor), rpm, RISING); //Gestion de l'interruption
pinMode(ledPin1, OUTPUT); // Première Led
pinMode(ledPin2, OUTPUT); // Deuxième Led
pinMode(ledPin3, OUTPUT); // Troisième led
pinMode(ledPin4, OUTPUT); // Quatrième led
pinMode(ledPin5, OUTPUT); // Cinquième led
if (!BLE.begin()) {
Serial.println("Erreur BLE");
while (1);}
BLE.setLocalName("NanoBLE");
BLE.setAdvertisedService(dataService); // Annoncez le service personnalisé
dataService.addCharacteristic(dataCharacteristic); // Ajouter la caractéristique personnalisée au service
BLE.addService(dataService); // Ajouter le service personnalisé
// Add the BLE connection event handler here
BLE.advertise(); // Démarrez la publicité BLE
Serial.println("En attente de connexion BLE...");}

void loop() {
BLEDevice central = BLE.central();
if (central) {
Serial.print("Connecté à : ");
Serial.println(central.address());
while (central.connected()) {
NbTopsFan = 0;
delay(1000);
Q = (NbTopsFan / 9.5);
String Q_str = String(Q, 2);// Round to two decimal places

  Calc = (Q / 60) + Calc;
  String Calc_str = String(Calc, 2); // Round to two decimal places
  String To_App = "Vol(L):" + Calc_str + '\n' + "D:" + Q_str + '\n';
  Serial.println(To_App);
  dataCharacteristic.writeValue(To_App.c_str(), To_App.length());
  delay(200);

if(Calc>=1){
digitalWrite(ledPin1,LOW);
}
else{
digitalWrite(ledPin1,HIGH);
}

if(Calc>5){
digitalWrite(ledPin2,LOW);
}
else{
digitalWrite(ledPin2,HIGH);
}

if(Calc>7){
digitalWrite(ledPin3,LOW);
}
else{
digitalWrite(ledPin3,HIGH);
}
if(Calc>8){
digitalWrite(ledPin4,LOW);
}
else{
digitalWrite(ledPin4,HIGH);
}
if(Calc>9){
digitalWrite(ledPin5,LOW);
}
else{
digitalWrite(ledPin5,HIGH);
}
}
Serial.print("Déconnecté de : ");
Serial.println(central.address());}
}

The OP switched to YAML format.
To parse that,

For each item in strings received
 Set yamlList to split item at \n
 For each yamlTagValue in yamlList
   If yamlTagValue Contains ':' then
     Set tagValueList to Split yamlTagValue at ':'
     Set tag to select item 1 from tagValueList
     Set value to select item 2 from tagValueList
     If tag=... Then
        Set label... To value
     Elseif tag=... Then
       Set label... To value
     ...
 End foreach
End foreach

I am so sorry but can you please show me the blocks using App inventor blocks. I want you to kindly remind you of my problem. I do receive data, my problem is i don't receive live data. I only receive after i disconnect and reconnect the BLE

I thought of a shorter fix

In your blocks, change that List From CSV Row block to a List From CSV Table block where you feed global List.

I am not a BLE sketch expert.

I recommend comparing your sketch loop against one of the samples, especially around where you test connection.

I do not see the need for a while () if you are inside loop ().

An if/then should suffice.