Autonomous line follower

Hi, I’m new. I’m in my first project and I’m having problems with the code. I’m doing the code on MPlab and the objective is to follow a black line. Some words are in Portuguese, so: SENSORDIREITA= right sensor; SENSORESQUERDA= left sensor; SENSORFRONTAL= center sensor; CORINTERMEDIARIA= avg; Thanks (:

[FONT=“Comic Sans MS”]#include “API.h”
#include “BuiltIns.h”
int SENSORDIREITA; //Sensor da direita.
int SENSORCENTRAL; //Sensor central.
int SENSORESQUERDA; //Sensor da esquerda.
int SENSORFRONTAL; //Sensor da frente.

int CORINTERMEDIARIA = 300; //Nível de luminosidade dos sensores (0=PRETO e 1000=BRANCO).
int FWD = 192; //Velocidade máxima para tras.

int STP = 127; //Velocidade nula.
int REV = 67; //Velocidade máxima para frente.
int SLOW = 157; //Velocidade lenta para tras.
int REVSLOW = 97; //Velocidade lenta para frente.
void main (void)
{
SetPWM (1,STP);
SetPWM (2,STP);
SENSORDIREITA = GetAnalogInput(1);
SENSORCENTRAL = GetAnalogInput(2);
SENSORESQUERDA = GetAnalogInput(3);
Wait (1000); //Tempo para carregar sensores.
while (1) //Loop Infinito.
{
while (SENSORCENTRAL < CORINTERMEDIARIA) //Sensor central está sobre a linha.
{
SENSORCENTRAL = GetAnalogInput(2);
SetPWM (1,REV);
SetPWM (2,FWD);
}
while (SENSORDIREITA < CORINTERMEDIARIA) //Caso o valor for menor que CORINTERMEDIARIA, então SENSORDIREITA está sobre a linha.
{
SENSORDIREITA = GetAnalogInput(1);
SetPWM (1,FWD);
SetPWM (2,FWD);
}
while (SENSORESQUERDA < CORINTERMEDIARIA) //Caso o valor for menor que CORINTERMEDIARIA, então SENSORESQUERDA está sobre a linha.
{
SENSORESQUERDA = GetAnalogInput(3);
SetPWM (1,FWD);
SetPWM (2,FWD);
}
SENSORDIREITA = GetAnalogInput(1);
SENSORCENTRAL = GetAnalogInput(2);
SENSORESQUERDA = GetAnalogInput(3);
}
} [/FONT]

First Off, this is EasyC Code, Version 1.x, which could be compiled in MPLAB if the the WPILIB is Included.

Over All, the Code has basically the Right Structure… But you need to expand the Logic…

Download this EasyC 2.x Printed Code and look at the Track_Line function.

Found on Page: Line Tracker Code - Printed

while(e^(i*Pi) == -1) {
if(!OnLine)
  lineFollow();
else if(OnLine)
  cookie += 1;
}

Your structure looks good but I think the logic needs some work (as MarkO said).

What goes wrong when you run it?

Thanks MarkO, I did the download and I’ll analyse what I can change in my code.

dontworryaboutit, nothing happens when I run the code. I tested some basic codes to check if the robot had any problem, but the robot was ok.

If all the analog values returned are greater than 300, your code will not do any SetPWM.

When saying “code doesn’t work”, it helps to list:

  • What you did: “put robot on line, and turn it on”
  • What you expected the robot to do: “follow the line forward”
  • What the robot did : “robot did not move”

Even just writing such a post will help you debug it yourself.
For example, If your robot never moves, then the motors were never turned on.
What conditions turn on the motors? GetAnalog < 300.
Maybe GetAnalog is always returning a value >= 300?

You need to determine what the Threshold Value is…

Add the following Lines of code to your Project:



    PrintToScreen ( "===================================\n" ) ;
    PrintToScreen ( "SENSORDIREITA --> %d\n" , (int)SENSORDIREITA ) ;
    PrintToScreen ( "SENSORCENTRAL --> %d\n" , (int)SENSORCENTRAL ) ;
    PrintToScreen ( "SENSORESQUERDA --> %d\n" , (int)SENSORESQUERDA ) ;
    PrintToScreen ( "\n" ) ;


Place them like this:


    SENSORDIREITA = GetAnalogInput(1);
    SENSORCENTRAL = GetAnalogInput(2);
    SENSORESQUERDA = GetAnalogInput(3);

    PrintToScreen ( "===================================\n" ) ;
    PrintToScreen ( "SENSORDIREITA --> %d\n" , (int)SENSORDIREITA ) ;
    PrintToScreen ( "SENSORCENTRAL --> %d\n" , (int)SENSORCENTRAL ) ;
    PrintToScreen ( "SENSORESQUERDA --> %d\n" , (int)SENSORESQUERDA ) ;
    PrintToScreen ( "\n" ) ;

    Wait (1000); //Tempo para carregar sensores.

Now after you download your program, the Downloader Program should change to the Terminal… You will see the values of each of the Line Sensors.

Disconnect the Motors from the Vex Controller, ( so it won’t drive away ) and place the Robot over the Line.

Position it so the Center is over the line and view the Terminal, the Left and Right values should be about the same, the Center should be different.

Place the Left Sensor over the Line and view the Terminal, the Center and Right values should be about the same, the Left should be different.

Place the Right Sensor over the Line and view the Terminal, the Left and Center values should be about the same, the Right should be different.

Your Threshold Value, CORINTERMEDIARIA should be between the Line Value and the Non Line Value.

Mark-O is spot on, you may also find as I did that each sensor has a different threshold, not a problem if they are close but can drive you to use sensor unique thresholds if they vary by a great deal (as mine do).

Cheers Kb

Spot On to you too… :wink:

Or… If your Sensors have a widely Varying Threshold, use an Upper Limit variably and a Lower Limit variable… Basically a Dead Band, where the Sensors are considered neither The Line or Not The Line.

Then, when you test for Below The Threshold, you use the Lower Value, and when you test for Above The Threshold you use the Higher Value.