RUI3 BLE UART implementation details

RUI3 4.1.1 BLE UART RAK4631 (and RAK12500)

I’m migrating my serial debug output and control input away from the USB based serial port emulation and on to the BLE UART port.

I’m using the “BLE Terminal App” on the Mac host, because mostly I want to just be able to look at debug messages like “Now trying this …”, “done”. I also want to send get|set controls like “PPS=on|off|?” to my GNSS module driver. These commands will just be text.

It seems to be working well enough so far, but there are a few questions.

The BLE UART write command takes a local buffer and length parameter and sends the whole string in one transaction. The BLE UART read command transfers just single character. Can you say anything about the implementation of these functions in RUI3? Are these right down on the hardware abstraction layer or is there some interrupt driven circular buffering lurking behind the scenes? ie Is the write call blocking and is the read call meant to be used in busy polling loop?

The final question (so far this time) is whether the AT+ commands can be directed through the BLE UART serial stream. If this is the case, it’s entirely likely that I’m effectively trying to reinvent AT+ like commands and I should lever off that rather than roll my own text parsing and dispatcher.

I am not sure about the lower levels of the BLE UART. Never digged down the BSO that deep.

For using AT commands over BLE, I am setting up the BLE UART with

	Serial6.begin(115200, RAK_AT_MODE);

And then the AT commands are working.

For my custom AT commands, I define an AT+PRINTF that sends the responses over both USB and BLE

#define AT_PRINTF(...)               \
	do                               \
	{                                \
		Serial.printf(__VA_ARGS__);  \
		Serial.printf("\r\n");       \
		Serial6.printf(__VA_ARGS__); \
		Serial6.printf("\r\n");      \
	} while (0);                     \
	delay(100)

And if I want the debug output over both USB and BLE I am defining a MYLOG like this

#define MYLOG(tag, ...)                  \
	do                                   \
	{                                    \
		if (tag)                         \
			Serial.printf("[%s] ", tag); \
		Serial.printf(__VA_ARGS__);      \
		Serial.printf("\n");             \
		Serial6.printf(__VA_ARGS__);     \
		Serial6.printf("\r\n");          \
	} while (0);                         \
	delay(100)

Setting up BLE UART for AT commands and BLE response for custom AT commands are used in my RUI3-LowPower-Example. [The debug output over BLE is not used in that example]

Thanks. I’ll give that approach a try.

@beegee, I’ve explored your example, and what I had done is pretty similar. In any case the example has a wealth of useful tips about running under event flow (ie sleep walking), so reading it was well worth it. Thanks for providing it.

With Serial6 opened in RAK_AT_MODE, I still don’t get any response from an AT+VER=? query. I thought maybe this was due to data overrun because there was no buffering. So I emptied out the loop() function entirely so the underlying “arduino” loop could read AT characters faster than the link can receive them. It didn’t make any difference.

In further exploring the potential for data overrun, I looked at the file RAKBleUart.cpp in the RUI3 source.

The read limitation of a single character is imposed by the RAK wrapping of the (presumably) Nordic driver.

char RAKBleUart::read() {
    char read_data;
    udrv_ble_nus_read((uint8_t *)&read_data, 1);

    return read_data;
}

Meanwhile, down a layer udrv_ble.c contains

int32_t udrv_ble_nus_read(uint8_t *Buffer, int32_t NumberOfBytes)
{
    return uhal_nus_read(Buffer, NumberOfBytes);
}

Am I able to access either of that level (or the HAL) directly?

Yes, you can use the UHAL or UDRV functions directly.

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