Bluefruit Friend UART BAUD change

For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
orbitronics
 
Posts: 47
Joined: Thu Jun 22, 2017 11:32 am

Bluefruit Friend UART BAUD change

Post by orbitronics »

Hi,

I'm using a Bluefruit UART friend conntect with RTS to a teensy to send out mouse commands, i've got it working quite nicely but the low baud rate i believe is quite a bottle neck and i want to experiment with a higher baud rate.

I tried here to change it

https://github.com/orbitinstasis/USB_La ... P.ino#L351

but when i boot i get the error: "Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?" if i used anything but 9600, i have a feeling the way i'm setting the baud rates (for serial, serial1, and 'ble') is wrong. Could you help?

User avatar
adafruit_support_mike
 
Posts: 67459
Joined: Thu Feb 11, 2010 2:51 pm

Re: Bluefruit Friend UART BAUD change

Post by adafruit_support_mike »

Just setting the baudrate on the microcontroller won’t work. First you’d have to use the 9600 baud connection to tell the nRF52832 what baudrate to use, with the AT+BAUDRATE command:

https://learn.adafruit.com/introducing- ... -2903871-2

Then you’d shut down the 9600 baud connection and open a new one at the rate you set.

The 9600 baud connection isn’t the bottleneck in the signal path though. The nRF52832’s input buffer is, with a lot of help from BLE itself.

BLE packets can only carry 20 bytes of user data. You can send 1 to 6 packets per frame, depending on what BLE central device you have. For anything except Nordic’s own app, you’ll probably get one or two.

Frames are separated by a gap of at least 7.5ms, and can be longer if the device is told to go slower. If you tried to use a 115200 baud connection, you’d send about 80 bytes worth of data in the gap between sending 20 to 40 bytes per frame.

And basic TX/RX Serial connections don’t have flow control, so your microcontroller will send whatever bytes it has as soon as it can. In our experience, baudrates higher than 9600 tend to overflow the nRF52832’s input buffer. When that happens the nRF52832 empties the buffer whether the data has been sent or not, and starts again. The BLE Serial connection starts dropping bytes.

User avatar
orbitronics
 
Posts: 47
Joined: Thu Jun 22, 2017 11:32 am

Re: Bluefruit Friend UART BAUD change

Post by orbitronics »

Thanks for the response, I really appreciate it.

I'm using Serial2 on the teensy, I change this with 'BLUEFRUIT_HWSERIAL_NAME.begin(BAUD);'.

I already try changing AT BAUDRATE on line 353, but I realise now, I should have set this first THEN change Serial2's baud rate.

I assumed Serial2 on the MCU has the baud rate of 9600 set by the 'Adafruit_BluefruitLE_UART' constructor. To change this I call Serial2.begin(x);, is there a function in the adafruit code that I should use instead? I did look at the c and h files.

Fixing the order of things, I currently have:

Code: Select all

Serial.begin(115200);
  BLUEFRUIT_HWSERIAL_NAME.setTX(TX);
  BLUEFRUIT_HWSERIAL_NAME.setRX(RX);
  BLUEFRUIT_HWSERIAL_NAME.attachCts(23);

  Serial.println(F("Adafruit Bluefruit HID Mouse Example"));
  Serial.println(F("---------------------------------------"));

  /* Initialise the module */
  Serial.print(F("Initialising the Bluefruit LE module: "));

  if ( !ble.begin(VERBOSE_MODE) )
  {
    error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
  }

  ble.println("AT+UARTFLOW");  ble.waitForOK();
  ble.println("AT+UARTFLOW=on");  ble.waitForOK();
  ble.println("AT+UARTFLOW");  ble.waitForOK();
  ble.println("AT+BAUDRATE");  ble.waitForOK();
  ble.print("AT+BAUDRATE=");
  ble.println(BAUD);  ble.waitForOK();
  ble.println("AT+BAUDRATE");  ble.waitForOK();

  //  delay(50);
  BLUEFRUIT_HWSERIAL_NAME.begin(BAUD);
  //  delay(50);

  if ( FACTORYRESET_ENABLE )
  {
    /* Perform a factory reset to make sure everything is in a known state */
    Serial.println(F("Performing a factory reset: "));
    if ( ! ble.factoryReset() ) {
      error(F("Couldn't factory reset"));
    }
  }


  /* Disable command echo from Bluefruit */
  ble.echo(false);

  Serial.println("Requesting Bluefruit info:");
  /* Print Bluefruit information */
  ble.info();

  ble.println("AT+BAUDRATE");  ble.waitForOK();
  ble.println("AT+UARTFLOW");  ble.waitForOK();
