Using BLE I can connect to Arduino but not send data

My App Inventor app can connect and disconnect to my UnoR4 using BLE but I never see data sent. I'm trying to send a hex byte. If I use the LightBlue tool it all works as expected. Any ideas what is wrong? Here are my blocks:

And here is some of the Arduino code. This works with LightBlue as a BLE app but not with my App Inventor code:
// --------------------------------------------------------------------------
void loop()
{
blinkLedNoDelay();

BLEDevice controller = BLE.central(); // listen for BLE peripherals to connect:

if (controller) // if a central is connected to peripheral:
{
Serial.print("Connected to controller: ");
Serial.println(controller.address()); // print the controller's MAC address:
matrix.loadFrame(happy);
carControlCharacteristic.writeValue(0);

// while the controller is still connected to peripheral:
while (controller.connected()) 
{
  if (carControlCharacteristic.written()) 
  {
    Serial.println("characteristic written");
    
    switch (carControlCharacteristic.value()) {
      case 0x01:
        Serial.println("LEFT");
        matrix.loadFrame(arrow_left);
        break;
      case 0x02:
        Serial.println("RIGHT");
        matrix.loadFrame(arrow_right);
        break;
      case 0x03:
        Serial.println("UP");
        matrix.loadFrame(arrow_up);
        break;
      case 0x04:
        Serial.println("DOWN");
        matrix.loadFrame(arrow_down);
        break;
      default:  // 0 or invalid control
        Serial.println("STOP");
        matrix.loadFrame(stop);
        break;
    }
  }
}

// when the central disconnects, print it out:
Serial.print(F("Disconnected from controller: "));
Serial.println(controller.address());
//digitalWrite(LED_BUILTIN, LOW);         // when the central disconnects, turn off the LED
matrix.loadFrame(stop);

}
}

Please post the Arduino Sketch file (.ino). The snippet does not help us to help you.

Your App probably needs Permission for Fine Location too. I see there are two Characteristic UUIDs but you only use one. You use the same Characteristic to send bytes and strings - which can't be right?

Also, you have registered to receive bytes - using that method, the data will be received (streamed) by the App according to what the microcontroller does, so it is possible to attempt a manual (button) send from the App during a receive.

I'm not sure you can use BLE Write Bytes with hex notation, the value should be an integer within the range 0 to 255. Your hex notation represents integers anyway.......

I tried changing the Write to 1 instead of 0x01 and it still doesn't get detected by the Arduino. Here is the .ino:
BLEMinimal.ino (4.3 KB)

Did you sort this out? Drag a location sensor into the Project to trigger location on.

I'm surprised you can connect, the BLE Local Name is too long, it should be no more than 8 chars to be compatible with the Advertising Data.

Which LED Matrix library are you using?

Can you try:

//https://www.professorcad.co.uk/appinventortips#BleUuids
#define BLE_SERVICE_UUID "6b18ab86-7622-438c-a712-86a61eccbc7a"
#define BLE_CHARACTERISTIC_UUID "0a81e003-4280-4638-bf38-196f30f2a6df"

//Service
BLEService carService(BLE_SERVICE_UUID);

//Characteristic
BLEShortCharacteristic carControlCharacteristic(BLE_CHARACTERISTIC_UUID, BLEWrite | BLERead | BLENotify, 16);

On the App side, use the Shorts Blocks. Note, you should only register value type if streaming that type into the App. Otherwise use a Read Block.

Why are you trying to read and write bytes, while your .ino seems to send strings?

So try this Sketch - I can't compile it, I don't have your LED Matrix Library.

BLEMinimalEdit.ino (4.9 KB)

Note, the App must use BLE Shorts Blocks to send (1,2,3 or 4 as required). Also Note I have changed the Device Name to "UnoR4BLE" (8 char max)

Thanks for your ideas! I added your suggestions to the .ino and stripped out the LED matrix stuff. There were compile errors with Arduino BLE version 1.3.6 (latest available from Arduino) here:
//BLEShortCharacteristic carControlCharacteristic(BLE_CHARACTERISTIC_UUID, BLEWrite | BLERead | BLENotify, 16); // compile error

BLEShortCharacteristic carControlCharacteristic(BLE_CHARACTERISTIC_UUID, BLEWrite | BLERead | BLENotify); // fixed

and here:
//carControlCharacteristic.readValue(AppCmd, 16); // compile error

carControlCharacteristic.readValue(AppCmd); // fixed

But I implemented fixes as shown. Using the LightBlue BLE utility tool I can send 1 or 2 from the Android to the Arduino and it works as expected. Here is the serial transcript using LightBlue:

*** Start...
Bluetooth® Low Energy device active, waiting for connections...
Connected to controller: 49:65:9a:35:d0:04
characteristic written
LEFT
characteristic written
RIGHT
Disconnected from controller: 49:65:9a:35:d0:04

Using the App Inventor app I can connect and disconnect but no data is received by the Arduino. Here is the serial transcript with many button presses:

Connected to controller: 49:65:9a:35:d0:04
Disconnected from controller: 49:65:9a:35:d0:04

I added a Location Sensor but wasn't sure what to do with it in terms of blocks.

I did have to add this line to the .ino
if (carControlCharacteristic.written())...
otherwise the readValue(AppCmd) returns the last thing written and the case executes every loop. I just want the thing to run once every time the characteristic is written.

By the way LightBlue gives the option to send as: Hex, UTF-8 String, Signed and Unsigned Big and Little Endian. I am sending Hex for test.

Finally here are the cleaned up blocks and .ino. Summary: it works with LightBlue utility but not with App Inventor yet.


BLEMinimalEdit2.ino (3.1 KB)

Test purposes only. Ultimately I want to send from Android to Arduino bytes and receive, on a different characteristic, a char array from the Arduino to the Android. But first thing is get a byte to transfer.

You don't need to do anything, it's presence will (should) trigger location on.

Hi St3v3

Your App Code is missing the Fine Location permission.

EDIT: You can't use the BLE Byte blocks with the Shorts Characteristic - change the Blocks to Shorts.

Thanks Chris. I changed to .RegisterForShorts and .WriteShorts. I also asked for FineLocation permission and Android 12 did ask for me to enable that in settings. Still no data transfer. I can connect and disconnect but in the .ino
if (carControlCharacteristic.written())
never goes true.

Here are my blocks at this point:

.ino unchanged from the one above.

I think my fine location block should have looked like this


but it still doesn't transfer data

Finally it works! Thank you Chris!

I changed to Write...WithResponse() in the app and that allows the Arduino function ...Characteristic.written() to fire. Here are the final working test blocks and .ino to help someone else.


BLEMinimalEdit2.ino (3.0 KB)

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.