Building on the Motor and BitBot classes, I decided to build a remote control for the bitbot so I can drive it using the radio rather than using hard-coded commands.

Remote Control

I decided on single command characters for each direction and to record the last action so that we don't spam the receiver with a stream of too many commands when nothing has really changed.

Tilting the remote control forwards and backwards will send 'forward' and 'back' commands and tilting left and right will move as you would expect. With the microbit held in two hands, game controller style, and the usb port facing away from you, x tilt is left and right and y tilt is forwards and back.

I applied a threshold to the tilt because it's difficult to maintain the remote at exactly zero x and y tilt due to natural wobble in your hands. Because the bitbot will continue in one direction until given another command, I made pressing a button or flattening the controller the command for 'stop'.


# Bitbot remote control
from microbit import *
import radio

tilt_threshold = 250
forward_command = 'F'
stop_command = 'S'
left_command = 'L'
right_command = 'R'
reverse_command = 'B'
fast_command = 'Z'
slow_command = 'W'

radio.on()

last_action = ''

while True:
    
    action = ''
    
    if button_a.was_pressed():
        action = fast_command
    elif button_b.was_pressed():
        action = slow_command
    else:
        side_to_side = accelerometer.get_x()
        forward_back = accelerometer.get_y()
        
        if forward_back < -tilt_threshold:
            display.show(Image.ARROW_N)
            action = forward_command
        elif forward_back > tilt_threshold:
            display.show(Image.ARROW_S)
            action = reverse_command
        elif side_to_side > tilt_threshold:
            display.show(Image.ARROW_E)
            action = right_command
        elif side_to_side < -tilt_threshold:
            display.show(Image.ARROW_W)
            action = left_command
        else:
            display.show(Image.SQUARE_SMALL)
            action = stop_command
            
    if action != last_action:
        radio.send(action)
        last_action = action 
        
    sleep(500)
    

BitBot

The hard work is mostly done by the remote and the motor control classes from last time. In the bitbot, we just check for a new command and react to it with directions.


# Bitbot RC 
from microbit import *
import radio

# bitbot classes go here...

forward_command = 'F'
stop_command = 'S'
left_command = 'L'
right_command = 'R'
reverse_command = 'B'
fast_command = 'Z'
slow_command = 'W'

motor_speed_percent = 50

bitbot = BitBot()

sleep(move_duration)

radio.on()

while True:
    
    received = radio.receive()
  
    if received:
        if received == stop_command:
            bitbot.stop()
        elif received == forward_command:
            bitbot.forward(motor_speed_percent)
        elif received == reverse_command:
            bitbot.reverse(motor_speed_percent)
        elif received == left_command:
            bitbot.circle_left(motor_speed_percent)
        elif received == right_command:
            bitbot.circle_right(motor_speed_percent)
         elif received == slow_command:
            motor_speed_percent = max(motor_speed_percent - 25, 0)
        elif received == fast_command:
            motor_speed_percent = min(motor_speed_percent + 25, 100)
            
    sleep(100)

Helpful in debugging the tilting directions and thresholds, and in checking that the remote control and the bitbot were both in sync, I made sure that both units displayed icons corresponding to the command they were sending or receiving. Arrows for each direction and a square for stop and as long as both units are displaying the same icon we know everything is good.

The last feature we added more recently. Instead of driving at a constant speed forward and reverse, we designated two other commands - Z and W - to select between faZt and sloW speeds. Pressing one of the remote buttons speeds up the driving, pressing the other slows it down.