Add touch sensor support for Powered Up platform#454
Conversation
|
Wow, it actually worked on the first try! from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port
from pybricks.tools import wait
device = PUPDevice(Port.B)
# Should print 5 for touch sensor
print(device.info())
while True:
# prints True when pressed, otherwise False
print(device.read(0))
wait(500) |
|
Required wiring:
|
| lego_device_type_id_t type_id = LEGO_DEVICE_TYPE_ID_ANY_DC_MOTOR; | ||
| // Check for touch sensor first. | ||
| lego_device_type_id_t type_id = LEGO_DEVICE_TYPE_ID_LPF2_TOUCH; | ||
| pbio_error_t err = pbio_port_dcm_assert_type_id(pbio_port_dcm_init_instance(port_id - PBIO_PORT_ID_A), &type_id); |
There was a problem hiding this comment.
Ew 😄
Could assert getting an analog value, which will assert the type without resetting the dcm.
pbio_port_get_analog_value(pbio_port_t *port, lego_device_type_id_t type_id, bool active, uint32_t *value)
There was a problem hiding this comment.
Fixed in c429735. Now using pbio_port_get_analog_value() instead of directly accessing the dcm.
|
Impressive! Heh, I guess we have fairly good abstractions. 🙈 I've been wondering if we should have an |
|
@copilot fix this comment and ignore all other comments. |
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
I'm planning to try this out this week. |
c429735 to
628d3d2
Compare
|
Fixed a few more cleanups and mistakes. Another caveat that would have introduced a subtle bug is that reading passive devices does not return an awaitable in async mode. I'm kind of inclined to leave it that way and add a comment instead. I don't think this feature will be used much. |
Wouldn't that break using it with block coding? Do we have a |
20cff21 to
9cd734b
Compare
|
I added the async handling. |
|
Thank you!
I've added a commit with a generic |
7c34485 to
f51c623
Compare
|
Please ignore if this is too soon to report: While trying the old V2 syntax descriptions: from pybricks.hubs import EV3Brick
from pybricks.tools import wait, multitask, run_task
from pybricks.parameters import Color, Direction, Port, Stop
from pybricks.nxtdevices import Motor, TouchSensor, ColorSensor, LightSensor, UltrasonicSensor
hub = EV3Brick()
# define variables used in the doc
color = Color.GREEN # EV3 only has RED GREEN and ORANGE
ts = TouchSensor(Port.S1)
print(f"TouchSensor is {ts}")
for x in dir(ts):
if not x.startswith("__"):
print("\t", x)
for i in range(5):
print(f"ts.pressed() {ts.pressed()}")
wait(500)Output on firmware If the sensor is attached, the output is OK. |
Nothing is too soon, but Powered Up is also completely unrelated to NXT. Please open dedicated issues for separate things. We will lose track otherwise. If in doubt, just open it separately anyway. Closing duplicates is easier than untangling differences :) And that is the correct behavior since not all NXT Touch Sensors are detectable, so you'd want that to pass. |
|
Thanks Laurens. |
| .parent_obj = ret_obj, | ||
| .iter_once = pb_type_async_constant_iter_once, | ||
| .return_map = pb_type_async_constant_return_map, | ||
| .state = 0, |
There was a problem hiding this comment.
| .state = 0, |
Technically not needed.
There was a problem hiding this comment.
I'd like to make it explicit here since state isn't always zeroed in the config. In some, it is set to the protothread state at the first yield.
pybricks/tools/pb_type_async.c
Outdated
| * re-used, otherwise assigned newly allocated object. | ||
| * @returns An awaitable if the runloop is active, otherwise the constant return value. | ||
| */ | ||
| mp_obj_t pb_type_async_return_constant(mp_obj_t ret_obj, pb_type_async_t **prev) { |
There was a problem hiding this comment.
| mp_obj_t pb_type_async_return_constant(mp_obj_t ret_obj, pb_type_async_t **prev) { | |
| mp_obj_t pb_type_async_return_obj(mp_obj_t ret_obj, pb_type_async_t **prev) { |
It doesn't need to be a constant. Any object will work.
| mp_obj_t pb_type_async_return_constant(mp_obj_t ret_obj, pb_type_async_t **prev) { | |
| mp_obj_t pb_type_async_return_result(mp_obj_t result_obj, pb_type_async_t **prev) { |
Another alternative.
There was a problem hiding this comment.
Thanks. Will update and merge tomorrow. I was thinking constant just for the name in terms of just returning the given value without any more changes or awaiting, but yes, object is a better name.
Async usage still works. |
Co-authored-by: Laurens Valk <laurens@pybricks.com>
We have a few functions with this structure:
async def some_func():
if simple_case:
# This commits adds a helper to do this:
return some_constant
return await some_awaitable_operation()
Also apply this to the touch sensor value of the Powered Up device.
f51c623 to
c31d077
Compare
Touch Sensor Support on Powered Up Platform
Changes Completed:
sensor_datafield tostruct _pbio_port_dcm_tinlib/pbio/src/port_dcm_pup.cpbio_port_dcm_thread()to read touch sensor value and store itpbio_port_dcm_get_analog_value()to returndcm->sensor_datapbio_port_dcm_assert_type_id()to handle touch sensor typepybricks/iodevices/pb_type_iodevices_pupdevice.cmake -C bricks/technichubImplementation Details:
C Library Changes (lib/pbio/src/port_dcm_pup.c):
uint32_t sensor_datafield tostruct _pbio_port_dcm_tto store touch sensor readingspbio_port_dcm_thread()to read touch sensor value from GPIO pin p5 and store it indcm->sensor_datapbio_port_dcm_get_analog_value()to return the storedsensor_datavalueLEGO_DEVICE_TYPE_ID_LPF2_TOUCHcase topbio_port_dcm_assert_type_id()to properly detect touch sensorsPython Bindings (pybricks/iodevices/pb_type_iodevices_pupdevice.c):
passive_portfield toiodevices_PUPDevice_obj_tto store port reference for passive devicesinit_passive_pup_device()to check for touch sensor usingpbio_port_get_analog_value()(proper abstraction)iodevices_PUPDevice_read()to handle touch sensor reads by callingpbio_port_get_analog_value()Build Status:
✅ Successfully builds for technichub platform
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.