Skip to content

Commit 421722b

Browse files
committed
bricks/ev3: Add Motor IR Control on apps tab.
1 parent a967db1 commit 421722b

9 files changed

Lines changed: 113 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Added `pybricks.pupdevices.MarioHub` to control it as a peripheral. It
99
cannot be used as a standalone device since it cannot ne updated.
1010
- Added `DriveBase.hold()` method ([support#2621]).
11+
- Added `Motor Button Control` and `Motor IR Control` on EV3 apps tab.
1112

1213
### Changed
1314
- The EV3 Color Sensor now returns `Color.NONE` instead of `None` when no color

bricks/_common/micropython.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ pbio_error_t pbsys_main_program_validate(pbsys_main_program_t *program) {
307307
#endif
308308
#if PBSYS_CONFIG_FEATURE_BUILTIN_USER_PROGRAM_EV3_APPS
309309
case PBIO_PYBRICKS_USER_PROGRAM_ID_EV3_MOTOR_BUTTON_CONTROL:
310+
case PBIO_PYBRICKS_USER_PROGRAM_ID_EV3_MOTOR_IR_CONTROL:
310311
return PBIO_SUCCESS;
311312
#endif
312313
default:
@@ -404,6 +405,10 @@ void pbsys_main_run_program(pbsys_main_program_t *program) {
404405
pb_package_pybricks_init(false);
405406
pyexec_frozen_module("_ev3_motor_button_control.py", false);
406407
break;
408+
case PBIO_PYBRICKS_USER_PROGRAM_ID_EV3_MOTOR_IR_CONTROL:
409+
pb_package_pybricks_init(false);
410+
pyexec_frozen_module("_ev3_motor_ir_control.py", false);
411+
break;
407412
#endif
408413

409414
default:

bricks/ev3/manifest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
include("../_common/manifest.py")
22
freeze_as_mpy("../ev3/modules", "_ev3_motor_button_control.py")
33
freeze_as_mpy("../ev3/modules", "_ev3_motor_dc.py")
4+
freeze_as_mpy("../ev3/modules", "_ev3_motor_ir_control.py")
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
from pybricks.tools import wait
2+
from pybricks.parameters import ImageFile, Button, Port, Color
3+
from pybricks.hubs import EV3Brick
4+
from pybricks.ev3devices import InfraredSensor
5+
6+
from _ev3_motor_dc import motor_set_dc
7+
8+
# Load assets.
9+
IMG_POS = ImageFile._ROTATE_CW18
10+
IMG_NEG = ImageFile._ROTATE_CCW18
11+
IMG_12 = ImageFile._APP_IR_CONTROL_12
12+
IMG_34 = ImageFile._APP_IR_CONTROL_34
13+
14+
# Power level for all motors when on.
15+
POWER = 100
16+
17+
# Load initial UI.
18+
center_was_pressed = False
19+
channel_12_active = True
20+
ev3 = EV3Brick()
21+
22+
23+
def draw_ui():
24+
ev3.screen.draw_image(0, 20, IMG_12 if channel_12_active else IMG_34)
25+
26+
27+
# Wait for sensor to be attached.
28+
draw_ui()
29+
sensor = None
30+
while sensor is None:
31+
try:
32+
sensor = InfraredSensor(Port.S4)
33+
sensor.buttons(1)
34+
except OSError:
35+
wait(10)
36+
37+
38+
# Exit if sensor is unplugged or program ends.
39+
while True:
40+
# Get button state for selected channel pair.
41+
channel_x = 1 if channel_12_active else 3
42+
channel_y = 2 if channel_12_active else 4
43+
pressed_x = sensor.buttons(channel_x)
44+
pressed_y = sensor.buttons(channel_y)
45+
46+
# Use tank drive to set power levels for each motor.
47+
power = [
48+
POWER
49+
if Button.LEFT_UP in pressed_y
50+
else -POWER
51+
if Button.LEFT_DOWN in pressed_y
52+
else 0,
53+
POWER
54+
if Button.LEFT_UP in pressed_x
55+
else -POWER
56+
if Button.LEFT_DOWN in pressed_x
57+
else 0,
58+
POWER
59+
if Button.RIGHT_UP in pressed_x
60+
else -POWER
61+
if Button.RIGHT_DOWN in pressed_x
62+
else 0,
63+
POWER
64+
if Button.RIGHT_UP in pressed_y
65+
else -POWER
66+
if Button.RIGHT_DOWN in pressed_y
67+
else 0,
68+
]
69+
70+
# Blink if power set, otherwise steady green.
71+
if any(power):
72+
ev3.light.blink(Color.GREEN, [100, 100, 800, 100])
73+
else:
74+
ev3.light.on(Color.GREEN)
75+
76+
# Apply power level to each motor, and draw visual indicator if moving.
77+
ev3.screen.draw_box(0, 0, 177, 16, fill=True, color=Color.WHITE)
78+
for m in range(len(power)):
79+
dc = motor_set_dc(m, power[m])
80+
if dc:
81+
ev3.screen.draw_image(20 + m * 40, 2, IMG_POS if dc > 0 else IMG_NEG)
82+
83+
# Keep moving until IR button state changes.
84+
while pressed_x == sensor.buttons(channel_x) and pressed_y == sensor.buttons(
85+
channel_y
86+
):
87+
wait(10)
88+
89+
# While we wait, monitor center button to change channels.
90+
if Button.CENTER not in ev3.buttons.pressed():
91+
center_was_pressed = False
92+
elif not center_was_pressed:
93+
# Pressed now but not before, so toggle channel and restart.
94+
center_was_pressed = True
95+
channel_12_active = not channel_12_active
96+
draw_ui()
97+
break

bricks/virtualhub/manifest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
include("../_common/manifest.py")
22
freeze_as_mpy("../ev3/modules", "_ev3_motor_button_control.py")
33
freeze_as_mpy("../ev3/modules", "_ev3_motor_dc.py")
4+
freeze_as_mpy("../ev3/modules", "_ev3_motor_ir_control.py")

lib/pbio/include/pbio/protocol.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ typedef enum {
7373
* Program to control EV3 motors with the buttons.
7474
*/
7575
PBIO_PYBRICKS_USER_PROGRAM_ID_EV3_MOTOR_BUTTON_CONTROL = 133,
76+
/**
77+
* Program to control EV3 motors with infrared remote.
78+
*/
79+
PBIO_PYBRICKS_USER_PROGRAM_ID_EV3_MOTOR_IR_CONTROL = 134,
7680
} pbio_pybricks_user_program_id_t;
7781

7882
/**
54.5 KB
Binary file not shown.
54.5 KB
Binary file not shown.

lib/pbio/sys/hmi_ev3_ui.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static pbsys_hmi_ev3_ui_t state;
8585
*/
8686
static const char *apps[] = {
8787
" Motor Button Control",
88+
" Motor IR Control",
8889
};
8990

9091
/**
@@ -283,6 +284,9 @@ pbsys_hmi_ev3_ui_action_t pbsys_hmi_ev3_ui_handle_button(pbio_button_flags_t but
283284
case 0:
284285
*payload = PBIO_PYBRICKS_USER_PROGRAM_ID_EV3_MOTOR_BUTTON_CONTROL;
285286
return PBSYS_HMI_EV3_UI_ACTION_RUN_PROGRAM;
287+
case 1:
288+
*payload = PBIO_PYBRICKS_USER_PROGRAM_ID_EV3_MOTOR_IR_CONTROL;
289+
return PBSYS_HMI_EV3_UI_ACTION_RUN_PROGRAM;
286290
default:
287291
// Other apps not yet implemented.
288292
state.overlay = PBSYS_HMI_EV3_UI_OVERLAY_COMING_SOON;

0 commit comments

Comments
 (0)