Remote control for Control+ sets without an app or smartphone – Pybricks

Update 9/3/2022 – please use the code below in the standard environment of Pybricks, not in the beta one.

One of the most frequent complaints about the Powered Up system is the need to have a smart device constantly for control, and you can only use touch controls with the official Control+ app. Even if you change touch control for the remote, you still need to run the Powered Up app all the time.

Here comes Pybricks – a custom coding environment for Powered Up devices that allows you to run code on the hub itself. Sounds complicated? It isn’t, no coding required to give it a try! Here are all the details in my video:

Here is the modified code used for the 42124 Off-Road buggy with the remote:

from pybricks.pupdevices import Motor, Remote
from pybricks.parameters import Port, Direction, Stop, Button
from pybricks.tools import wait

# Initialize the motors.
steer = Motor(Port.B)
front = Motor(Port.A, Direction.COUNTERCLOCKWISE)

# Connect to the remote.
remote = Remote()

# Read the current settings
old_kp, old_ki, old_kd, _, _ = steer.control.pid()

# Set new values
steer.control.pid(kp=old_kp*4, kd=old_kd*0.4)

# Find the steering endpoint on the left and right.
# The middle is in between.
left_end = steer.run_until_stalled(-200, then=Stop.HOLD)
right_end = steer.run_until_stalled(200, then=Stop.HOLD)

# We are now at the right. Reset this angle to be half the difference.
# That puts zero in the middle.
steer.reset_angle((right_end - left_end)/2)
steer.run_target(speed=200, target_angle=0, wait=False)

# Set steering angle for the buggy
steer_angle = (((right_end - left_end)/2)-5)
print('steer angle:',steer_angle)

# Now we can start driving!
while True:
    # Check which buttons are pressed.
    pressed = remote.buttons.pressed()

    # Choose the steer angle based on the right controls.

    if Button.RIGHT_PLUS in pressed:
        steer.run_target(1400, -steer_angle, Stop.HOLD, False)
    elif Button.RIGHT_MINUS in pressed:
        steer.run_target(1400, steer_angle, Stop.HOLD, False)
    else:
        steer.track_target(0)

    # Choose the drive speed based on the left controls.
    drive_speed = 0
    if Button.LEFT_PLUS in pressed:
        drive_speed += 100
    if Button.LEFT_MINUS in pressed:
        drive_speed -= 100

    # Apply the selected speed.
    front.dc(drive_speed)

    # Wait.
    wait(10)

And here is the code for the 42129 4×4 Mercedes-Benz Zetros Trial Truck with the remote:

from pybricks.pupdevices import Motor, DCMotor, Remote
from pybricks.parameters import Port, Direction, Stop, Button, Color
from pybricks.hubs import TechnicHub
from pybricks.tools import wait

# Initialize the motors.
steer = Motor(Port.D)
drive1 = Motor(Port.B)
drive2 = Motor(Port.A)
diff_control = DCMotor(Port.C)

# Initialize the hub.
hub = TechnicHub()

# Connect to the remote.
remote = Remote()

# Read the current settings
old_kp, old_ki, old_kd, _, _ = steer.control.pid()

# Set new values
steer.control.pid(kp=old_kp*4, kd=old_kd*0.8)

#Set the differential lock in open position
diff_control.dc(100)
wait(400)
diff_control.brake()

hub.light.on(Color.GREEN)
hublight = 0

# Find the steering endpoint on the left and right.
# The middle is in between.
left_end = steer.run_until_stalled(-500, then=Stop.HOLD)
right_end = steer.run_until_stalled(500, then=Stop.HOLD)

# We are now at the right. Reset this angle to be half the difference.
# That puts zero in the middle.
steer.reset_angle((right_end - left_end)/2)
steer.run_target(speed=200, target_angle=0, wait=False)

# Set steering angle for the Zetros
steer_angle = (((right_end - left_end)/2)+5)

