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);
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.......
//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.
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
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.
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.
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.
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.