Unable receive data from Arduino BLE

Hi I'm new of App Inventor and I'm trying to read data from an Arduino33Ble or send data to it.
I can send data as byte but I'm not able to read data from Arduino also if withNRF Connect I see the data received.

I hope someone can give me any suggestion to fix the issue.

Thanks Roberto.

Here the App Inventor block :

This is the arduino sketch jusr related to read data from Arduino.

#include <ArduinoBLE.h>

const int led_Pin = LED_BUILTIN; // pin to use for the LED

const int button_PIN = 3; // pin to use for the button
const int cmd1=0;

// never add BLENotify to a characteristic that has a BLEwrite parameter only
BLEService batteryService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service

BLEIntCharacteristic batteryLevelChar("19B10001-E8F2-537E-4F6C-D104768A1214", BLEWrite | BLENotify );

void setup() {
Serial.begin(9600);
// set LED pin to output mode
pinMode(button_PIN, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}

  // Set a local name for the BLE device. 
  // This name will appear in advertising packets and can be used 
  // by remote devices to identify this BLE device.
  
  BLE.setLocalName("BatteryMonitor");
  
  //Here we will add and set the value for the Service UUID and the Characteristic.
  
  BLE.setAdvertisedService(batteryService);
  batteryService.addCharacteristic(batteryLevelChar);
  
  BLE.addService(batteryService);

  // Start advertising BLE.  
  // It will start continuously transmitting BLE advertising packets and 
  // will be visible to remote BLE central devices until it receives a new connection.
  BLE.advertise();
  Serial.println("Bluetooth device active, waiting for connections...");

}

void loop(){

BLEDevice central = BLE.central();
if (central) {
Serial.print("Connected to central: ");
Serial.println(central.address());
digitalWrite(LED_BUILTIN, HIGH);

while (central.connected()) {

  int battery = analogRead(A0);
  int batteryLevel = map(battery, 0, 1023, 0, 100);
  Serial.print("Battery Level % is now: ");
  Serial.println(batteryLevel);
  batteryLevelChar.writeValue(batteryLevel);

}
}

digitalWrite(LED_BUILTIN, LOW);
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}

An example Sketch that shows the little details to get right with the Serial function.:

// App Send and Receive via BLE

// BluetoothLE
#include <string.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

unsigned long lgUpdateTime;
//Data From App Examples: D29\0 M12\0 Y2020\0
char code;
char data[6];
char day[4];
char month[4];
char year[6];

#define        SERVICE_UUID = "0000FFE0-0000-1000-8000-00805F9B34FB"
#define CHARACTERISTIC_UUID = "0000FFE1-0000-1000-8000-00805F9B34FB"

BLEServer *pServer = NULL;
BLECharacteristic *pTxCharacteristic;
bool deviceConnected = false;

class MyServerCallbacks: public BLEServerCallbacks
{

        void onConnect(BLEServer *pServer)
        {
             deviceConnected = true;
        }

        void onDisconnect(BLEServer *pServer)
        {
             deviceConnected = false;
        }
}

void setup()
{
          Serial.begin(9600);
         Serial1.begin(9600);

         // Create the BLE Server
         pServer = BLEDevice::createServer();
         pServer->setCallbacks(new MyServerCallbacks());

         // Create the BLE Service
         BLEService *pService = pServer->createService(SERVICE_UUID);

         // Create a BLE Characteristic
         pTxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_NOTIFY);
         pTxCharacteristic->addDescriptor(new BLE2902());

         // Start the service
         pService->start();

         // Start advertising
         pServer->getAdvertising()->start();

         Serial.println("Bluetooth device active, waiting for connection...");

         lgUpdateTime = millis();
}

void loop()
{
         if ((millis() - lgUpdateTime) > 600) //Loop every 600 milliseconds
         {

               lgUpdateTime = millis();

               //From App
               if (Serial.available() > 0)
               {
                         code = Serial.read(); //read first byte (ascii char = 1 byte)
                         data = Serial.readString(); //Read remaining characters up to \0

                         switch (code)
                         {
                             case 'D':
                                       strcpy(day,data);
                                       break;

                             case 'M';
                                       strcpy(month,data);
                                       break;

                             case 'Y';
                                       strcpy(year,data);
                                       break;
                         }
               }

               //To App       Note, Serial sends numbers as ASCII text
               Serial1.print(code);
               Serial1.println();   //End Of Data delimiter expected by App
         }
}

My problem is that App inventor seems not able to receive the data from Arduino while I can send command from app inventor to Arduino . In this post I've isolated just the part of code related to this problem.
Tks.

