Teaching the RCX VLL

Or: What that mysterious ‘P’ Program is for. This article covers what VLL is and how to make an RCX ‘speak’ it to a Micro Scout.

An RCX communicating with a Micro Scout

If you happen to own a Droid Developer Kit or Darkside Developer kit, you’ll have a Micro-Scout lying around. The Micro Scout is a mini pBrick with a built in motor and light sensor. The Micro Scout has 7 built in programs which do all sorts of fun stuff, but once you’ve exhausted their possibilities it can become a bit boring.

This is where the mysterious P program (After the 7th program) comes in. When P is selected, the Micro Scout goes into a state which allows it to receive commands, and even for 15 of those commands to be stored and ran as a customisable ‘program’. The signals are sent to the Micro Scout through it’s light sensor, as visible flashes of light.

Ingredients:

  • An RCX with firmware 1 or 2 installed
  • A Micro Scout
  • Some way of connecting a light source to an RCX out port

This guide assumes that you have set the RCX up and can download programs to it one way or the other. I will be using NQC programs, transmitted via MacNQC for demonstration purposes.

Some notes:

For technically minded people, there is a brilliant description of exactly what VLL is and how it works at Elecbrick. I am not well up on the workings of the binary signals, and Doug offers a much better explanation of how the technologies work than I could provide. If you just want to get it to work, however, stick with my tutorial.

Walkthrough:

Starting Off

My RCX to Micro Scout Hardware setup

The first step is to ensure that the light signals will be able to get from the RCX to the Micro Scout. I use the Mindstorms fibre-optic element and a single fibre with a cone on the end, which allows me to plug the fibre optic element into the micro scout as show. If you just have a lamp, you will need to hold it right next to the Micro Scout’s light sensor.

If you don’t have a Lego lamp of some kind, or a fibre optic element, you’ll have to buy or make one. Making one is quite easy, so long as you don’t try to make it too small! I tried making a tiny one - not recommended if you have bad soldering skills.

Once you’ve got a light source, make sure it’s connected so that it lights when going OnFwd(). This is important for the code later to work! Write a quick program to test that the light is working and the RCX can control it. For example, make it flash on and off every second.

If you did actually do that, you’ve written a very basic version of what’s to come. VLL is a protocol that consists of sets of flashes of light.

What Next?

Ok, as far as hardware is set up, you’re pretty much done. Now all you need is to know what sequences of flashes to send to the Micro Scout in order to make it do things. Fortunately, thanks to the RIS 2.0 SDK and Elecbrick, I got there before you needed to and wrote a Not Quite C Header file containing functions that emit the required flashes for most known instructions.

Download RCXVLL.nqh

RCXVLL.nqh is a Not Quite C Header file, that must be in the same folder as the .nqc source file that uses it. I would reccommend making a Micro Scout folder, and putting RCXVLL.nqh in it. Afterwards, use this folder for any Micro Scout development.

Getting down to the programming

Make a new NQC file in your Micro Scout folder, or whichever folder contains RCXVLL.h. Before the standard task main() definition, you need two extra lines to make RCXVLL.nqh work:

#define VLL_OUT OUT_C // You can assign it to whatever output you're using for VLL communication

#include "RCXVLL.nqh"

In the first line, replace OUT_C with whatever output your light source is connected to.

You’re now ready to use the functions in RCXVLL.nqh to program the Micro Scout. Add this to your program:

task main()
{
    OnFor(VLL_OUT, 50);

    while (true)
    {
        msFwd();
    }
}

The micro scout motor directions: Forwards = counter clockwise, Reverse = clockwise

task main() defines this task as the task that is run when the program is started. The OnFor() statement turns the output On for 50ms - this is required at the very start of a program for VLL signals to register with the Micro Scout.

while (true) loops forever. In this case we are sending the msFwd() command over and over again.

A quick look at RCXVLL.nqh reveals that msFwd() is a Direct function (it controls the Micro Scout in real time) that makes the motor turn forwards. Download the program to your RCX, set your Micro Scout to ‘P’ and run the RCX program. You should be rewarded with the Micro Scout’s motor turning.

That didn’t work?

