Introduction: Hacking the Lego Mindstorms RCX With an Arduino Part III: Line Follower

Picture of Hacking the Lego Mindstorms RCX With an Arduino Part III: Line Follower

After spending nearly a week trying to build a line-following robot I decided to give up: I just couldn't seem to get the sensitivity of the sensors to respond appropriately. The next morning I re-jigged the robot chassis to build it with a caterpillar track. This made it a lot slower but I realised that this allowed it to be able to respond better to changes on the sensor. 10 mins later I had a fully-functioning line-follower!

Step 1: Setting Up the Sensors

Picture of Setting Up the Sensors

Starting with the motorised robot from Hacking the Lego Mindstorms RCX With an Arduino Part II, I added 2 of the RCX light sensors to the front spaced about 3cm apart.

I used black electrical tape to form a simple curved loop on a table top. I tried to put a few gentle curves and a few more severe ones. Electrical tape is good to use as it can be twisted slightly to provide smooth curves.

The right hand sensor is attached to ground and A0 pin, the left hand sensor attached to ground and A2 pin (the only reason I didn't use A1 is because my clumsy soldering meant they needed a gap between them...)

My light sensor program from Hacking the LEGO Mindstorms RCX Part I needed a few small tweeks:

I set up a function called 'look()' in order to return a binary value for the sensor whether it was above my line or not. With (a lot) of trial and error I came up with the sensor values that would return a 0 for 'above the line' and a 1 for 'not above the line'.

void look(){
  pinMode(r_sensorOutputPin, OUTPUT); 
  digitalWrite(r_sensorOutputPin, HIGH);
  delay(10);
  pinMode(r_sensorInputPin, INPUT);
  int r_value=analogRead(r_sensorInputPin); 
  
  // changing value to a binary value
  if (r_value < 135)
  {r_sensor = 0;
  }
  if (r_value >= 135 )
  {r_sensor = 1 ;
  }

  pinMode(l_sensorOutputPin, OUTPUT); 
  digitalWrite(l_sensorOutputPin, HIGH);
  delay(10);
  pinMode(l_sensorInputPin, INPUT);
  int l_value=analogRead(l_sensorInputPin); 
  
  // changing value to a binary value
  if (l_value < 135)
  {l_sensor = 0;
  }
  if (l_value >= 135 )
  {l_sensor = 1 ;
  }
  Serial.print("left: ");
  Serial.println(l_sensor);
  Serial.print ("right: ");
  Serial.println(r_sensor);
  
}

The full code is attached but I just wanted to show the key differences between my motor code and the sensor code.

Step 2: The Chassis

Picture of The Chassis

You can use any old chassis in principle but I found that the caterpillar track one worked the best. I'm not sure of the copyright issues here so I haven't attached pictures of the instructions that came with the set. A bit of searching will get you some help here, or have a look at my photos. There is quite a dedicated online community for LEGO Mindstorms with some amazingly impressive stuff but, as the RCX is pretty obsolete, I found that a lot of links to instructions and the like might be missing or broken.

Step 3: The Brain

Aside from the motor and sensor code, we need to tell the robot what to do in different circumstances:

void loop() {
 look();
 
 if (r_sensor == 1 && l_sensor == 1){
  fast_forward();
  delay(100);
 }
 if (r_sensor == 0 && l_sensor == 0){
  fast_forward();
  delay(100);
  }
  if (r_sensor == 0 && l_sensor == 1){
    left();
    delay(100);
  }
  if (r_sensor == 1 && l_sensor == 0){
    right();
    delay(100);
  }
  r_sensor = 0;
  l_sensor = 1;
}

I kept it pretty simple: If one sensor is above the line and the other isn't, the robot turns in the appropriate direction.

I've actually got my 'left()' and 'right()' the other way round here - I had the motors attached backwards to how I had them during the motor setup - was just easier than re-writing the code...

Again the delay values here were through trial and error - these seem to work fine.

Step 4: In Conclusion

I'm fairly happy with how this went - my main headache was getting the sensors to have the right sensitivity.

There is some code available from Visuino (https://www.visuino.com/) that has an RCX Light Sensor input already. It seems to work a lot better than mine but I personally don't like the 'hidden' nature of the Visuino code - I prefer to be able to read code to try to understand it - I know that's not the best way but I'm no programmer.

If anyone has a better or simpler way of writing my code I'd be very happy to hear it. I'm guessing that my robot is going to keep getting more complicated!

Comments

ROBO HUB (author)2016-11-30

Good

BoianM (author)2016-11-29

Cool project! I have been planning line tracking LEGO robot for a while, but never had the time :-(

Thank you for mentioning Visuino :-) . You should give it a try sometime ;-) You may actually like it ;-)

lordgert (author)BoianM2016-11-29

Thanks - don't get me wrong, I liked Visuino and I'm sure some people work better like that but I need to see how things work- your sensor program works a lot better than mine but I just can't make sense of your code!
All a bit too clever for me...

BoianM (author)lordgert2016-11-29

The code is the Visuino diagram ;-) The C++ code it produces is not intended to be modified or studied, the same way assembly code is not intended to be modified once generated from C++. The Visuino diagram is the program, and it is the one that should make sense, and be easy to understand ;-)