Radio Control

In this example, we'll utilize the micro:bits' abilities to communicate with one another, as well as the built-in buttons to control our RVR+/RVR wirelessly! We'll give the RVR+/RVR its own micro:bit and use a second micro:bit as a controller to cut the physical ties between the RVR+/RVR and that which is controlling it.

This example should take about 45 min to go through before you are ready to hit the road!

If you haven't already set up your micro:bit and favorite editor, it's probably best to take care of that before jumping in here. Feel free to check out our Getting Started docs on:

Hardware Setup (Parts List)

If you want to build your own Radio Control RVR+/RVR, you will need the following parts (most of them are included in this nifty "inventor's" kit from SparkFun):

Software Setup

The code is divided into two folders: transmitter and receiver. Let's explore the code a bit and then we'll walk through how to flash the code to the respective micro:bits.

The Code

Transmitter

Let's get started with our imports. One of the coolest things about micro:bit is that it has (A and B) buttons built in, so you don't need additional components to be able to give it inputs. This allows us to use the micro:bit, itself, as our "transmitter".

We'll import the buttons, so that we can use them for our code and will also be using the display on the micro:bit, so we'll import display and image, too:

import radio

from microbit import button_a

from microbit import button_b

from microbit import display

from microbit import Image


We start by configuring the radio (so the micro:bits can talk to each other):

radio.config(group=1)

radio.on()


And initiating that neither button is being pressed at the start of the program:

a_pressed = False

b_pressed = False


The control code is simple. We start by setting the values of the variables we initiated earlier (a_pressed and b_pressed) to functions that trigger when a button on the micro:bit is pressed (is_pressed).

If only A is pressed, we will display an arrow for the direction the RVR+/RVR will head in ('W' or left) on the micro:bit and will send a string of 'a_pressed' to the receiver (we'll address how the receiver interprets that string in the next section).

In the next bit of logic (if the previous was untrue), if only B is pressed, we will display an arrow for the direction the RVR+/RVR will head in ('E' or right) on the micro:bit and will send a string of 'b_pressed' to the receiver.

If neither of those pieces of logic were true, we check if both A and B are pressed then we display an arrow for the direction the RVR+/RVR will head in ('N' or forward) and send a string of 'ab_pressed' to the receiver.

Our final condition is for the case in which all buttons have been released, in which case, the micro:bit displays a downward arrow (signified by the letter 'S') and a string of 'not_pressed' is sent to the receiver:

while True:

    a_pressed = button_a.is_pressed()

    b_pressed = button_b.is_pressed()


    if a_pressed and not b_pressed:

        display.show(Image.ARROW_W)

        radio.send('a_pressed')

    elif not a_pressed and b_pressed:

        display.show(Image.ARROW_E)

        radio.send('b_pressed')

    elif a_pressed and b_pressed:

        radio.send('ab_pressed')

        display.show(Image.ARROW_N)

    else:

        radio.send('not_pressed')

        display.show(Image.ARROW_S)


Now that we've gotten that sorted out, let's dive in to the receiver code...

Receiver

Let's get started with our imports. We'll be using the display on the micro:bit, so we'll import display and image and this is where we'll actually make the RVR+/RVR drive, so we also import RVRDrive from sphero:

import radio

from microbit import display

from microbit import Image

from microbit import sleep

from sphero import RVRDrive


Once again, we'll configure the radio (so the micro:bits can talk to each other), and we'll also set the RVR's "compass" so it's current direction is "forward":

radio.config(group=1)

radio.on()

RVRDrive.reset_yaw()


We'll initialize all our parameters, stating that the RVR+/RVR is not moving and is facing forward. We'll also set the rates for how fast the RVR+/RVR turns, how fast it accelerates and how quickly it decelerates:

speed = 0

heading = 0

turn_rate = 5

accel_rate = 10

decel_rate = 20


Now for the meat of the code! One of the very first things we do is prepare to receive the strings sent by the transmitter and store them in a variable called data. In our logic, we check the string sent by the transmitter and adjust the speed and heading accordingly:

In our next logic block, we ensure that the speed does not dip below 0 or go above 225.

In our final logic block, we also keep the heading between the bounds of 0 and 359 (because 360 is the same as 0).

Once all of the data has been collected, we have the RVR+/RVR drive in the heading we landed on at the speed we landed on:

while True:

    data = radio.receive()


    if data != None and data == 'a_pressed':

        display.show(Image.ARROW_W)

        heading -= turn_rate

        speed -= turn_rate

    elif data != None and data == 'b_pressed':

        display.show(Image.ARROW_E)

        heading += turn_rate

        speed -= turn_rate

    elif data != None and data == 'ab_pressed':

        display.show(Image.ARROW_N)

        speed += accel_rate

    else:

        display.show(Image.ARROW_S)

        speed -= decel_rate


    if speed < 0:

        speed = 0

    elif speed > 255:

        speed = 255


    if heading > 359:

        heading = heading - 359

    elif heading < 0:

        heading = 359 - heading


    sleep(25)

    RVRDrive.drive(speed, heading)


Let's get flashy with it!

Flashing the Code

While we did just walk through the two code files specific to this project in detail, it may be helpful to use the ones we have stored in our GitHub, since you'll also need our more generic sphero.py program to make the receiver work correctly. As you might have guessed, the code contained within each (transmitter or receiver) folder gets loaded onto the micro:bit you want to act as the either transmitter or receiver.

There are a couple of ways to compile and load code onto a micro:bit. We recommend using the micro:bit Python Editor to flash Python code onto your micro:bit. See detailed instructions on our micro:bit Python Setup page. 

Hardware Setup (Plugging Everything In)

We have two assemblies to complete, one for the RVR+/RVR and one for the controller...

The RVR+/RVR

To complete the RVR+/RVR setup, you need only connect your receiver micro:bit to your RVR+/RVR using the Data-Enabled Micro B USB cable:


The Controller

For the controller (transmitter), just pop your batteries into your battery pack and plug it in to the JST connection port on your micro:bit:


You Did It!!

Once both micro:bits are powered, they will both display an arrow pointing down; this means you are ready to roll!

Driving Controls:

Now What?

Try to improve your Radio Controlled RVR+/RVR! Here are some ideas to get you started: