BLESerial library alternatives

I got stuck in that state also but flashed the program over DFU again and it started working. Flashing via the cloud didn’t bring it out of that state.

#include "BleSerialPeripheralRK.h"
SerialLogHandler logHandler;
SYSTEM_THREAD(ENABLED);
//SYSTEM_MODE(MANUAL); //For Xenons

// First parameter is the transmit buffer size, second parameter is the receive buffer size
BleSerialPeripheralStatic<256, 256> bleSerial;
const unsigned long TRANSMIT_PERIOD_MS = 250;
unsigned long lastTransmit = 0;
int counter = 0;
void setup() {
    Mesh.off();
    //WiFi.off();
    Serial.begin();
    // This must be called from setup()!
    bleSerial.setup();
    // If you don't have any other services to advertise, just call advertise().
    // Otherwise, call getServiceUuid() to get the serial service UUID and add that to your
    // custom advertising data payload and call BLE.advertise() yourself with all of your necessary
    // services added.
    BleAdvertisingData data;
    
    //bleSerial.advertise();
     
    //Added
    data.appendLocalName("Starship");                     // give the device a name to advertise (can be anywhere in the bundle)
    data.appendServiceUUID(bleSerial.getServiceUuid()); // add the UUID that is created by the bleSerial object
    // optionally add any additional service UUIDs
    // optionally add any custom data you want (if it still fits)
    BLE.advertise(&data);        
    //End of Added
    
    // take control of the LED to turn it off to lowest power operation. Prevents LED from lighting up on every wake. 
  RGB.control(true);
  // scales brightness of all three colors, 0-255.
  // the following sets the RGB LED brightness to 25%:
  RGB.brightness(0);
}
void loop() {
    // This must be called from loop() on every call to loop.
    bleSerial.loop();
    // Print out anything we receive
    if(bleSerial.available()) {
        String s = bleSerial.readString();
        Log.info("received: %s", s.c_str());
    }
    if (millis() - lastTransmit >= TRANSMIT_PERIOD_MS) {
        lastTransmit = millis();
        // Every two seconds, send something to the other side
        bleSerial.printlnf("Bat V %d, I %d, W %d / Solar V %d, I %d, W %d", counter,counter,counter,counter,counter, counter);
        Log.info("counter=%d", counter++);
    }
}

I tested the BleSerialPeripheral example again on Android.

I flashed argon-system-part1@1.3.0-rc.1.bin to an Argon. I didn’t flash the bootloader, as if could be upgraded OTA if necessary since this device has Wi-Fi configured.

I built the example from the library and flashed it to the device by USB:

particle compile argon examples/1-simple-BleSerialPeripheralRK/ --saveTo firmware.bin --target 1.3.0-rc.1
particle flash --usb firmware.bin

USB serial logs looked normal using particle serial monitor.

Used the Bluefruit app on the iPhone (XR 12.3.1), UART worked as expected.

Ran the Bluefruit app on a Samsung A10. The first time I tried, the UART device was shown, but I got a failure to connect. Later on, it did work properly and I was able to send and receive data. I’m not sure of the cause of the connection failure.

Ran the nRFToolbox app. I had both successful and unsuccessful connections, but even when it connected, it didn’t show anything. I don’t really understand the UART UI in this app.

Ran the nRF UART v2.0 app. That worked properly, however by this time, the Bluefruit app was also working normally.

So there might be an issue on Android with connecting to the UART service in BleSerialPeripheralRK, but I’m not sure of the cause or solution. Since it’s no longer happening for me that will make it harder to figure out.

I have (so far) always been using OTA update via Web IDE an can consistently not use the service that’s advertised after connecting to the device (Argon and Boron) - but I can use it when running the UART Peripheral example.

I yet have to test CLI build and USB flashing.

The only time I saw the UART service not being available is after changing your BLE Serial UART demo code to try to include a custom name and not getting the code right to do that the first time. Trying to figure out how to change the Local Advertised name I did add some code that changed the UUID which is what made the UART service to disappear.

I found that Flashing the code I have which includes a unique Advertised Local name via USB DFU mode using Workbench would bring all the BLE UART services back while multiple previous OTA flashing attempts did not bring back the BLE UART service. I’m not sure why it took a USB DFU programming to fix it but it did work just fine.

I think the bottom line is that using the wrong code or BLE commands in the wrong sequence or just not using the right commands at all in the code can put the BLE module in a mode where it does not Advertise the UART service.

From my testing using the proper code to Advertise for UART will make the Gen 3 device start advertising UART services but it may take a USB DFU programming session to bring the BLE UART services back.

Maybe it was that a power reset was required to get the BLE UART services back after programming the proper code? Not sure but USB DFU programming fixed the issue where the BLE apps would not show the Gen3 device as being a UART connection. I don’t think there is a big issue here, just something small that maybe we don’t understand yet when switching UUID’s incorrectly.

The biggest issue I have seen with BLE is that when your connected to the BLE UART via a app like Adafruit Bluefruit and you go out of range it causes the Argon to lock up and show SOS error which resets the code from the beginning vs. just the connection dropping gracefully and the Argon code continuing to run. I’m not sure if that can be fixed but if so that would be ideal so the application is not affected by the loss of BLE Connection.