If that didn’t work, have a browse through the checklist below:

  • Is the light source flashing quickly? If it is, then the VLL is working, the Micro Scout isn’t seeing it. Make sure the Micro Scout is on the ‘P’ program. Hold the Micro Scout in the dark and restart it (recalibrates the Light sensor). Try again.
  • If the light source isn’t flashing, either it’s not connected so that it lights on ‘Fwd’, or you haven’t #defined VLL_OUT as the port it’s connected to.

If it did work, well done! You’ve got the RCX controlling your Micro Scout. A lot more is now possible:

Going a Step further

Have a flick through RCXVLL.nqh. Try using some of the other direct functions, like msRev(). Have a go at sequences of commands — make the micro scout go Fwd for 2 seconds, then Rev for 2 seconds.

You’ll quickly notice that there’s not much possible with direct mode, and what is possible is annoying. You don’t have to listen to a sequence of bleeps before the motor turns, but the motor does not run smoothly, and I haven’t found a way to make it in direct mode.

There is another, more versatile way that the RCX can control the Micro Scout through VLL. It involves sending a sequence of ‘programming’ VLL codes once, then either sending the msRunScript() signal or pressing ‘Run’. Only one sequence of 15 codes can be stored, but using the built in behaviours, we can actually do rather a lot with that.

Making a simple Script

Let’s record a simple script on the Micro Scout, then run it directly from the RCX.

We’ll mainly be using functions from the third part of RCXVLL.nqh - the ‘Scripting Functions’ section. These are similar to the direct functions, but have an underscore () after the ms, e.g. msFwd10() for ‘Go forward for one second’.

#define VLL_OUT OUT_C
#include "RCXVLL.nqh"

task main()
{
    OnFor(VLL_OUT, 50);

    // Here is our sequence of scripting functions:

    ms_Fwd20(); // Forward 2 sec
    ms_Rev10(); // Rev 1 sec
    ms_Fwd05(); // Forward 0.5 sec
    ms_Rev50(); // Reverse 5 sec

    // Now, we use a direct function to run the program we've just sent:

    msRunScript();
}

As is obvious from the comments, this program (when run on the RCX) sends 4 scripting commands to the Micro Scout, which are stored, not executed. They are only executed when the ‘Run’ button is pressed, or (in this case) when the msRunScript() signal is sent. Note that this script is now stored, you can restart the Micro Scout and still run it.

Try the script and make sure it works. Experiment with different sequences and durations of Fwd and Rev.

Using In-Built Behaviours in Scripts

Within our Micro Scout scripts, we can call some of the Micro Scout’s built in programs. These allow us to make more complex behaviours and cheat some of the restrictions provided by direct and scripting modes.

Behaviours:

  • Wait for Light: ms_WaitForLight() - Not an actual program, this step waits for a light to be shone at the light sensor before continuing with your script.
  • Seek Light: ms_SeekLight() - This is program 3. Goes backwards in bursts until it sees light, at which point it goes forwards uninterrupted, indefinitely until it doesn’t see light. If uninterrupted, comes out after 30 secs of going backwards.
  • Code: ms_Code() - One of the less useful. Prog. 7, this makes a series of beeps and then you have to flash that same series back at it. If you get it right, or after 3 failed attempts, it continues with your program.
  • Keep Alive: msKeepAlive() - This is program 5. Stays still in dark, but goes forward and gains speed as a light is flashed. Continues with script after 30 seconds of standing still msKeepAlive() is a very useful command, as it allows us not only to drive the Micro Scout’s motor forwards uninterrupted, it actually gives us (limited) control over the speed of the motor.

We can do this through:

  • The RCX sending a ms_KeepAlive() signal, making a script
  • The RCX sending a msRunScript() signal, starting that script
  • The RCX flashing it’s light source at the Micro Scout. Faster flashing = faster Micro Scout

Using any previous NQC knowledge and what you’ve seen in this guide, you should be able to handle that by now. A little tip for the flashing light if you’re stuck:

int x = 50; // 50 = half a second.  Use different values for different speeds of flashing

while (true) // Loop forever
{
    OnFor(VLL_OUT, x); // Light on for x hundredths of a second (1/2 a second if x = 50)
    Wait(x); // Wait x
}

This is just an example, through experimentation and logical thought, many interesting behaviours can be scripted into the Micro Scout. If you make something cool, let me know! I’m barnaby@waterpigs.co.uk

If you have any problems or questions, contact me at barnaby@waterpigs.co.uk and I’ll do my best to help.