Building a light-eating robot
Everyone dreams of building their own robot. With the Dwengo board, some Lego™ and this tutorial, this becomes easy. Step by step we'll show you how to build a robot that can autonomously drive towards the light. Using this tutorial, a basic explanation on some different kinds of sensors and your own imagination, you can extend your robot into a line-follower or even an advanced sumobot.
Requirements
- A Dwengo Board and Programmer
- A USB cable
- Optionally a Dwengo Breadboard to quickly connect some sensors
- Some Lego™ to build the robot's chassis
- Two photo transistors and matching resistors
- Two Lego™ motors
Driving DC-motors using PWM
In the tutorial on interrupts you have already seen how to generate a PWM signal. We also mentioned here that you can use these PWM signals to drive for instance a motor. All devices that operate on direct current or DC require a constant input voltage. This includes several components such as Lego™ motors and LEDs. The voltage over these components is typically specified in a certain range but can often be reduced. In the case of LEDs a lower voltage results in less light output, while a motor will turn slower.
When a PWM signal with very high frequency is generated, the motor will experience this as a constant, but voltage. By changing the pulse width or duty cycle of the PWM signal, the amplitude of the average voltage can be controlled. This will in turn speed up or slow down the motor. The same concept can be applied for dimming LEDs. Although to be exact: an LED has a lower capacitance and will therefore do see the individual pulses, and thus turn on and off at high frequency. Our eyes are too slow to see this though, so we will experience a gradual change in brightness.)
When we take a close look at the Dwengo Board, we can see a connector to connect two motors. As can be seen on the figure, these are marked M1 and M2.
The schematics of the Dwengo Board show that these motor pins M1 and M2 are connected to the motor driver. This is a component that converts the PWM signal from the microcontroller into signals that are suitable for driving the motor. This is necessary because motors require a much higher current than what the microcontroller can deliver directly, and often the voltage driving the motor needs to be higher than the +5V that is powering the PIC controller. This voltage can be selected using jumper 2, which will either send the regulated 5V to the motor driver, or directly connect it to the Dwengo Board's input voltage. The motor driver is connected to the microcontroller's built-in PWM modules using the CCP1 and CCP2 pins. It is these modules that we need to configure correctly to make the motors turn as we want.
A light-eating robot
When you have followed all our previous tutorials, this code should be easy to follow. Indeed, most topics such as driving the LCD screen and reading out the light sensor, have been discussed in earlier tutorials. We won't repeat these here in detail, so don't hesitate to refer to them when needed. We will spend some more time on using the PWM signals to drive the robot's motors.
We start by loading the required library files. New here is a library that drives the microcontroller's PWM module: the dwengoMotor library.
#include <dwengoBoard.h> #include <dwengoCongig.h> #include <dwengoADC.h> #include <dwengoDelay.h> #include <dwengoMotor.h>
We also define a few macros that will make our code more readable.
#define THRESHOLD 30 // defines light sensitivity #define MAX_SPEED 1023 // maximal speed setting #define MIN_SPEED 600 // minimal speed setting
Next, we write the main loop of our program. We'll make two arrays of two integers each, in which we'll store the values read from the light sensors. We will keep both the previous and the current value, this will allow us to filter out noise, as we did in the tutorial on the light tracker.
void main(void) { int lightSensors[2]; int previousLightSensors[2];
We initialize the functionality of the Dwengo board. Calling these functions makes sures that all pins are correctly setup. For example, the function initMotor() makes sure that the motor pins M1 and M2 are configured as digital outputs and that the PWM module is correctly setup. If you want more detailed information about what happens inside these functions, we refer to our tips section.
// initializations initBoard(); initADC(); initMotor(); backlightOn();
Now that the ADC module and the LCD screen have been initialized, and the PWM modules with timer2 have been configured, we can start programming the intelligence of our robot. As explained in the tutorial on the light-tracker we turn on the LCD's backlight and initialize the lightSensors variables using some sensible values.
LCDBacklightOn(); lightSensors[0] = 500; lightSensors[1] = 500;
The intelligence of our light-eating robot consists of an infinite loop that reads out the light sensors and filters the results, compares the readings of both sensors (the left and right one), and sets the speed of both motors to turn into the direction from where the most light was received. This means that the left motor should run faster (this will make the robot turn right) when there was more light on the right, and vice versa.
We start by programming the infinite loop, saving the old sensor values, reading the new values, showing them on the LCD screen and applying some basic filtering.
while(TRUE) { // set previous sensor data previousLightSensors[0] = lightSensors[0]; previousLightSensors[1] = lightSensors[1]; // read lightsensors lightSensors[0] = readADC(); lightSensors[1] = readADC(); // show sensor data clearLCD(); appendStringToLCD("Right: ", 0, 0); appendIntToLCD(lightSensors[0]); appendStringToLCD("Left: ", 1, 0); appendIntToLCD(lightSensors[1]); // filtering lightSensors[0] = (lightSensors[0] + previousLightSensors[0])/2; lightSensors[1] = (lightSensors[1] + previousLightSensors[1])/2;
Now we compare the filtered readings of the light sensors. The sensors operate according to the principle that the more light they receive, the smaller the value will be that is read out. When the value of the sensor that is mounted on the right side of the robot (this value is stored in lightSensor[1]) exceeds the value of the left sensor (lightSensors[0]), the left sensor receives more light than the right one. In this case the right wheel must turn faster and the robot will turn left, towards the light. Just as in the tutorial on the light tracker we'll use a threshold value to determine the sensitivity to the light. Both wheels must turn at the same speed when both sensors receive approximately the same amount of light.
The speed of the motors can be controlled by setting the pulse width of the PWM signal. This can be done by calling the function setSpeedMotor1 for the first motor and setSpeedMotor2 for the second motor. The argument to these functions is a number that controls the pulse width, and must be between 0 (pulse width equals zero, so no pulse and the motor stops) and 1023 (pulse width equals the PWM period, so the motor runs at full speed). You can also give a negative value to let the engines turn in the opposite direction. The correct interpretation of turning left and right will depend on the way how you connected your motors to the connector M1 and M2. Nevertheless, this can be configured in software.
// set motor speed if((lightSensors[1]-lightSensors[0]) > THRESHOLD) { // turn left setSpeedMotor1(-MIN_SPEED); setSpeedMotor2(MAX_SPEED); } else if((lightSensors[0]-lightSensors[1]) > THRESHOLD) { // turn right setSpeedMotor1(-MAX_SPEED); setSpeedMotor2(MIN_SPEED); } else { // drive straight setSpeedMotor1(-MAX_SPEED); // - or + depends on how motors are connected to the board setSpeedMotor2(MAX_SPEED); }
While the motors run at the required speed, we wait a bit before restarting at the top of the while loop.
// wait a bit delay_ms(250); } }
Building your robot
You can quickly and easily build a robot using the Lego™ parts you may have at home. Apart from the Lego™ technic or Lego™ mindstorms parts, these components are essential:
- Two DC motors: for instance two Power Functions XL-Motors

- A battery holder with an output voltage between 9 V and 15 V which you can connect to the Dwengo Board
If you don't have enough Lego parts, you can order them separately at for instance BrickLink
, or try to find a good deal on eBay
.
Connecting the hardware
For connecting the light sensors, we'll refer to the tutorials on measuring light en tracking light nog eens door.
To connect the Lego motors to your Dwengo Board:
- Cut the connector from the Lego motors, making sure to keep a long wire at the connector's side.
- Detach the four smaller wires that make up the cable.
- Cut away the outer two wires.
- Strip the inner two wires, removing the insulation.
- Repeat steps 1-4 for the second Lego motor
- Connect the 4 stripped wires of the motors to a connector that fits the Dwengo Board's motor connector. The wires for one motor should be next to each other and connect to the pins labeled M1 on the Dwengo Board, while both wires for the second motor should match up to the pins labeled M2.
This should result in a setup such as the one on this picture. This particular robot also includes a ground sensor.
Extension to a light-following robot
When you own the Starters Kit Plus, or the Dwengo Sensors kit, you'll also have a number of ground sensors. Assemble them using the instructions on the sensors page and connect them to pins AN2 and AN3 on the Dwengo Board's extension connector. Mount these sensors on your robot and point them at the ground. Next, extend your robot's programming such that it will no longer drive off the table. Another possibility is to use the ground sensors to follow a line that you draw on the ground. By pointing them away from the robot, they become simple distance sensors which you can use to avoid hitting objects. If you also want to detect objects further away, read the rest of the sensors page! Have fun! And do post your creations on our forum...

Your shopping cart


