Skip to content

Conversation

@laurensvalk
Copy link
Member

This partially fixes pybricks/support#2206. I don't think there is a true cure but it turns out we can reduce the symptoms significantly.

We used to believe that alternating between observing and broadcasting was the right workaround, but on closer look it appears that this might not be the case. The freezes are not random. When the Bluetooth chip locks up, it is always just after an observe restart. It will then get stuck at the very next Bluetooth command, whatever that is. That was usually broadcasting, so this is why we assumed they were conflicting.

So every time we restart observing, there is a small chance of locking up the Bluetooth chip. The restart was added in the first place as a workaround for the scan queue getting full so new scan events were not coming in (pybricks/support#1096). This usually doesn't happen for a long time, so we can avoid restarting observing until that happens.

This reduces the number of restart from once every 10 seconds to a few times per hour, significantly reducing the odds of a lock up. In practice, some applications that used to get stuck after 10 minutes can now run for hours.

Since there isn't a good way to know if the queue is full, we can request a restart if we are not receiving data when the user is expecting some data. In the worst case, this will still restart it every 10 seconds as it used to do. If all of the subscribed channels get incoming data, restarting is delayed, thus reducing the likelihood of a freeze.

This could potentially be made to work better if we told bluetooth_stm32_cc2640 which channels to expect, but this resides at the module level. If it was at the driver level, we could do it at the right time even if the user wasn't calling observe. This requires much bigger changes though, so probably isn't worth it.

@coveralls
Copy link

coveralls commented Jun 13, 2025

Coverage Status

coverage: 57.141%. remained the same
when pulling 8dea17f on work
into 4a4714a on master.

@laurensvalk
Copy link
Member Author

This needs a changelog entry.

Everytime we restart observing, there is a small chance of locking up the Bluetooth chip. The restart was added as a workaround for the scan queue getting full so new scan events were not coming in. This usually doesn't happen for a long time, so we can avoid restarting observing until then.

Since there isn't a good way to know if the queue is full, we can request a restart if we are not receiving data when the user is expecting some data. In the worst case, this will still restart it every 10 seconds as it used to do. If all of the subscribed channels get incoming data, restarting is delayed, thus reducing the likelihood of a freeze.
@laurensvalk
Copy link
Member Author

Also added a minor change to avoid setting advertising data if that data was already set.

This should help if users try to broadcast the same data in a tight loop over and over.

@laurensvalk
Copy link
Member Author

Results in pybricks/support#2206 are very promising, so let's merge this. We can further improve from here if further ideas for improvement are found.

@laurensvalk laurensvalk merged commit 8dea17f into master Jun 16, 2025
32 checks passed
@dlech dlech deleted the work branch June 16, 2025 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Technic Hub freezes when using ble.broadcast()

3 participants