Interrupts, driving a servo: a light tracker

In this tutorial we explain step by step how to build a small robot that drives in the direction of the light. For this the robot uses a servo and two light sensors. The same principle could be used to always perfectly align solar panels in order to maximize their performance.

Requirements

  1. One Dwengo board
  2. One Dwengo programmer
  3. Accompanied cables
  4. Two phototransistors accompanied with two 22 kOhm resistors
  5. Optionally a Dwengo breadboard in order to easily build your analog circuit and some wires
  6. A servo motor
  7. A soldering iron and some tin to build the sensor

Building a robot

In this section we build the hardware of the robot.

Connecting a servo

Typically a servo has three wires connected to connector. Two of these wires, the power lines, provide the servo with the correct voltage. The third one can be used to set the position of the servo. The two power lines are always colored black (convention for ground) and red (convention for 5 V). To easily connect servos, the Dwengo board is equipped with two connectors: servo1 and servo2. The connectors can be used to drive servo that require at most between 200 and 400 mA. Connect the servo in such a way that the dark brown or black wire corresponds with the "-"-sign as shown in the picture.

Connecting the servo


In this tutorial we assume that the servo is connected to the servo1 connector.

Connecting the servos

In the tutorial about ADC we showed how to build a light sensor with a resistor and a phototransistor. For the light tracker you have to build this circuit two times. However, in this case the idea is to solder the sensors in such a way that they can be mounted on the servo. Similarly as in the previous tutorial you connect one of the sensors to AN0 of the Dwengo board. The second sensor is connected to AN1 of the Dwengo board. Connect the long leg (+) of the phototransistor to the ground and the short leg (-) to the resistor that is connected with the 5 V pin. The connecting with wires is easily done on the Dwengo breadboard. You get a circuit as depicted in the photograph.

Circuit of the light tracker


When everything is well connected and programmed you have a working light tracker!

Overview of working light tracker

The program

The program code of the robot looks as follows:

  1. #include <dwengoConfig.h>
  2. #include <dwengoBoard.h>
  3. #include <dwengoServo.h>
  4. #include <dwengoADC.h>
  5.  
  6. #define THRESHOLD 50 // defines light sensitivity
  7.  
  8. void main(void) {
  9. int rightSensor, leftSensor;
  10. unsigned char position;
  11.  
  12. initADC();
  13. initServo();
  14.  
  15. while (TRUE) { // Repeat the following forever
  16.  
  17. // Read light sensors
  18. rightSensor = readADC(0);
  19. leftSensor = readADC(1);
  20.  
  21. // Calculate new possition
  22. if ((leftSensor - rightSensor > THRESHOLD) && (position > 0)) {
  23. position--;
  24. } else if ((rightSensor - leftSensor > THRESHOLD) && (position < 255)) {
  25. position++;
  26. }
  27.  
  28. // Send new possition to servo1
  29. setPosition(1,position);
  30.  
  31. // Give the servo some time to move to the new possition
  32. delay_ms(10);
  33. }
  34. }

Initialization

The lines 9-13 initialize the light tracker. The variables leftSensor and rightSensor are used to respectively for storing the current light intensity of the left and right sensor. The variable position is used to store the position of the servo. Since we use the dwengoADC library and the dwengoServo library, both libraries needs to be initialized.

The main loop

The code that makes sure the servo points towards the brightest light is from line 15 to 33 and repeated in an infinite loop and performs the following tasks:

  • Read the sensors and store these values in the variables leftSensor and *rightSensor;
  • Calculate the new position of the servo using the new sensor values and write this position into the variable position;
  • Send the new position to the servo;
  • Wait a moment in order to give the servo the time to reach its new position.

For reading out the sensor values we use the readADC function that is part of the dwengoADC library. The argument of this function is the channel that needs to be read out. Since the right light sensor is connected to the AN0 pin, we read out its value on channel 0. The left light sensor is connected to the AN1 pin and hence read out on channel 1.

Adjusting the position of the servo is done in line 21 to 26. If the left sensor receives more light than the right one, the servo has to turn to the left and to the right in the opposite case. Note that receiving more light, results in a lower value of sensor. We also use a threshold value to make sure that when both sensors receive about the same amount of light the servo keeps its current position. Only when the threshold is exceeded, the servo will change its position by adding or subtracting 1 to its current value. Finally we also make sure that the position of the servo does not drop below 0 or exceeds 255, since this is the range of valid servo positions.

On line 29 we give the servo the command to move to a new position using the setPosition function from the dwengoServo library. This functions has two arguments: an index number of the servo and the new position. Since we want to use servo1 we use index 1.

The last line (line 32) lets the program wait for a while in order to reach the new servo position. This is needed because the servo cannot change its position at the speed of light.

Source codeSource code files are only available to registered users. If you have an account on the Dwengo site, please log in to download source files, else you can create your free account by registering.