BLE stops sending values when input data moving too fast

Hi !

I am currently trying to develop an app that should act as a GamePad controller sending data (such as Joysticks and toggle switches) through BLE to an Arduino Uno r4 WiFi.

The app is working pretty good except regarding one point : when I start moving one Joystick in a circular motion without any "stops", the received data on the Serial Plotter are blocked to the last sent values until I stop rotating it.

Here is what I tried to troubleshoot the problem :

  • At first, I printed the values of the joysticks on the screen every 100ms to see if these values where blocked until I stop rotating, which is not the case : the values were correctly updated almost instantly.

  • Then, I tried to send fixed ramp values to see if the BLE module was "blocked" during the fast rotation of the joysticks, which was not the case : when moving the joysticks fast, it took a bit more time to receive the whole ramp, but it was still working.

  • After this, I told myself that maybe the "BLE.WriteBytes" function wants input data that are "stable" and so wait for the data to stabilise before sending it. To test this assumption, I created buffer variables that, every 100ms, take the values of the actual values. Even with this strategy, the problem kept persisting.

  • Finally, I tried to add a 100ms delay between the "BytesWritten" event and the "WriteBytes", such that the whole system has a bit more time to breathe and is not constantly sending data through BLE. Once again, it didn't fix the problem.

Here is a screenshot of my BLE callback :

I join aswell the whole aia file.

Arduino_GAMEPAD_v2 (1).aia (339.0 KB)

Thanks a lot for anyone taking time to read this post !

The problem is at the last branch of this event:

Of the 4 elseif branches, the first 3 have associated flags to shut off the flow of Bytes Written.

The 4th doesn't, so it always sends, and always gets a response triggering another send.

This behaviour was actually intended :
The flags and potentiometers are supposed to have a higher priority and if none of them has been updated then the joystick message is sent by default. This allows to have a continuous stream of data (which is maybe not the best idea?)
I don't really see the link betwen the absence of flag and this problem of joystick moving too fast, and especially how to solve it.

Thank you very much for the answer !

Could someone explain me how to solve the problem?

ANother mitigation tactic for mismatched transmission and reception rates is to use lists as queues.

Each queue would be composed of newly added data waiting to be transmitted, with the oldest at slot 1 where it would be removed after receiving acknowledgement of transmission.

You could add one or more Labels showing the length of each queue, as an indication of how long a delay you have reached, like the amusement park signs warning park goers of their expected wait times on line around the popular roller coaster.

1 Like

After one week of trouble-shooting, I finally came to a solution.

I localized the problem by adding to my Bluetooth callback a print that just displays a value and then increments it. It allows to see the period at which the Bluetooth message are sent by monitoring the rate of change of this print variable. When I was moving the Joystick fast to make the system goes in the "blocked" mode, the variable was fixed, meaning that the Bluetooth callaback wasn't executing at all anymore.

So, I think that the problem was a kind of difference in priority between the "BytesWritten" event and the "Ball.Dragged" event : it seems like the joystick "dragged" event was pre-empting the bluetooth callback, making it totally blocked until the ball stops moving.

To fix the issue, I added a 20ms timer that limits the update of the joystick position by a system of raising/lowering flags. I don't know if this is the best way to solve this but with this I can achieve both a sufficient update rate for the joysticks (then making continuous motion) and a low latency for the Bluetooth connection.

If some are interested by the project, I join my current version of the code.
Arduino_GAMEPAD_v2.aia (340.5 KB)

Thanks ABG for your help, and if you (or anyone) have any further explanations about how the events are handled and what is the system of priority and pre-emption, I am definitely intersted !

1 Like

Here are the expanded blocks, for future reference.
Thanks for the sample code.
This is a common problem.

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