# Now we can start driving!
while True:
    # Check which buttons are pressed.
    pressed = remote.buttons.pressed()

    # Choose the steer angle based on the right controls.

    if Button.RIGHT_PLUS in pressed:
        steer.run_target(1400, -steer_angle, Stop.HOLD, False)
    elif Button.RIGHT_MINUS in pressed:
        steer.run_target(1400, steer_angle, Stop.HOLD, False)
    else:
        steer.track_target(0)

    # Choose the drive speed based on the left controls.
    drive_speed = 0
    if Button.LEFT_PLUS in pressed:
        drive_speed += 100
    if Button.LEFT_MINUS in pressed:
        drive_speed -= 100
    if Button.LEFT in pressed:
        print('Battery voltage:',(hub.battery.voltage())/1000,"V")
        wait(100)


    # Apply the selected speed.
    drive1.dc(drive_speed)
    drive2.dc(drive_speed)

    if (Button.RIGHT in pressed) and (hublight == 0):
        hublight = 1
        diff_control.dc(-100)
        wait(400)
        diff_control.brake()
        hub.light.on(Color.RED)
        
    
    elif (Button.RIGHT in pressed) and (hublight == 1):
        diff_control.dc(100)
        wait(400)
        diff_control.brake()
        hub.light.on(Color.GREEN)
        hublight = 0

    # Wait.
    wait(10)

24 Comments:

  1. can Eny 1 help me

  2. Pingback: Remote control for Control+ sets without an app/smartphone – Pybricks – iGamezone

  3. Hello, Balazs!
    I want to add light to my buggy 42124. I would be very grateful for your help in finalizing the code so that another port (C or D) can be used to turn on and off the light with a button on the remote control.
    Thank you in advance!

  4. Hi, here is a documentation from pybricks
    https://docs.pybricks.com/en/stable/pupdevices/light.html

    You have to import “Light”, then you can use it like this:

    lights = Light(Port.C)
    lights_on = False

    #this should land in “while True” loop
    if Button.LEFT in pressed:
    if (lights_on):
    lights_on = False
    lights.off()
    else:
    lights_on = True
    lights.on(100)
    wait(250)

  5. Huge thanks!

  6. This is very exciting! Are there any other controls that can be used – or can you point me toward documentation about what controls can be used? I’d like to find an option with proportional inputs if possible.

  7. Hi, I’m trying these. But when trying to install I get these message in pybrick coding environment :

    Traceback (most recent call last):
    File “main.py”, line 1, in
    ImportError: can’t import name Remote

    Do you know what might be the issue?

  8. Just tried the beta, now I’m getting:

    Traceback (most recent call last):
    File “main.py”, line 10, in
    OSError: [Errno 116] ETIMEDOUT

  9. Hi everyone!

    first of all, many thanks to all the people that take the time to program, experiment and share their findings with everybody.

    I programmed my son’s Buggy and works great.

    One thing I have tried and not completely be able to have it working is to change the color of the remote light when it is connected to the car.
    I want to change it to green following the code here https://docs.pybricks.com/en/stable/pupdevices/remote.html. I think I put the code in the wrong place of the program.

    Any little help will be appreciated!

    Many thanks in advance

    Cheers!

  10. How can i turn my Control+ hub to change colors when pressing a button?

  11. Hi, has anyone tried pybricks to control the liebherr excavator? Again keen to move away from smartphone.

  12. Thanks for a clear tutorial on how to start with pybricks. I was able to us the custom code on my off-rood buggy, but I seem to have issues with the steer.track_target(0) command when resetting to 0 steering angle. At first the program woks, but after steering a couple of times it starts to bounce back between left and right without pressing any button. I have to admit it looks comical, but makes steering impossible. After steering to one side for a while it usually stops, but only after some seconds. I assume it’s trying to find the 0 spot, but keeps overshooting. I replaced that line with a run_target for now.

  13. is there a tutorial for custom code

  14. Can this be connected to a PS/Xbox controller?

  15. Szia BalƔzs!
    SegƭtsƩgedet szeretnƩm kƩrni!
    MĆ”r a firmware telepĆ­tĆ©snĆ©l elakadtam,kƶvettem a videĆ³dban az utasĆ­tĆ”sokat lila fĆ©ny villog utĆ”na elkezdi a firmware telepĆ­tĆ©sĆ©t zƶld,piros,kĆ©k fĆ©ny kis idő mĆŗlva hiba Ć¼zenet:Error: Failed to execute ‘getPrimaryService’ on ‘BluetoothRemoteGATTServer’: GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
    at https://code.pybricks.com/static/js/main.a3e3d8b4.js:2:1479169
    Ɖs itt elakadtam mindĆ­g ez a hiba Ć¼zenet vĆ”r akĆ”rhĆ”nyszor prĆ³bĆ”lkozom,Ć©s nem tudom,hogy hol a baj.
    VĆ”laszodat előre is kƶszƶnƶm!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.