@rickkas7, I can confirm now that the issue for me is tied to cloud building.
When I build via Workbench (locally) I do see the service exposed.
When I then build/flash OTA or via USB the firmware that was build by Web IDE then the service is missing.
This also happens when I build in the cloud via CLI (particle compile boron --target 1.3.0-rc.1) or Workbench (the same project that works with building locally)
That’s fully reproducable for my devices.
Local WB build always works
Cloud build (WebIDE, CLI, WB) never
Both targets are set to 1.3.0-rc.1 and compile exactly the same sources (a local copy of your library).

Could it be that there is a build farm (for Europe) that doesn’t behave as expected?

1 Like

I flashed the the bootloader “argon-bootloader@1.2.1.bin” to my Argon and compiled and flashed via CLI like @rickkas7 demonstrated.
On Bluefruit the Argon does not display as though it is UART capable, but when I connect on my Samsung S8 UART service is exposed.

Messages do transmit from the Argon and display in the app, but only on the Android. The iPhone 7 I am using for testing does not have the UART services exposed.

When I try to send a message from the app it does NOT print down the serial port connected.

If I take the same code and flash it through the workbench (Application Local), the UART services are not exposed on the Android or iPhone. I then flashed it again via CLI exactly as the first time when it worked. This time no UART services were exposed. I restarted the Argon without any changes to available services.

This inconsistency is really hard to develop on. I think that it shouldn’t manner how I flash it if it stable.

What combination/version of OS, Bootloader and ncp firmware is the key to making this work?
What modes does it work in? If in Automatic mode, must it be connected to the cloud in order to function?
I think these details are key to explaining the setup of a functioning program.
@rickkas7 do you have older phones to test this on? I doubt most of our customers are going to have the latest phone to use this on. Thanks for your continued help on this. This is the last piece that is now in the critical path of our product launching. If we don’t have stable Bluetooth communication, we don’t have a product :frowning:

I'm pretty sure I was seeing the exact same behavior here in the USA.

You need the 1.3.0 bootloader for BLE to work.

It only works when I put the bootloader 1.2.1. The OS on the other hand is 1.3.0.rc-1

I take that back. I just flashed the 1.3.0 bootloader and it works if I compile and flash it via the CLI.

1 Like

You can always use the bare UART Peripheral example instead of that library.
I had no issue with that example whatsoever, but for some obscure reason the library that packages that code seems to behave somewhat wayward.

Maybe you are right. I was having difficulties in transmitting messages from that example. I hoped this would simplify my code...

What do you mean by that exactly?

Only when using the lib I have the issues local vs. cloud build - so the library appears to be the cause for the (assumed) differences in cloud build farm setup to show up.

It's not (necessarily) that the lib misbehaves but something in it seems to be disliked by some build environments.

Hi there,

Just FYI, except those mobile Apps you mentioned above, there is an App named “LightBlue” which is more reliable and universal for testing BLE functionalities. No matter how you build that BLE UART serial library from Workbench or cloud, you can verify if the UART service is successfully added or not by using this mobile App to connect the BLE device.

The Argon reset issue after disconnection is most likely fixed by this way: BLE Peripheral UART Streaming Assertion Failure.

Best regards,
Guohui

I did doubt it’s just a case of using another app (after already using multiple others) but I went ahead and downloaded “LightBlue” as well and what shall I, say the expected non-functioning behaviour manifests itself with that just the same.

If you wish I can send you the cloud built binary to check yourself (the build run was just a few minutes ago, if you want to look at the logs).


(click to view full image - service gets advertised but is not present in the GATT service list)

From the image, I can see the UART service UUID is correct and is appended to advertising data successfully, but the UUID of the added UART service is incorrect. There must be something wrong when adding the UART service and characteristics.

Yup, but not on the code side as the exact same code works just fine when building locally.

I am unable to get the example to work. I have tried compiling locally and via the cloud or flashing (using Workbench) with an Argon v1.4.4

All I see is:

By contrast, the demo in the documentation works fine.

Real pity as this would be a very useful tool.

I know this is an old thread, but it's not clear that the issues above were ever solved, so I thought it might help to share my experience:

Recently, I was having the same problem as @mawrob using the exact example from @rickkas7 without modification on a Boron 4.2.0. The Bluefruit app recognized the UART service and connected fine, but the services didn't function. However, when I looked at the Bluefruit Info tab (the only option offered) I noticed that the characteristics all had the wrong numbers:

In particular these numbers didn't match the ones specified in the library:

static const BleUuid serviceUuid("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
static const BleUuid rxUuid("6E400002-B5A3-F393-E0A9-E50E24DCCA9E");
static const BleUuid txUuid("6E400003-B5A3-F393-E0A9-E50E24DCCA9E");

I tried redefining the UUIDs with the alternate syntax by replacing these lines with:

const char* serviceUuid = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E";
const char* rxUuid = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E";
const char* txUuid = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E";

...and then it all started working correctly :slight_smile:
[I also had no problems flashing OTA after putting in Safe Mode].

I don't know for sure that these definitions were the source of the problem since I believe both formats should work, but hope this might help others in a similar situation.

2 Likes