Skip to content

Commit 3a5d824

Browse files
committed
pybricks.common.BLE: Implement observe_enable()
This allows users to toggle observing off and on so that they can alternate between observing and broadcasting. This results in better stability on Technic Hub which can lock up when simultaneous advertising and broadcasting. Fixes pybricks/support#1806
1 parent f47c21f commit 3a5d824

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
- Allow color objects to be iterated as h, s, v = color_object or indexed
1010
as color_object[0]. This allows access to these properties in block
1111
coding ([support#1661]).
12+
- Added `observe_enable` to the hub `BLE` class to selectively turn observing
13+
on and off, just like you can with broadcasting ([support#1806]).
1214

1315
### Changed
1416

@@ -32,6 +34,7 @@
3234
[support#1623]: https://github.com/pybricks/support/issues/1623
3335
[support#1661]: https://github.com/pybricks/support/issues/1661
3436
[support#1668]: https://github.com/pybricks/support/issues/1668
37+
[support#1806]: https://github.com/pybricks/support/issues/1806
3538
[support#1846]: https://github.com/pybricks/support/issues/1846
3639
[support#1858]: https://github.com/pybricks/support/issues/1858
3740
[support#1863]: https://github.com/pybricks/support/issues/1863

pybricks/common/pb_type_ble.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ static observed_data_t *observed_data;
4949
static uint8_t num_observed_data;
5050

5151
static pbio_task_t broadcast_task;
52+
static pbio_task_t toggle_observe_task;
5253

5354
typedef struct {
5455
mp_obj_base_t base;
5556
mp_obj_t broadcast_channel;
56-
pbio_task_t *broadcast_task;
5757
observed_data_t observed_data[];
5858
} pb_obj_BLE_t;
5959

@@ -306,8 +306,8 @@ static mp_obj_t pb_module_ble_broadcast(size_t n_args, const mp_obj_t *pos_args,
306306
pbio_set_uint16_le(&value.v.data[2], LEGO_CID);
307307
value.v.data[4] = mp_obj_get_int(self->broadcast_channel);
308308

309-
pbdrv_bluetooth_start_broadcasting(self->broadcast_task, &value.v);
310-
return pb_module_tools_pbio_task_wait_or_await(self->broadcast_task);
309+
pbdrv_bluetooth_start_broadcasting(&broadcast_task, &value.v);
310+
return pb_module_tools_pbio_task_wait_or_await(&broadcast_task);
311311
}
312312
static MP_DEFINE_CONST_FUN_OBJ_KW(pb_module_ble_broadcast_obj, 1, pb_module_ble_broadcast);
313313

@@ -406,7 +406,7 @@ static const observed_data_t *pb_module_ble_get_channel_data(mp_obj_t channel_in
406406
observed_data_t *ch_data = lookup_observed_data(channel);
407407

408408
if (!ch_data) {
409-
mp_raise_ValueError(MP_ERROR_TEXT("channel not allocated"));
409+
mp_raise_ValueError(MP_ERROR_TEXT("channel not configured"));
410410
}
411411

412412
// Reset the data if it is too old.
@@ -467,6 +467,28 @@ static mp_obj_t pb_module_ble_observe(mp_obj_t self_in, mp_obj_t channel_in) {
467467
}
468468
static MP_DEFINE_CONST_FUN_OBJ_2(pb_module_ble_observe_obj, pb_module_ble_observe);
469469

470+
/**
471+
* Enables or disable observing
472+
*
473+
* @param [in] self_in The BLE object.
474+
* @param [in] enable_in Thruthy to enable, falsy to disable.
475+
* @returns Awaitable.
476+
*/
477+
static mp_obj_t pb_module_ble_observe_enable(mp_obj_t self_in, mp_obj_t enable_in) {
478+
479+
if (num_observed_data == 0) {
480+
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("channel not configured"));
481+
}
482+
483+
if (mp_obj_is_true(enable_in)) {
484+
pbdrv_bluetooth_start_observing(&toggle_observe_task, handle_observe_event);
485+
} else {
486+
pbdrv_bluetooth_stop_observing(&toggle_observe_task);
487+
}
488+
return pb_module_tools_pbio_task_wait_or_await(&toggle_observe_task);
489+
}
490+
static MP_DEFINE_CONST_FUN_OBJ_2(pb_module_ble_observe_enable_obj, pb_module_ble_observe_enable);
491+
470492
/**
471493
* Retrieves the filtered RSSI signal strength of the given channel.
472494
*
@@ -496,6 +518,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(pb_module_ble_version_obj, pb_module_ble_versio
496518
static const mp_rom_map_elem_t common_BLE_locals_dict_table[] = {
497519
{ MP_ROM_QSTR(MP_QSTR_broadcast), MP_ROM_PTR(&pb_module_ble_broadcast_obj) },
498520
{ MP_ROM_QSTR(MP_QSTR_observe), MP_ROM_PTR(&pb_module_ble_observe_obj) },
521+
{ MP_ROM_QSTR(MP_QSTR_observe_enable), MP_ROM_PTR(&pb_module_ble_observe_enable_obj) },
499522
{ MP_ROM_QSTR(MP_QSTR_signal_strength), MP_ROM_PTR(&pb_module_ble_signal_strength_obj) },
500523
{ MP_ROM_QSTR(MP_QSTR_version), MP_ROM_PTR(&pb_module_ble_version_obj) },
501524
};
@@ -519,6 +542,7 @@ static MP_DEFINE_CONST_OBJ_TYPE(pb_type_BLE,
519542
mp_obj_t pb_type_BLE_new(mp_obj_t broadcast_channel_in, mp_obj_t observe_channels_in) {
520543
// making the assumption that this is only called once before each pb_type_ble_start_cleanup()
521544
assert(observed_data == NULL);
545+
pb_module_tools_assert_blocking();
522546

523547
// Validate channel arguments.
524548
if (broadcast_channel_in != mp_const_none && (mp_obj_get_int(broadcast_channel_in) < 0 || mp_obj_get_int(broadcast_channel_in) > UINT8_MAX)) {
@@ -537,7 +561,6 @@ mp_obj_t pb_type_BLE_new(mp_obj_t broadcast_channel_in, mp_obj_t observe_channel
537561
#endif // PBSYS_CONFIG_BLUETOOTH_TOGGLE
538562

539563
pb_obj_BLE_t *self = mp_obj_malloc_var(pb_obj_BLE_t, observed_data_t, num_observe_channels, &pb_type_BLE);
540-
self->broadcast_task = &broadcast_task;
541564
self->broadcast_channel = broadcast_channel_in;
542565

543566
for (mp_int_t i = 0; i < num_observe_channels; i++) {
@@ -559,11 +582,9 @@ mp_obj_t pb_type_BLE_new(mp_obj_t broadcast_channel_in, mp_obj_t observe_channel
559582
observed_data = self->observed_data;
560583
num_observed_data = num_observe_channels;
561584

562-
// Start observing.
585+
// Start observing right away by default.
563586
if (num_observe_channels > 0) {
564-
pbio_task_t task;
565-
pbdrv_bluetooth_start_observing(&task, handle_observe_event);
566-
pb_module_tools_pbio_task_do_blocking(&task, -1);
587+
pb_module_ble_observe_enable(MP_OBJ_FROM_PTR(self), mp_const_true);
567588
}
568589

569590
return MP_OBJ_FROM_PTR(self);
@@ -576,7 +597,7 @@ void pb_type_ble_start_cleanup(void) {
576597
pbdrv_bluetooth_stop_observing(&stop_observing_task);
577598
observed_data = NULL;
578599
num_observed_data = 0;
579-
// Tasks awaited in pybricks de-init.
600+
// The aforementioned tasks started here are awaited in pybricks de-init.
580601
}
581602

582603
#endif // PYBRICKS_PY_COMMON_BLE

0 commit comments

Comments
 (0)