Line Follower + Obstacule Sensor (HC-SR04)

Hello Guys,

I am new here and would love to get some help for my project that has the following hardware:

  • Nano V3
  • Dual Motor Drive DRV8833 (Pololu)
  • QTR 8A (6 sensors)
  • Obstacle Sensor (HC-SR04)

Goal:
Complete the circuit in the shortest time, having to stop for 10 seconds to find an obstacle.
I could make him be swift and walk the line and could also make it stop any obstacles.
It turns out that the Sketches are different.
How can I do to integrate them into a single sketche. Could anyone help me?

Complete the circuit in the shortest time, having to stop for 10 seconds to find an obstacle.

This objective makes no sense. Are you supposed to stop at some random point along the curve and spend 10 seconds looking for an obstacle, and then proceed, regardless of whether there is an obstacle or not?

Or, are you supposed to stop for 10 seconds when you find an obstacle, and then roar off, hoping that the obstacle will no longer be a problem?

How can I do to integrate them into a single sketche.

Start with an achievable, intelligent, objective. The one you have now is neither.

Hello. Thank you for answer.

Yes. It is the second goal. Along the back, to find the obstacle the robot must stop for 10 seconds and after resuming his line.
The fastest robot wins the race.
I tested a script with PID Line Follower and for Ultrasonic Sensor to detect the obstacle.
I have both Sketches that work perfect individually, but do not know how to make them work together in a single sketch.
If you need to make a post of both.
Any help is welcome.

Best Regards

I have both Sketches that work perfect individually, but do not know how to make them work together in a single sketch.

Still not going to post them, or your attempt to combine them or the results of that attempt, though, I see.

Hi,

Can you please post a copy of your sketch, using code tags?
They are made with the </> icon in the reply Menu.
See section 7 http://forum.arduino.cc/index.php/topic,148850.0.html

Tom..... :slight_smile:

SKETCH 1: Line Follower

#include <QTRSensors.h>

#define Kp 0.034 // experiment to determine this, start by something small that just makes your bot follow the line at a slow speed
#define Kd 0.89 // experiment to determine this, slowly increase the speeds and adjust this value. ( Note: Kp < Kd) 
#define rightMaxSpeed 100 // max speed of the robot
#define leftMaxSpeed 100 // max speed of the robot
#define rightBaseSpeed 95 // this is the speed at which the motors should spin when the robot is perfectly on the line
#define leftBaseSpeed 95  // this is the speed at which the motors should spin when the robot is perfectly on the line
#define NUM_SENSORS  6     // number of sensors used
#define NUM_SAMPLES_PER_SENSOR  4  
#define TIMEOUT  2500  // waits for 2500 us for sensor outputs to go low
#define NO_EMITTER_PIN 255 // emitter is controlled by digital pin 2

#define rightMotor1 6
#define rightMotor2 8
#define rightMotorPWM 5
#define leftMotor1 14
#define leftMotor2 13
#define leftMotorPWM 11
#define motorPower 9

QTRSensorsAnalog qtra((unsigned char[]) {A0,A1,A2, A3, A4, A5},NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, NO_EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];

//QTRSensorsRC qtrrc((unsigned char[]) {  19, 20, 21, 22, 23, 24} ,NUM_SENSORS, TIMEOUT, QTR_NO_EMITTER_PIN ou EMITTERS_ON_AND_OFF); // sensor connected through analog pins A0 - A5 i.e. digital pins 14-19

//unsigned int sensorValues[NUM_SENSORS];

void setup()
{
  pinMode(rightMotor1, OUTPUT);
  pinMode(rightMotor2, OUTPUT);
  pinMode(rightMotorPWM, OUTPUT);
  pinMode(leftMotor1, OUTPUT);
  pinMode(leftMotor2, OUTPUT);
  pinMode(leftMotorPWM, OUTPUT);
  pinMode(motorPower, OUTPUT);
  
  int i;
for (int i = 0; i < 250; i++) // calibrate for sometime by sliding the sensors across the line, or you may use auto-calibration instead

  /* comment this part out for automatic calibration 
  if ( i  < 25 || i >= 75 ) // turn to the left and right to expose the sensors to the brightest and darkest readings that may be encountered
     turn_right();  
   else
     turn_left(); */ 
   qtra.calibrate();   
   delay(20);
wait();  
delay(2000); // wait for 2s to position the bot before entering the main loop 
    
    // comment out for serial printing
    
    Serial.begin(9600);
    for (int i = 0; i < NUM_SENSORS; i++)
    {
      Serial.print(qtra.calibratedMinimumOn[i]);
      Serial.print(' ');
    }
    Serial.println();

    for (int i = 0; i < NUM_SENSORS; i++)
    {
      Serial.print(qtra.calibratedMaximumOn[i]);
      Serial.print(' ');
    }
    Serial.println();
    Serial.println();
    
  } 
 
int lastError = 0;

void loop()
{
  unsigned int sensors[6];
  int position = qtra.readLine(sensors); // get calibrated readings along with the line position, refer to the QTR Sensors Arduino Library for more details on line position.
  int error = position - 2500;

  int motorSpeed = Kp * error + Kd * (error - lastError);
  lastError = error;

  int rightMotorSpeed = rightBaseSpeed + motorSpeed;
  int leftMotorSpeed = leftBaseSpeed - motorSpeed;
  
  if (rightMotorSpeed > rightMaxSpeed ) rightMotorSpeed = rightMaxSpeed; // prevent the motor from going beyond max speed
  if (leftMotorSpeed > leftMaxSpeed ) leftMotorSpeed = leftMaxSpeed; // prevent the motor from going beyond max speed
  if (rightMotorSpeed < 0) rightMotorSpeed = 0; // keep the motor speed positive
  if (leftMotorSpeed < 0) leftMotorSpeed = 0; // keep the motor speed positive
  
   {
  digitalWrite(motorPower, HIGH); // move forward with appropriate speeds
  digitalWrite(rightMotor1, HIGH);
  digitalWrite(rightMotor2, LOW);
  analogWrite(rightMotorPWM, rightMotorSpeed);
  digitalWrite(motorPower, HIGH);
  digitalWrite(leftMotor1, HIGH);
  digitalWrite(leftMotor2, LOW);
  analogWrite(leftMotorPWM, leftMotorSpeed);
}
}
  
