Remote Control
Invent Logo

We're now going to remote-control our robot! Your remote control is a complete computer module that can be programmed just like the main module of the Invent! robot. It doesn't have a speaker or the left and right LEDs, but is perfect for controlling other devices wirelessly.

We'll write a program on the remote to send key presses to the robot and we'll write a program on the robot to receive them and move in the desired direction.

On the left of your remote are 4 buttons for moving up, down, left and right.

Remote Control
The A and B buttons

On the right of your remote are two more buttons labelled 'A' and 'B'. You can use them for whatever you want - perhaps one as a 'Turbo' button to go faster!

The A and B buttons
Powering on

First turn on the remote control by sliding the power button to the right.

Just like your robot, your remote control should be configured either to connect to your WiFi network (in which case the 'Stat' LED will turn red and then green), or act as an access point and create its own WiFi network (and the LED will turn blue).

Powering on
Connecting

We won't explain how to connect to the remote as it is identical to connecting to the robot but make sure if you are using the 'WiFi' mode to connect to an existing WiFi network you enter the 6-character code for the remote control instead of the robot when you want to write a program for it.

Hint: You might want to pop up another browser tab to program the remote control and leave the existing tab for programming the robot. This way you can swap between them if you need to later.

Connecting
Seeing how it works

You can use the 'Print' statement in an infinite loop to test out new things you've added like the line sensor or obstacle sensor.

Try out the gamepad buttons in the same way.

The gamepadbuttons() function gets the buttons that are pressed on the remote.

You should see that your test program prints things like 'U' if the up button is pressed, 'D' if the down button is pressed, 'L' for left and 'R' for right.

What happens when you press both the up and left button at the same time, or the down and the 'A' button?

from invent import *

while True:
  print(gamepadbuttons())
Multiple buttons

You should see that if you press up and right, then it will print 'UR'. If you press down and left, it will print 'DL'.

If you can actually physically hit more buttons at once, you might be able to get it to print something like 'URA' which means these three buttons are pressed!

What it's doing is returning a 'string' where the first character is 'U' or 'D', the second character is 'L' or 'R', and the next two characters are 'A' and 'B' (if these are pressed).

Useful combinations

This is a simple way of handling multiple buttons. We can't detect if up and down are both pressed at the same time (or left and right), but that really wouldn't make sense anyway.

However, being able to detect up and left could be useful. It could also be useful to detect when we're hitting in our 'turbo' button (A or B) at the same time as moving the robot.

We're now ready to write our program for the remote control to send the button presses to the robot ...

Useful combinations
The remote control program
ESPNow

Let's start by copying this bit of code to setup the remote. You will need to change the address to the one written on your robot.

'ESPNow' is a protocol (a way of communicating) that our main board can use to send messages directly between two devices. The 'espinit()' command initialises the communications system to get it ready.

The 'espaddpeer" command specifies which device we are connecting to. You'll need to enter the characters that are on the label on your robot. Previously we've just used the last 6 characters (the ones in bold), but this time you'll need all 12 characters starting with the 6 non-bold characters, then the 6 bold characters. Take care - if a single character is wrong, your code won't send the message to the right robot!

from invent import *

espinit()
espaddpeer("B0B21CF462EC")
The basic programme

Now add more code as shown.

Our basic code is fairly simple. We just need an infinite loop that sends the gamepad buttons to the robot. We'll do that about 20 times a second, so you'll need a 'delay 50 milliseconds' block. (50 milliseconds is 50 thousands of a second which is the same as 1/20th of a second).

from invent import *
import time

espinit()
espaddpeer("B0B21CF46590")
while True:
  espsend((gamepadbuttons()))
  time.sleep_ms(50)
Checking for changes of buttons

Actually, our program is a bit wasteful as we only have to send the buttons if something changes. To do this, we need to create a 'lastbuttons' variable and a 'buttons' variable (which will contain the currently pressed buttons), and compare the two. If they have changed, then we'll send the contents of the new 'buttons' variable.

This is what the code looks like. Modify yours to look the same. Can you see how it works?

Once you've written this program, make sure you save it, as we'll need it in a minute when we've written the robot's program that will receive these messages. Then create a new file which we will use for the robot code.

from invent import *
import time

espinit()
espaddpeer("B0B21CF46590")
lastbuttons = ''
while True:
  buttons = gamepadbuttons()
  if buttons != lastbuttons:
    espsend(buttons)
    lastbuttons = buttons
  time.sleep_ms(50)
The robot program

Here's the basic program that you need to create for the robot and how it works:

  • We continually try to receive a message into the 'packet' variable
  • If we have received a message, we check that it's length is 4 characters long (as our transmitter always sends 4 characters containing the buttons pressed)
  • If it is four characters, we check what's in the first and second letter of these characters (position zero and 1 as text strings count their first character as being in position zero), and move in an appropriate way.

Try running this code to move your robot. Remember to run the remote code from earlier as well.

from invent import *
import time


espinit()
while True:
  if espavail():
    packet = esprcv()
    if len(packet) == 4:
      if packet[0] == 'U':
        move(20,False)
      elif packet[0] == 'D':
        move((-20),False)
      elif packet[1] == 'L':
        spin(-1,False)
      elif packet[1] == 'R':
        spin(1,False)
       else:
        move(0,"false")
 
More advanced remote control

We're now going to modify our program so that the 'A' button makes it go into turbo mode. Can you work out how to do this? If you can, try it out now. If you need a tip, read on ...

Turbo mode code

Here is the robot code again with the turbo mode added.

The same if statements as before are used, but this time we have added on the extra if statement at the bottom. This increases the speed whilst the "A" button is held down.

from invent import *
import time

packet = None

espinit()
while True:
  if espavail():
    packet = esprcv()
    if len(packet) == 4:
      if packet[0] == 'U':
        move(20,False)
      elif packet[0] == 'D':
        move((-20),False)
      elif packet[1] == 'L':
        spin(-1,False)
      elif packet[1] == 'R':
        spin(1,False)
      else:
        move(0,"false")
      if packet[2] == 'A':
        speed(10)
      else:
        speed(5)
  time.sleep_ms(1)
Police chase

Now we're going to add a 'police chase' option to our robot using both lights and sounds!

Police chase
Adding lights

Your first task is to use the 'B' button to flash the two lights on the main board red and green for 'police mode'! You can decide how long the lights flash for when the button is pressed.

Hint: The 'B' button is the fourth character of the 'buttons pressed string ' (so position '3').

Adding lights
Adding sounds

Can you now add a siren sound? You can choose the sound you make. The easiest would be a two-tone alternating siren. Perhaps the tones can change in time with the lights flashing? If you really want a challenge, see if you can make one that sweeps up (or down) in pitch.

Hint: For a sweeping-pitch siren, you'll need to create a variable that increases (or decreases) every time through a loop, and then use that variable to control the frequency of the speaker!

Adding sounds
Advanced police chase

If you really want a challenge, can you modify your program so that the lights and siren work whilst driving?

This is a really tricky one! Any time you use a 'wait' block in your code, your program wills top being run until the wait block finishes, so you need to come up with a way that doesn't wait around for long.

Hint: One idea is to add a delay (small one - let's say 10 milliseconds), every time you go through the main loop. Then create a variable that goes up every time through the loop. Then using the contents of this variable you can determine the times you want things like lights or sounds to change.