Is this more or less what you're suggesting? I just tried it, this is the serial output:

Code: Select all

AT+UARTFLOW

<- AT+UARTFLOW
1
OK
AT+UARTFLOW=on

<- AT+UARTFLOW=on
OK
AT+UARTFLOW

<- AT+UARTFLOW
1
OK
AT+BAUDRATE

<- AT+BAUDRATE
9600
OK
AT+BAUDRATE=1000000

<- AT+BAUDRATE=1000000
OK
AT+BAUDRATE

<- ATE=0

<- ATE=0
OK
Requesting Bluefruit info:
----------------
BLEFRIEND32
nRF51822 QFACA10
5D4B383D56D29DA2
0.8.1
0.8.1
Apr 10 2019
S110 8.0.0, 0.2
----------------
AT+BAUDRATE

<- 1000000
OK
AT+UARTFLOW

<- 1
OK
ATI=4
0.8.1

<- OK
Enable HID Service (including Mouse): 
AT+BleHIDEn=On

<- OK
Performing a SW reset (service changes require a reset): 
ATZ

<- OK
It seems ok except that baud rate query after setting it.

The code seems to work well up to 460800, anything higher and there are moments of non-responsiveness which i assume is the 200ms blocking delays when the TX FIFO buffer fills up?

A repeat flash the MCU gives the error when calling ble.begin, which makes sense since I figured i'm trying to talk with the wrong baud rates. I haven't got my head around how to fix it for repeat flashes yet.

I do have flow control set up:

MCU CTS <-- nRF RTS

I did this hoping the teensy would refrain from transmitting until the nRF was ready.

I only plan on using BLEhid with this project.

I don't mind if there are a few dropped packets as long as i can transmit with a lower latency.

I want to try this before considering the SPI friend which i noticed has a 4MHz bandwidth which is surely enough.

I do also have an 'nRF52832 Bluetooth Low Energy Module - MDBT42Q-512KV2' feather but i didn't want to port the code over particularly since the PCB I have is designed for a teensy which means a respin. Obviously the 'UART friend' utilises an nRF51822 which has a maximum of half the RAM and memory - bit of a long shot but do you think i''d have the bottleneck with the input buffer that you mentioned on the nRF52832 if i used it in the same way as i do now (teensy uart to nRF52832 UART) ? I noticed there are no AT commands.

I guess the bottleneck you mention won't be an issue if I used the SPI friend.

All this said, with the changes in the code above (and a multiplier added to the sensor input), the latency is low enough for the system to behave and respond pretty well, but due latency somewhere I find the cursor movement is a bit jittery. Could a part of this be the echo I'm getting such as 'AT+BleHidMouseMove=2,0', I don't know why I'm getting this since I did turn ble echo off in the setup. This is the code that sends out the mouse commands:

Code: Select all

char _x [10];
    char _y [10];
    #define MULTIPLIER 2
    itoa(report.x * MULTIPLIER, _x, 10);
    itoa(-report.y * MULTIPLIER, _y, 10);
    ble.print(F("AT+BleHidMouseMove="));
    ble.print(_x);
    ble.print(",") ;
    ble.println(_y) ;

User avatar
orbitronics
 
Posts: 47
Joined: Thu Jun 22, 2017 11:32 am

