bricknil.sensor¶
Actual sensor and motor peripheral definitions from Boost and PoweredUp
Classes¶
Button (name[, port, capabilities]) |
Register to be notified of button presses on the Hub (Boost or PoweredUp) |
CurrentSensor (name[, port, capabilities]) |
Voltage sensor |
DuploSpeaker (name[, port, capabilities]) |
Plays one of five preset sounds through the Duplo built-in speaker |
DuploSpeedSensor (name[, port, capabilities]) |
Speedometer on Duplo train base that measures front wheel speed. |
DuploTrainMotor (name[, port, capabilities]) |
Train Motor on Duplo Trains |
DuploVisionSensor (name[, port, capabilities]) |
Access the Duplo Vision/Distance Sensor |
ExternalMotor (name[, port, capabilities]) |
Access the stand-alone Boost motors |
InternalMotor (name[, port, capabilities]) |
Access the internal motor(s) in the Boost Move Hub. |
InternalTiltSensor (name[, port, capabilities]) |
Access the internal tilt sensor in the Boost Move Hub. |
LED (name[, port, capabilities]) |
Changes the LED color on the Hubs. |
Light (name[, port, capabilities]) |
Connects to the external light. |
RemoteButtons (name[, port, capabilities]) |
Represents one set of ‘+’, ‘-‘, ‘red’ buttons on the PoweredHub Remote |
TrainMotor (name[, port, capabilities]) |
Connects to the train motors. |
VisionSensor (name[, port, capabilities]) |
Access the Boost Vision/Distance Sensor |
VoltageSensor (name[, port, capabilities]) |
Voltage sensor |
Members¶
-
class
bricknil.sensor.
InternalMotor
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.TachoMotor
Access the internal motor(s) in the Boost Move Hub.
Unlike the train motors, these motors (as well as the stand-alone Boost motors
ExternalMotor
) have a built-in sensor/tachometer for sending back the motor’s current speed and position. However, you don’t need to use the sensors, and can treat this motor strictly as an output device.Examples:
# Basic connection to the motor on Port A @attach(InternalMotor, name='left_motor', port=InternalMotor.Port.A) # Basic connection to both motors at the same time (virtual I/O port). # Any speed command will cause both motors to rotate at the same speed @attach(InternalMotor, name='motors', port=InternalMotor.Port.AB) # Report back when motor speed changes. You must have a motor_change method defined @attach(InternalMotor, name='motor', port=InternalMotor.Port.A, capabilities=['sense_speed']) # Only report back when speed change exceeds 5 units @attach(InternalMotor, name='motors', port=InternalMotor.Port.A, capabilities=[('sense_speed', 5)])
- And within the run body you can control the motor output::
- await self.motor.set_speed(50) # Setting the speed await self.motor.ramp_speed(80, 2000) # Ramp speed to 80 over 2 seconds await self.motor.set_pos(90, speed=20) # Turn clockwise to 3 o’clock position await self.motor.rotate(60, speed=-50) # Turn 60 degrees counter-clockwise from current position
See also
TrainMotor
for connecting to a train motorExternalMotor
for connecting to a train motor
Maps the port names A, B, AB to hard-coded port numbers
-
class
bricknil.sensor.
ExternalMotor
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.TachoMotor
Access the stand-alone Boost motors
These are similar to the
InternalMotor
with build-in tachometer and sensor for sending back the motor’s current speed and position. You don’t need to use the sensors, and can treat this as strictly an output.Examples:
# Basic connection to the motor on Port A @attach(ExternalMotor, name='motor') # Report back when motor speed changes. You must have a motor_change method defined @attach(ExternalMotor, name='motor', capabilities=['sense_speed']) # Only report back when speed change exceeds 5 units, and position changes (degrees) @attach(ExternalMotor, name='motor', capabilities=[('sense_speed', 5), 'sense_pos'])
And then within the run body:
await self.motor.set_speed(50) # Setting the speed await self.motor.ramp_speed(80, 2000) # Ramp speed to 80 over 2 seconds await self.motor.set_pos(90, speed=20) # Turn clockwise to 3 o'clock position await self.motor.rotate(60, speed=-50) # Turn 60 degrees counter-clockwise from current position
See also
TrainMotor
for connecting to a train motorInternalMotor
for connecting to the Boost hub built-in motors
-
class
bricknil.sensor.
VisionSensor
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Peripheral
Access the Boost Vision/Distance Sensor
Only the sensing capabilities of this sensor is supported right now.
- sense_color: Returns one of the 10 predefined colors
- sense_distance: Distance from 0-7 in roughly inches
- sense_count: Running count of waving your hand/item over the sensor (32-bit)
- sense_reflectivity: Under distances of one inch, the inverse of the distance
- sense_ambient: Distance under one inch (so inverse of the preceeding)
- sense_rgb: R, G, B values (3 sets of uint16)
Any combination of sense_color, sense_distance, sense_count, sense_reflectivity, and sense_rgb is supported.
Examples:
# Basic distance sensor @attach(VisionSensor, name='vision', capabilities=['sense_color']) # Or use the capability Enum @attach(VisionSensor, name='vision', capabilities=[VisionSensor.capability.sense_color]) # Distance and color sensor @attach(VisionSensor, name='vision', capabilities=['sense_color', 'sense_distance']) # Distance and rgb sensor with different thresholds to trigger updates @attach(VisionSensor, name='vision', capabilities=[('sense_color', 1), ('sense_rgb', 5)])
The values returned by the sensor will always be available in the instance variable self.value. For example, when the sense_color and sense_rgb capabilities are enabled, the following values will be stored and updated:
self.value = { VisionSensor.capability.sense_color: uint8, VisionSensor.capability.sense_rgb: [ uint16, uint16, uint16 ] }
Notes
The actual modes supported by the sensor are as follows:
- 0 = color (0-10)
- 1 = IR proximity (0-7)
- 2 = count (32-bit int)
- 3 = Reflt (inverse of distance when closer than 1”)
- 4 = Amb (distance when closer than 1”)
- 5 = COL (output) ?
- 6 = RGB I
- 7 = IR tx (output) ?
- 8 = combined: Color byte, Distance byte, 0xFF, Reflected light
-
class
capability
¶ Bases:
enum.Enum
An enumeration.
-
sense_ambient
= 4¶
-
sense_color
= 0¶
-
sense_count
= 2¶
-
sense_distance
= 1¶
-
sense_reflectivity
= 3¶
-
sense_rgb
= 6¶
-
-
datasets
= {<capability.sense_color: 0>: (1, 1), <capability.sense_distance: 1>: (1, 1), <capability.sense_count: 2>: (1, 4), <capability.sense_reflectivity: 3>: (1, 1), <capability.sense_ambient: 4>: (1, 1), <capability.sense_rgb: 6>: (3, 2)}¶
-
allowed_combo
= [<capability.sense_color: 0>, <capability.sense_distance: 1>, <capability.sense_count: 2>, <capability.sense_reflectivity: 3>, <capability.sense_rgb: 6>]¶
-
class
bricknil.sensor.
InternalTiltSensor
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Peripheral
Access the internal tilt sensor in the Boost Move Hub.
The various modes are:
- sense_angle - X, Y angles. Both are 0 if hub is lying flat with button up
- sense_tilt - value from 0-9 if hub is tilted around any of its axis. Seems to be a rough mesaure of how much the hub is tilted away from lying flat. There is no update for just a translation along an axis
- sense_orientation - returns one of the nine orientations below (0-9)
- InternalTiltSensor.orientation.up = flat with button on top
- InternalTiltSensor.orientation.right - standing up on side closest to button
- InternalTiltSensor.orientation.left - standing up on side furthest from button
- InternalTiltSensor.orientation.far_side - on long face facing away
- InternalTiltSensor.orientation.near_side - on long face facing you
- InternalTiltSensor.orientation.down - upside down
- sense_impact - 32-bit count of impacts to sensor
- sense_acceleration_3_axis - 3 bytes of raw accelerometer data.
Any combination of the above modes are allowed.
Examples:
# Basic tilt sensor @attach(InternalTiltSensor, name='tilt', capabilities=['sense_tilt']) # Or use the capability Enum @attach(InternalTiltSensor, name='tilt', capabilities=[InternalTiltSensor.sense_tilt]) # Tilt and orientation sensor @attach(InternalTiltSensor, name='tilt', capabilities=['sense_tilt, sense_orientation'])
The values returned by the sensor will always be available in the instance variable self.value. For example, when the sense_angle and sense_orientation capabilities are enabled, the following values will be stored and updated:
self.value = { InternalTiltSensor.capability.sense_angle: [uint8, uint8], InternalTiltSensor.capability.sense_orientation: Enum(InternalTiltSensor.orientation) }
-
class
capability
¶ Bases:
enum.Enum
An enumeration.
-
sense_acceleration_3_axis
= 4¶
-
sense_angle
= 0¶
-
sense_impact
= 3¶
-
sense_orientation
= 2¶
-
sense_tilt
= 1¶
-
-
datasets
= {<capability.sense_angle: 0>: (2, 1), <capability.sense_tilt: 1>: (1, 1), <capability.sense_orientation: 2>: (1, 1), <capability.sense_impact: 3>: (1, 4), <capability.sense_acceleration_3_axis: 4>: (3, 1)}¶
-
allowed_combo
= [<capability.sense_angle: 0>, <capability.sense_tilt: 1>, <capability.sense_orientation: 2>, <capability.sense_impact: 3>, <capability.sense_acceleration_3_axis: 4>]¶
-
class
bricknil.sensor.
LED
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Peripheral
Changes the LED color on the Hubs:
@attach(LED, name='hub_led')
self.hub_led.set_output(Color.red)
-
class
bricknil.sensor.
Light
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Peripheral
Connects to the external light.
Example:
@attach(Light, name='light')
And then within the run body, use:
await self.light.set_brightness(brightness)
-
class
bricknil.sensor.
TrainMotor
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Motor
Connects to the train motors.
TrainMotor has no sensing capabilities and only supports a single output mode that sets the speed.
Examples:
@attach(TrainMotor, name='train')
And then within the run body, use:
await self.train.set_speed(speed)
See also
-
class
bricknil.sensor.
RemoteButtons
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Peripheral
Represents one set of ‘+’, ‘-‘, ‘red’ buttons on the PoweredHub Remote
Each remote has two sets of buttons, on the left and right side. Pick the one your want to attach to by using the port argument with either Port.L or Port.R.
There are actually a few different modes that the hardware supports, but we are only going to use one of them called ‘KEYSD’ (see the notes in the documentation on the raw values reported by the hub). This mode makes the remote send three values back in a list. To access each button state, there are three helper methods provided (see below)
Examples:
# Basic connection to the left buttons @attach(RemoteButtons, name='left_buttons', port=RemoteButtons.Port.L) # Getting values back in the handler async def left_buttons_change(self): is_plus_pressed = self.left_buttons.plus_pressed() is_minus_pressed = self.left_buttons.minus_pressed() is_red_pressed = self.left_buttons.red_pressed()
Maps the port names L, R
-
class
Button
¶ Bases:
enum.IntEnum
The button index in the value list returned by the sensor
-
MINUS
= 2¶
-
PLUS
= 0¶
-
RED
= 1¶
-
-
datasets
= {<capability.sense_press: 4>: (3, 1)}¶
-
allowed_combo
= []¶
-
class
-
class
bricknil.sensor.
Button
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Peripheral
Register to be notified of button presses on the Hub (Boost or PoweredUp)
This is actually a slight hack, since the Hub button is not a peripheral that is attached like other sensors in the Lego protocol. Instead, the buttons are accessed through Hub property messages. We abstract away these special messages to make the button appear to be like any other peripheral sensor.
Examples:
@attach(Button, name='hub_btn')
Notes
Since there is no attach I/O message from the hub to trigger the
activate_updates()
method, we instead insert a fake “attaach” message from this fake sensor on port 255 in the BLEventQ.get_messages method that is used to register for updates from a given sensor.Call super-class with port set to 255
-
datasets
= {<capability.sense_press: 0>: (1, 1)}¶
-
allowed_combo
= [<capability.sense_press: 0>]¶
-
-
class
bricknil.sensor.
DuploTrainMotor
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Motor
Train Motor on Duplo Trains
Make sure that the train is sitting on the ground (the front wheels need to keep rotating) in order to keep the train motor powered. If you pick up the train, the motor will stop operating withina few seconds.
Examples:
@attach(DuploTrainMotor, name='motor')
And then within the run body, use:
await self.train.set_speed(speed)
See also
TrainMotor
for connecting to a PoweredUp train motor
-
class
bricknil.sensor.
DuploSpeedSensor
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Peripheral
Speedometer on Duplo train base that measures front wheel speed.
This can measure the following values:
- sense_speed: Returns the speed of the front wheels
- sense_count: Keeps count of the number of revolutions the front wheels have spun
Either or both can be enabled for measurement.
Examples:
# Report speed changes @attach(DuploSpeedSensor, name='speed_sensor', capabilities=['sense_speed']) # Report all @attach(DuploSpeedSensor, name='speed_sensor', capabilities=['sense_speed', 'sense_count'])
The values returned by the sensor will be in self.value. For the first example, get the current speed by:
speed = self.speed_sensor.value
For the second example, the two values will be in a dict:
speed = self.speed_sensor.value[DuploSpeedSensor.sense_speed] revs = self.speed_sensor.value[DuploSpeedSensor.sense_count]
-
datasets
= {<capability.sense_speed: 0>: (1, 2), <capability.sense_count: 1>: (1, 4)}¶
-
allowed_combo
= [<capability.sense_speed: 0>, <capability.sense_count: 1>]¶
-
class
bricknil.sensor.
DuploVisionSensor
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Peripheral
Access the Duplo Vision/Distance Sensor
- sense_color: Returns one of the 10 predefined colors
- sense_ctag: Returns one of the 10 predefined tags
- sense_reflectivity: Under distances of one inch, the inverse of the distance
- sense_rgb: R, G, B values (3 sets of uint16)
Any combination of sense_color, sense_ctag, sense_reflectivity, and sense_rgb is supported.
Examples:
# Basic color sensor @attach(DuploVisionSensor, name='vision', capabilities=['sense_color']) # Or use the capability Enum @attach(DuploVisionSensor, name='vision', capabilities=[DuploVisionSensor.capability.sense_color]) # Ctag and reflectivity sensor @attach(DuploVisionSensor, name='vision', capabilities=['sense_ctag', 'sense_reflectivity']) # Distance and rgb sensor with different thresholds to trigger updates @attach(DuploVisionSensor, name='vision', capabilities=[('sense_color', 1), ('sense_rgb', 5)])
The values returned by the sensor will always be available in the instance variable self.value. For example, when the sense_color and sense_rgb capabilities are enabled, the following values will be stored and updated:
self.value = { DuploVisionSensor.capability.sense_color: uint8, DuploVisionSensor.capability.sense_rgb: [ uint16, uint16, uint16 ] }
Notes
The actual modes supported by the sensor are as follows:
- 0 = color (0-10)
- 1 = ctag (32-bit int)
- 2 = Reflt (inverse of distance when closer than 1”)
- 3 = RGB I
-
class
capability
¶ Bases:
enum.Enum
An enumeration.
-
sense_color
= 0¶
-
sense_ctag
= 1¶
-
sense_reflectivity
= 2¶
-
sense_rgb
= 3¶
-
-
datasets
= {<capability.sense_color: 0>: (1, 1), <capability.sense_ctag: 1>: (1, 1), <capability.sense_reflectivity: 2>: (1, 1), <capability.sense_rgb: 3>: (3, 2)}¶
-
allowed_combo
= [<capability.sense_color: 0>, <capability.sense_ctag: 1>, <capability.sense_reflectivity: 2>, <capability.sense_rgb: 3>]¶
-
class
bricknil.sensor.
DuploSpeaker
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Peripheral
Plays one of five preset sounds through the Duplo built-in speaker
See
sounds
for the list.Examples:
@attach(DuploSpeaker, name='speaker') ... await self.speaker.play_sound(DuploSpeaker.sounds.brake)
Notes
Uses Mode 1 to play the presets
-
class
sounds
¶ Bases:
enum.Enum
An enumeration.
-
brake
= 3¶
-
horn
= 9¶
-
station
= 5¶
-
steam
= 10¶
-
water
= 7¶
-
-
class
-
class
bricknil.sensor.
VoltageSensor
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Peripheral
Voltage sensor
Returns the raw mV value (0-3893) which probably needs to be scaled to 0-9600.
It contains two capabilities, although they both appear to do the same thing: * sense_l * sense_s
Examples:
@attach(VoltageSensor, name='volts', capabilities=['sense_l'])
-
datasets
= {<capability.sense_s: 0>: (1, 2), <capability.sense_l: 1>: (1, 2)}¶
-
allowed_combo
= []¶
-
-
class
bricknil.sensor.
CurrentSensor
(name, port=None, capabilities=[])[source]¶ Bases:
bricknil.peripheral.Peripheral
Voltage sensor
Returns the raw mA value (0-4095) which probably needs to be scaled to 0-2444.
It contains two capabilities, although they both appear to do the same thing: * sense_l * sense_s
Examples:
@attach(CurrentSensor, name='cur', capabilities=['sense_l'])
-
datasets
= {<capability.sense_s: 0>: (1, 2), <capability.sense_l: 1>: (1, 2)}¶
-
allowed_combo
= []¶
-