Part of your problem is in the detail of how you are sending, hence my example Sketch.

The problem is you send the data as text using serial.print. If you want to send binary data use serial.write.

You can send data as text, but then in appinventor use string.received instead of integer.received.

After that, I can see that you are sending debug data via BT. For example "Serial.println (" starting BLE failed! ");". If you want to have debugging in a terminal on your computer then use a virtual serial port created on other pins to send data so as not to clutter the transmission with debug data. The problem is also when you use the terminal and bluetooth at the same time.

I'm not using the serial to pass data to the bel module .
I'm using and Arduino33Ble board with athe ArduinoBLE library .
The method to pass the value to the ble is :
batteryLevelChar.writeValue(batteryLevel);
I've also disabled the Seria and nothing change, I can't receive data from Arduino .

That's right, I can see now. Do you see the correct values on the serial monitor?

Yes, both on serial monitor and also using the nRF Connect app , i see the value of this service change if I adjust the trimmer on analog input.

What version of the extension are you using?

I'm using edu.mit.appinventor.ble-20200828.aix.

Just to avoid confusion in the arduino schetch that I've posted there is a mistake and this row
BLEIntCharacteristic batteryLevelChar("19B10001-E8F2-537E-4F6C-D104768A1214", BLEWrite | BLENotify );

in reality is as this

BLEIntCharacteristic batteryLevelChar("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify );
But It dosen't change the problem ...

After additional check I've verified that with actual ble extension I can receive data in other format but not like integer .
Am I wrong or someother had the same problem ?

Hi,has described in this post https://community.appinventor.mit.edu/t/unable-receive-data-from-arduino-ble/29251 I've faced some issues with this BLE extension to receive integer data. With other format works but not with Integer.
Is it a bug of extension or I'm wrong with my program ?

Why not show your blocks?

Hi ,is't all described in the link that I've indicated , It's my original post .
After some check I'm arrived at the possible conclusion that could be something wrong with the integer interpretation because similar structure of code and block but with different data format works.

Anyway here the blocks

About the arduino theis is the code:
This is the arduino sketch jusr related to read data from Arduino.

#include <ArduinoBLE.h>

const int led_Pin = LED_BUILTIN; // pin to use for the LED

const int button_PIN = 3; // pin to use for the button
const int cmd1=0;

BLEService batteryService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service

BLEIntCharacteristic batteryLevelChar("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify );

void setup() {
Serial.begin(9600);
// set LED pin to output mode
pinMode(button_PIN, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}

  // Set a local name for the BLE device. 
  // This name will appear in advertising packets and can be used 
  // by remote devices to identify this BLE device.
  
  BLE.setLocalName("BatteryMonitor");
  
  //Here we will add and set the value for the Service UUID and the Characteristic.
  
  BLE.setAdvertisedService(batteryService);
  batteryService.addCharacteristic(batteryLevelChar);
  
  BLE.addService(batteryService);

  // Start advertising BLE.  
  // It will start continuously transmitting BLE advertising packets and 
  // will be visible to remote BLE central devices until it receives a new connection.
  BLE.advertise();
  Serial.println("Bluetooth device active, waiting for connections...");

}

void loop(){

BLEDevice central = BLE.central();
if (central) {
Serial.print("Connected to central: ");
Serial.println(central.address());
digitalWrite(LED_BUILTIN, HIGH);

while (central.connected()) {

  int battery = analogRead(A0);
  int batteryLevel = map(battery, 0, 1023, 0, 100);
  Serial.print("Battery Level % is now: ");
  Serial.println(batteryLevel);
  batteryLevelChar.writeValue(batteryLevel);

}
}

digitalWrite(LED_BUILTIN, LOW);
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}

Since they are related i merged your posts. Lets see if someone can help you.

The issue there is that you are sending a String and an Integer.

Sending the String is superfluous - the App can add that string on receipt of the data if required, so just receive the integer with an Integer Block.

Sorry ChrisWard, I'm not sending string and char .
Probably what confuse is the name of the characteristic that I've used "batteryLevelChar" but as you see the declatarion of that characteristic is integer : BLEIntCharacteristic batteryLevelChar("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify );

Could be that in the block where I go to write the received data I must convert in such way the integer to string before to write into the "TextReceived" block ?

If you figured the problem might be with integer values, send a string to app and receive a string. For AppInventor, it makes no difference.

Good morning Bob

I have similar issues that you faced. Arduino does transmit data which I know is correct as nRF Mobile app shows the data on my Android phone.

I am getting far too many issues with MIT App not receiving the data. If possible could you send me Arduino sketch and MIT Inventor sketch please