-
-
Notifications
You must be signed in to change notification settings - Fork 7
Description
There are not any official LEGO touch sensors for Powered Up. However, from reverse engineering, we have seen that it was at least considered at some point. We can take advantage of this to allow people to make their own 3rd-party touch sensor.
Here is how we could do it:
The easy parts are that we need read data from the sensor. We just need to uncomment the last line here (from lib/pbio/src/port_dcm_pup.c):
// ID1 is inverse of touch sensor value
// TODO: save this value to sensor dcm
// sensor_data = !pbdrv_gpio_input(&pins->p5);And we need a way to get the data in Python which can be done with the following change:
diff --git a/pybricks/iodevices/pb_type_iodevices_pupdevice.c b/pybricks/iodevices/pb_type_iodevices_pupdevice.c
index f0da7c452..bb114b9a1 100644
--- a/pybricks/iodevices/pb_type_iodevices_pupdevice.c
+++ b/pybricks/iodevices/pb_type_iodevices_pupdevice.c
@@ -164,6 +164,11 @@ static mp_obj_t iodevices_PUPDevice_read(size_t n_args, const mp_obj_t *pos_args
iodevices_PUPDevice_obj_t, self,
PB_ARG_REQUIRED(mode));
+ if (self->passive_id == LEGO_DEVICE_TYPE_ID_LPF2_TOUCH) {
+ // TODO: replace `sensor_data` with actual reading from the touch sensor
+ return mp_obj_new_bool(sensor_data);
+ }
+
// Passive devices don't support reading.
if (self->passive_id != LEGO_DEVICE_TYPE_ID_LPF2_UNKNOWN_UART) {
pb_assert(PBIO_ERROR_INVALID_OP);The tricky part is that sensor_data is not defined and we need to figure out the correct way to pass data from one module to the other.
For example, we could add a uint32_t sensor_data; field to
struct _pbio_port_dcm_t {
/** Most recent one-off device ID candidate. */
lego_device_type_id_t type_id;
/** Previous one-off device ID candidate. */
lego_device_type_id_t prev_type_id;
/** Number of consecutive detections of the same device ID. */
uint8_t dev_id_match_count;
// Intermediate state values to preserve in between async calls.
dev_id_group_t dev_id1_group;
uint8_t gpio_value;
uint8_t prev_gpio_value;
};Then modify this function to return dcm->sensor_data;.
uint32_t pbio_port_dcm_get_analog_value(pbio_port_dcm_t *dcm, const pbdrv_ioport_pins_t *pins, bool active) {
return 0;
}And in iodevices_PUPDevice_read() replace sensor_data with a call to pbio_port_get_analog_value() to get that value.
Originally posted by @dlech in #2556 (reply in thread)