Re: Bluefruit Friend UART BAUD change

Post by orbitronics »

Here's a video of me using my logitech mouse for reference up to 9seconds, then the trackpoint through the code above

I guess one thing i can do to verify the actual bandwidth of the nRF is to hook up the RTS pin to a scope and measure the pulse rate, what do you think?

User avatar
orbitronics
 
Posts: 47
Joined: Thu Jun 22, 2017 11:32 am

Re: Bluefruit Friend UART BAUD change

Post by orbitronics »

EDIT: I found line 111 in Adafruit_BluefruitLE_UART::begin which I changed with the new baud rate, now i can cold boot the board and it works fine (also after flashing re-compilation)

I took the scope to the RTS, does this look sane?

User avatar
adafruit_support_mike
 
Posts: 67459
Joined: Thu Feb 11, 2010 2:51 pm

Re: Bluefruit Friend UART BAUD change

Post by adafruit_support_mike »

Typically the transmitting device sets RTS high to ask the receiver if there’s room for more data. The receiver answers yes by setting CTS high.

How does your system interpret RTS on its own?

User avatar
orbitronics
 
Posts: 47
Joined: Thu Jun 22, 2017 11:32 am

Re: Bluefruit Friend UART BAUD change

Post by orbitronics »

The teensy MCU has

Code: Select all

Serial2.attachCts(x);
so it's signalled by the nRF's RTS pin.

I don't use Rts on the MCU side because the MCU is much faster and has no issues receiving data.

User avatar
adafruit_support_mike
 
Posts: 67459
Joined: Thu Feb 11, 2010 2:51 pm

Re: Bluefruit Friend UART BAUD change

Post by adafruit_support_mike »

I think the signal names may be a bit mixed up..

RTS is Ready To Send, which you can classify as information about the state of a transmitter’s TX pin: the TX buffer has data ready to go out.

CTS is Clear To Send, which you can classify as information about the state of a receiver’s RX pin: the receiver’s RX buffer has empty space for incoming data.

Using RTS on its own doesn’t do any useful flow control. The transmitter has no way of knowing if the receiver has room for new data in its RX buffer.

Using CTS by itself can make sense if the receiver flips the signal high and low as part of managing its RX buffer.

Assuming that’s what’s happening, the scope traces above look reasonable. The blips going high would be moments when the BLE module has room in its RX buffer, and the signal wouod drop when the buffer is full.

User avatar
orbitronics
 
Posts: 47
Joined: Thu Jun 22, 2017 11:32 am

Re: Bluefruit Friend UART BAUD change

Post by orbitronics »

I think what you describe is what i'm intentionally doing, which is why i set up CTS on the MCU to read the RTS signal from the bluefruit board.

Do you think it's pointless to try this code with an SPI friend, or is that BLE buffer bottleneck still going to exist?

User avatar
adafruit_support_mike
 
Posts: 67459
Joined: Thu Feb 11, 2010 2:51 pm

Re: Bluefruit Friend UART BAUD change

Post by adafruit_support_mike »

I don’t think it’s pointless.. you might be able to make something work, and even if it doesn’t you’ll end up with a more detailed understanding of what’s possible. Negative results are valuable.

The principle of limiting resources says there will always be something that acts as a bottleneck for everything else. You don’t get rid of bottlenecks so much as move them around. Eventually any optimized system will arrange itself around the limits of the resource that’s hardest to improve further.

On the flip side, improving a non-limiting resource probably won’t do much for system performance. Once some piece of the system works well enought to be limited by something outside itself, you have to find new reasons to justify improving it further. Making code 20% faster doesn’t have much value if the next thing that happens is a busy-wait loop.

So go ahead and try to get as much Serial performance as you can, but keep an eye on the overall effect of your improvements in terms of data received at the other end of the BLE connection.

Locked
Please be positive and constructive with your questions and comments.

Return to “Wireless: WiFi and Bluetooth”