Maqueen PLUS V2.1 2 large red LEDs software control ?
DAVID.SELKIRK 2026-01-31 03:10:18 171 Views4 Replies I have purchased 15 Macqueen PLUS V2.1 robot cars to use as a teaching aid for 12-13 year olds in a school. I have been starting to play with it , but noticed early on that the extension library that I was using did not allow for control of the 2 large LEDs(headlights?) at the front? I have spent hours and hours trying different browsers, extensions, etc etc to no avail. So can anyone please advise me on this . Are these 2 large Red LEDs at the front actually software controlled and if so , what is the correct extension I should be installing (I tried about 3 different ones with no luck ) . appreciate any help on this Dave
The two large red LEDs on the Maqueen PLUS V2.1 can be controlled via software using set_headlights(True/False) in the MicroPython driver. Make sure you have the correct Maqueen V2 driver installed, initialize I2C with I2CInit(), and then use set_headlights() for the front lights and set_underglow() for the bottom RGB lights.
Hung.dol # Maqueen Plus V2 MicroPython driver (single-file)
# Tested with python.microbit.org v3 runtime on micro:bit V2
# Based on the register map from the DFRobot Maqueen Plus V2 MakeCode
# extension and community MicroPython ports. MIT-style.
from micropython import const
from microbit import i2c, display, Image, pin13, pin14, pin15, accelerometer, compass
from machine import time_pulse_us
from neopixel import NeoPixel
from time import sleep_ms, sleep_us, ticks_us
from math import sqrt, asin, cos, sin, atan2, pi
I2C_ADDR = const(0x10)
LEFT_MOTOR_REGISTER = const(0x00)
RIGHT_MOTOR_REGISTER = const(0x02)
LEFT_LED_REGISTER = const(0x0B)
RIGHT_LED_REGISTER = const(0x0C)
LINE_STATE_REGISTER = const(0x1D)
ADC0_REGISTER = const(0x1E)
ADC1_REGISTER = const(0x20)
ADC2_REGISTER = const(0x22)
ADC3_REGISTER = const(0x24)
ADC4_REGISTER = const(0x26)
VERSION_CNT_REGISTER = const(0x32)
VERSION_DATA_REGISTER = const(0x33)
class Motor:
LEFT = 0
RIGHT = 1
ALL = 2
class Direction:
FORWARD = 0
BACKWARD = 1
class Led:
LEFT = 0
RIGHT = 1
ALL = 2
class LineSensor:
L1 = 0
M = 1
R1 = 2
L2 = 3
R2 = 4
ALL = 5
class Color:
RED = 0xFF0000
ORANGE = 0xFFA500
YELLOW = 0xFFFF00
GREEN = 0x00FF00
BLUE = 0x0000FF
INDIGO = 0x4B0082
VIOLET = 0x8A2BE2
PURPLE = 0xFF00FF
WHITE = 0xFFFFFF
BLACK = 0x000000
class ColorLED:
L1 = 0
L2 = 1
R2 = 2
R1 = 3
ALL = 4
_np = NeoPixel(pin15, 4)
_brightness = 0xFF
_motor_calibration = [[], []]
_def_icon = Image('00000:00009:00090:90900:09000')
def I2CInit():
try:
i2c.write(I2C_ADDR, bytearray([VERSION_CNT_REGISTER]))
_ = i2c.read(I2C_ADDR, 1)
except Exception:
pass
display.show(_def_icon)
sleep_ms(400)
display.clear()
def rgb(r, g, b):
return (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF)
def led_rgb(color, led=ColorLED.ALL, brightness=None):
if brightness is None:
brightness = _brightness
r = (color >> 16) * (brightness / 255)
g = ((color >> 8) & 0xFF) * (brightness / 255)
b = (color & 0xFF) * (brightness / 255)
if led == ColorLED.ALL:
for i in range(4):
_np[i] = (int(r), int(g), int(b))
else:
if 0 <= led < 4:
_np[led] = (int(r), int(g), int(b))
_np.show()
def led_rgb_off(led=ColorLED.ALL):
if led < 0 or led > ColorLED.ALL:
led = ColorLED.ALL
led_rgb(Color.BLACK, led)
def _read_u8(reg):
i2c.write(I2C_ADDR, bytearray([reg]))
return i2c.read(I2C_ADDR, 1)[0]
def _read_u16(reg):
i2c.write(I2C_ADDR, bytearray([reg]))
b = i2c.read(I2C_ADDR, 2)
return (b[1] << 8) | b[0]
def line_sensor(sensor):
state = _read_u8(LINE_STATE_REGISTER)
vals = (
1 if (state & 0x10) else 0,
1 if (state & 0x08) else 0,
1 if (state & 0x04) else 0,
1 if (state & 0x02) else 0,
1 if (state & 0x01) else 0,
)
if sensor == LineSensor.ALL:
return vals
mapping = {
LineSensor.L2: 0,
LineSensor.L1: 1,
LineSensor.M: 2,
LineSensor.R1: 3,
LineSensor.R2: 4,
}
return vals[mapping[sensor]]
def line_sensor_all():
return line_sensor(LineSensor.ALL)
def line_sensor_data(sensor):
regs = [ADC0_REGISTER, ADC1_REGISTER, ADC2_REGISTER, ADC3_REGISTER, ADC4_REGISTER]
if sensor == LineSensor.ALL:
return tuple(_read_u16(r) for r in regs)
mapping = {
LineSensor.L2: 0,
LineSensor.L1: 1,
LineSensor.M: 2,
LineSensor.R1: 3,
LineSensor.R2: 4,
}
return _read_u16(regs[mapping[sensor]])
_heading_window_size = 1
_heading_buffer = [0.0]
_heading_index = 0
def mq_heading():
acc_raw = (accelerometer.get_x(), accelerometer.get_z(), -accelerometer.get_y())
mag_raw = (compass.get_x(), compass.get_z(), -compass.get_y())
acc_norm = sqrt(acc_raw[0]*acc_raw[0] + acc_raw[1]*acc_raw[1] + acc_raw[2]*acc_raw[2])
try:
acc_x = acc_raw[0]/acc_norm
acc_y = acc_raw[1]/acc_norm
pitch = asin(acc_x)
roll = -asin(acc_y / cos(pitch))
mag_x = mag_raw[0] * cos(pitch) + mag_raw[2] * sin(pitch)
mag_y = (mag_raw[0] * sin(roll) * sin(pitch) +
mag_raw[1] * cos(roll) -
mag_raw[2] * sin(roll) * cos(pitch))
heading = 180 * atan2(mag_y, mag_x) / pi
if heading < 0:
heading += 360
return heading
except Exception:
return 0
def heading_set_window_size(n=1):
global _heading_window_size, _heading_buffer, _heading_index
_heading_window_size = 1 if n < 1 else n
_heading_buffer = [0 for _ in range(_heading_window_size)]
_heading_index = 0
def _heading_append(val):
global _heading_index
_heading_buffer[_heading_index] = val
_heading_index = (_heading_index + 1) % _heading_window_size
def _heading_mean():
if _heading_window_size == 1:
return _heading_buffer[0]
return sum(_heading_buffer) / _heading_window_size
def heading_diff(h0, apply_window=True):
h = mq_heading()
if apply_window:
_heading_append(h)
cur = _heading_mean()
else:
cur = h
d = cur - h0
# wrap to [-180, 180]
while d > 180:
d -= 360
while d < -180:
d += 360
return d
# ########
def set_headlights(on, led=Led.ALL):
"""
2025-08-21
Don't confuse programmers with a meaningless name like 'led_red'.
We're setting headlights on and off.
"""
led_red(on, led)
def set_underglow(color, led=ColorLED.ALL ):
"""
2025-08-21
Don't confuse programmers with a meaningless name like 'led_rgb'; we're setting the
underglow's color.
"""
led_rgb(color, led)
# #######
from microbit import *
print("Starting...") # Change Starting to Wake up, dummy
I2CInit()
display.show(Image.HAPPY) # Change HAPPY TO DUCK
set_headlights(False)
set_underglow(Color.BLACK)
print("Press button_a to turn on both headlights.")
while not button_a.was_pressed():
sleep(100)
set_headlights(True)
print("Press button_a to make both headlights blink.")
while not button_a.was_pressed():
sleep(100)
for _ in range(5):
set_headlights(True)
sleep(500) # Change 500 to 100
set_headlights(False)
sleep(500)
print("Press button_a to signal a left turn.")
while not button_a.was_pressed():
sleep(100)
set_headlights(False)
for _ in range(0, 5):
set_headlights(True, led=Led.LEFT)
sleep(100) # Change 100 to 1000
set_headlights(False, led=Led.LEFT)
sleep(100)
print("Press button_a to signal a right turn.")
while not button_a.was_pressed():
sleep(100)
set_headlights(False)
for _ in range(0, 10):
set_headlights(True, led=Led.RIGHT)
sleep(100)
set_headlights(False, led=Led.RIGHT)
sleep(100)
print("Press button_a to make the bottom of the car red.")
while not button_a.was_pressed():
sleep(100)
set_underglow(Color.RED) # Change RED to GREEN
print("Press button_a to make the bottom of the car yellow.")
while not button_a.was_pressed():
sleep(100)
set_underglow(Color.YELLOW) # Change YELLOW to INDIGO
print("Press button_a to turn off the lights and end the program.")
while not button_a.was_pressed():
sleep(100)
set_headlights(False)
set_underglow(Color.BLACK)
display.clear()
print("Bye") # Change Bye to Shalom
print("")
# end of file
Eli.Lato i wrote a Maqueen course for my 5th and 6th graders. it's 100% free. you may find it helpful.
https://sites.google.com/view/englishwithcrazyeli/%D7%AA%D7%95%D7%9B%D7%A0%D7%99%D7%95%D7%AA-%D7%9C%D7%99%D7%9E%D7%95%D7%93-%D7%97%D7%99%D7%A0%D7%9E%D7%99%D7%95%D7%AA/%D7%AA%D7%9B%D7%A0%D7%95%D7%AA-%D7%9E%D7%97%D7%A9%D7%91%D7%99%D7%9D/robotics-with-microbit-the-maqueen-robot-car-and-python?authuser=0
Eli.Lato This is a fantastic resource. I’m sure the students will enjoy these lessons with the Maqueen robot. Appreciate you putting this together!!!