void wait(){
    digitalWrite(motorPower, LOW);
}

SKETCH 2 - OBSTACLE SENSOR ( Thanks for all ! I need all in one )

#include <Ultrasonic.h>  // inclui biblioteca de manipulação do sensor PING.

// definição de objetos.
//Servo myservo;

// definição de variáveis e pinos.
int echopin = 8;               // a saída echo do HC-SR04 ligado no pin 11.
int trigerpin = 9;             // a saída triger do HC-SR04 ligado no pin 12.
int inA1 = 3;                 // pino 1 do motor 1; direito
int inA2 = 5;                 // pino 2 do motor 1; direito
int inB1 = 10;                  // pino 1 do motor 2; esquerdo
int inB2 = 11;                  // pino 2 do motor 2; esquerdo
unsigned long pulsetime = 0;   // variável que faz a leitura do pulso.
unsigned long distancia = 0;   // variável que que armazena a distância.        
int distLimite = 40;           // distancia limite para o sensor em cm



// executado na inicialização do Arduino
void setup(){
  Serial.begin(9600);          // inicializa a comunicação serial
  pinMode(inA1, OUTPUT);       // pinos dos motores como saídas 
  pinMode(inA2, OUTPUT);
  pinMode(inB1, OUTPUT);
  pinMode(inB2, OUTPUT);
  pinMode(trigerpin, OUTPUT);  // define o pino triger como saída.
  pinMode(echopin, INPUT);     // define o pino echo como entrada.
  set_motors(0,0);             // inicialmente motor parado
  Serial.println("PARADO");    // imprime na serial
  delay(500);                 // espera 0.5s antes de iniciar
}

// loop principal do Arduino
void loop(){
  distancia = lerDistancia();              // chama a funcao que retorna a distancia em cm.
  Serial.print("DistF.: ");                // imprime na serial
  Serial.print(distancia);                 
  Serial.println(" cm");                   
  if (distancia > distLimite){             // se a distância for maior que 20 cm.
    Serial.println("SEGUE EM FRENTE");     // imprime na serial
    //delay(1000);                           // atraso na execução
    set_motors(100,100);                   // segue em frente.
  }
  else {                                   // senão, a distância frontal é MENOR ou IGUAL a 20 centímetros.
    Serial.println("PARADO");              // imprime na serial
    set_motors(0,0);                       // pare os motores.
    delay(10000);                         // aguarde 10 segundos.
    set_motors(100,100);                   // segue em frente.


    }       
  }



// ########################### set de funções ###########################

// Acionamento dos motores
void set_motors(int left_speed, int right_speed){
  if(right_speed >= 0 && left_speed >= 0){
    analogWrite(inA1, 0);
    analogWrite(inA2, right_speed);
    analogWrite(inB1, 0);
    analogWrite(inB2, left_speed);
  }
  if(right_speed >= 0 && left_speed < 0){
    left_speed = -left_speed;
    analogWrite(inA1, 0);
    analogWrite(inA2, right_speed);
    analogWrite(inB1, left_speed);
    analogWrite(inB2, 0);
  }
  if(right_speed < 0 && left_speed >= 0){
    right_speed = -right_speed;
    analogWrite(inA1, right_speed);
    analogWrite(inA2, 0);
    analogWrite(inB1, 0);
    analogWrite(inB2, left_speed);
  } 
}

// função que retorna a distância em cm 
int lerDistancia(){
  // primeiro geramos um pulso de 10 ms no pino trigger do sensor PING.
  digitalWrite(trigerpin, LOW);        // para garantir a inicialização do pino e não gerar pulso em falso
  digitalWrite(trigerpin, HIGH);       // coloca o pino trigger en nível alto.
  delayMicroseconds(10);               // por 10 ms.
  digitalWrite(trigerpin,LOW);         // coloca o pino trigger en nível baixo.
  pulsetime = pulseIn(echopin, HIGH);  // faz a leitura do pulso no pino echo do sensor.
  return pulsetime/58;                 // converte para cm e retorna da função
                                       // veja o cálculo completo em "http://arduinobymyself.blogspot.com.br/"
}
  int i;
for (int i = 0; i < 250; i++)

Two variables named i? Why?

   {
  digitalWrite(motorPower, HIGH); // move forward with appropriate speeds
  digitalWrite(rightMotor1, HIGH);
  digitalWrite(rightMotor2, LOW);
  analogWrite(rightMotorPWM, rightMotorSpeed);
  digitalWrite(motorPower, HIGH);
  digitalWrite(leftMotor1, HIGH);
  digitalWrite(leftMotor2, LOW);
  analogWrite(leftMotorPWM, leftMotorSpeed);
}

Piss poor indenting. Useless curly braces.

void wait(){
    digitalWrite(motorPower, LOW);
}

Stupid name for a function that does NOT wait for anything.

Your attempt to combine the sketches is conspicuously absent.

Dear Paul

I am very grateful for his "educated" answers.
If I were an expert would not be in Arduino Forum seeking for help.
Although with these "educated" critical and minor errors, these TWO sketches work perfectly, individually and without compilation errors.

Thank you