Introduction: Hacking the Lego Mindstorms RCX With an Arduino

I recently found a few boxes of an old LEGO Mindstorms RCX set and then spent a frustrating 2 weeks trying to get all the software and hardware to work together. Main problem was that the USB IR tower that they made to speak to the RCX control block would only run under a 32 bit computer. After setting up a Virtual Machine on my laptop and running Windows XP I managed to get the tower working but it would repeatedly drop the connection to the block during the firmware upload.

Eventually I gave up and realised that everything I might want to do I should be able to do with my Arduino plus I shouldn't have to learn any more weird and obsolete programming languages on top.

This is a little recap of what I went through to do this. I hope this may be of use to anyone trying the same. I have tried to credit any sources that I have used along the way.

Step 1: Making the Connections

I took one of the cables that connect the RCX brick to the various motors and sensors and cut off the end before soldering some Arduino connecting wires to the ends. I also did it with the male pins but found this very fiddly compared the the connecting wires. It was only afterwards I face-palmed and realised that I shouldn't just have cut the end off - if I had cut the whole cable in two I would have two cables instead of one...

Step 2: Connecting the Motor

I knew this would probably be the easiest step but was concerned about damaging my Arduino so did a bit of research instead of just plugging it in.

From http://www.dummies.com/computers/arduino/how-to-spin-a-dc-motor-with-the-arduino/ I found out that small amounts of back current from the motor might affect my board so they recommend adding a diode across the motor connections. The circuit simply uses a transistor to operate the motor. Anything more sophisticated such as changing direction and I would have to get a motor driver chip (such as an L239D). I ordered a few of those and continued with the basics (I'll add something on the motor driver later).

Connect up as shown just take care that your transistor is the right way round. I used a 2N3904 which is 'backward' compared the the flat side shown on the diagram - check the specs of yours first. For the diode I just used a 1N4148.

Step 3: Motor Driving Code

Fairly simple code if you're familiar with Arduino:

int motorPin = 9;

int motorTime = 1000;

//sets up the pin that the motor is controlled by and the time to have it on or off (1 second)

void setup() {
pinMode (motorPin, OUTPUT);

}

//defines the pin as an output

void loop() {

digitalWrite(motorPin, HIGH);

delay(motorTime*8);

digitalWrite(motorPin, LOW);

delay(motorTime);

}

//turns motor on for 8 seconds then off for 1 second

Obviously you can play about with the timings if you want - this just worked for the mini-crane type mechanism that I had built to test the motor.

Step 4: The Light Sensor

This one had me confused for a while. At first I assumed it was some sort of distance/proximity measuring device but when I had it connected up to the Arduino as an input, not a lot was happening.

There is a red l.e.d. and, what I assumed was a sensor l.e.d. Connecting it up as an output made the red l.e.d. light up. I assumed that you needed the red l.e.d. to be on and then use the sensor to pick up the amount of light. I tried to get the Arduino to use it as an output and an input but, again, not a huge amount of happening.

With a bit more research I gathered that the light sensor would be used more as a line-following sensor for a robot and probably wasn't much use as a distance measuring device. Also, with the help of Ro-Bot-X's blog, I gathered that I could turn it on as an output briefly then quickly turn it to an input and get a similar effect to how it is meant to be used.

I connected one lead to ground and one to the A0 pin. Code as follows;

int OutputPin = A0;
int InputPin = A0;

void setup(){

Serial.begin(9600);

}

void loop(){

pinMode(OutputPin, OUTPUT);

digitalWrite(OutputPin, HIGH);

delay(100);

pinMode(InputPin, INPUT);

int value=analogRead(InputPin);

Serial.println(value);

delay (1000);

}


So I first set up A0 as an input and output pin then start my serial monitor so that I can see the sensor values.

In the loop I turn on the red l.e.d. for 0.1 then immediately turn the pin into an input and read the value. I played around with the time for this quit a bit and anywhere between 1ms and 200ms seems to work pretty much the same.

I tried the sensor out against a background of masking tape on black paper and got values of around 120-160 from matt dark to bright light.

I then added a map code to try to turn this into a percentage;

byte MappedValue = map (value, 130, 150, 0, 100);

Which roughly worked.

I assume that for a line-following robot I'd need a more binary scenario so put a few 'ifs' in ;

if (MappedValue < 50)
{sensor = 0; }

if (MappedValue > 50 )

{sensor = 1 ; }

This worked good enough for me and it was definitely recognising when it was above the tape or above the paper (at least 80% of the time...). I guess that I'd need to tweak these values depending on my circumstance.

Step 5: The Rotation Sensor

Still not totally sure what this is originally used for. When I hooked up the sensor it returned values of a little under 200 or a little over 800, nothing inbetween. Essentially the value changes every 1/8 or a turn, or 22.5 degrees.

I thought it would give me a nice value that I could map from 0-360 degrees but no such luck.

I figured that if I turned it into a binary counter like I did with the light sensor, I could (potentially!) write some code that would count the 1s and 0s and could possible measure rotational speed or work out an angle turned from that.

Because the values were so distinct it was easy to set up a few 'ifs' to get my binary;

if (value < 300)
{sensor = 0;

}

if (value > 500 )

{sensor = 1 ;

}

Step 6: The Push Button

This one was pretty straightforward.

When out, it returned a value of 1024 (ish) and when in, 0.

There was actually a tiny bit of analogue action when nearly fully depressed which could potentially have a use but I imagine this will be just used as a push button.

Step 7: In Conclusion

I feel that I have got enough information from this for any future problems to be 'merely' programming ones. I was doing this so that my STEM club students could build robots from these old kits so I will let you know of any interesting projects that they build and how we set it all up together.

Any comments on to how I could use these sensors in a better or more interesting way will be hugely welcome.

I hope that my first Instructable might be useful to someone out there!

First Time Authors Contest 2016

Participated in the
First Time Authors Contest 2016