Problem making Ping sensor work on an integrated code

Hi everyone, first let me say that english is not my first language, so my apologizes if i make any mistake.

As the subject says, i have troubles making this sensor work, i have read many tips on this forum(i’m pretty new) and i can make it work when i just want to use the sensor, it works perfectly, but when i put it into a bigger code ( Obect avoidance robot) it literally doesn’t work and i can’t find why.

I have on the robot, 2 basic dc motors, arduino mega, Ping sensor and a servo motor ( I also have a L298 Dual H-bridge Motor Driver).

So i made various loops to coordinate the directions, motor start, motor stop, and a Scan loop ( As i’m new to this, i have took many examples and read a lot to be able to make this code, besides, i’m learning this by myself). I have the ping code on the scan loop, which is the same as the example that comes with the program.

This is my void Scan:

void Scan()
{
  

  long duration, inches, cm;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  
  

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  delay(100);
}

And my void loop :

void loop()
{
  
  long duration, inches, cm;

  
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  void Scan();
  servo.write(90);
  motorStart(1, MOTOR_ADELANTE);
  setSpeed(1, 140);
  motorStart(2, MOTOR_ADELANTE);
  setSpeed(2, 140);
  
  cm = distance;
  if(cm < 30)
  {
    motorStop(1);
    motorStop(2);
    delay(500);
    servo.write(0);
    delay(500);
    Scan();
    rDistance=distance;
    servo.write(180);
    delay(500);
    Scan();
    lDistance=distance;
    if(lDistance<rDistance)
    {
      turnRight();
      
    }
    else{
      turnLeft();
    }
  }
}

I also have at the end of the code/after the void loop, the correct code to transform the distance to inches or centimeters:

long microsecondsToInches(long microseconds)
{
  
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  
  return microseconds / 29 / 2;
}

So, everything works but as the Ping sensor doesn’t, the conditions aren’t met.

The purpose of the object avoidance robot is to move forward until some object is under 30 cm of distance, then he stops, and the Servo motor moves the ping sensor and scans right and left, then he chooses the best way to go. Thats what i basically want to do.

I think that the structure of the code may be wrong, but i’ve tried almost everything, i don’t have anyone teaching me because i’m studying it by myself.

Obviusly i put the variables and the setup and everything. If something is missing here for you to be able to help me, please let me know.

Thanks!

You can see the entire code here :

#include <Servo.h>
Servo servo;
#define motor1_1  8  // I1  
#define motor1_2 9  // I2  
#define motor1_pwm   11 // EA  
  
#define motor2_1  6  // I3  
#define motor2_2  7  // I4  
#define motor2_pwm  10 // EB  
  
#define MOTOR_ADELANTE  0  
#define MOTOR_ATRAS  1  
const int pingPin = 4;
int pos = 0;
int fDistance;
int lDistance;
int rDistance;
int distance;





void setup(){
  pinMode(motor1_1,OUTPUT);
  pinMode(motor1_2,OUTPUT);
  pinMode(motor1_pwm,OUTPUT);
  pinMode(motor2_1,OUTPUT);
  pinMode(motor2_2,OUTPUT);
  pinMode(motor2_pwm,OUTPUT);
  Serial.begin(9600);
  servo.attach(3);
}

void setSpeed(char motor_num, char motor_speed)
{
  if(motor_num==1)
  {
    analogWrite(motor1_pwm,motor_speed);
  }
  else
  {
    analogWrite(motor2_pwm,motor_speed);
  }
  
}

void motorStart(char motor_num, byte direction)
{
  char pin_ctl1;
  char pin_ctl2;
  
  if(motor_num==1)
  {
    pin_ctl1=motor1_1;
    pin_ctl2=motor1_2;
  }
  else
  {
    pin_ctl1=motor2_1;
    pin_ctl2=motor2_2;
  }


switch (direction)
{
  case MOTOR_ADELANTE:
  {
    digitalWrite(pin_ctl1,HIGH);
    digitalWrite(pin_ctl2,LOW);
  }
  break;
  case MOTOR_ATRAS:
  {
    digitalWrite(pin_ctl1,LOW);
    digitalWrite(pin_ctl2,HIGH);
  }
  break;
}
}

void motorStop(char motor_num)
{
  setSpeed(motor_num, 0);
  if(motor_num==1)
  {
    digitalWrite(motor1_1,LOW);
    digitalWrite(motor1_2,LOW);
  }
  else
  {
    digitalWrite(motor2_1,LOW);
    digitalWrite(motor2_2,LOW);
  }
}
void turnRight()
{
  motorStart(1, MOTOR_ATRAS);
  setSpeed(1,140);
  motorStart(2, MOTOR_ADELANTE);
  setSpeed(2,140);
  delay(500);
}
void turnLeft()
{
  motorStart(1, MOTOR_ADELANTE);
  setSpeed(1,140);
  motorStart(2, MOTOR_ATRAS);
  setSpeed(2,140);
  delay(500);
}

void Scan()
{
  

  long duration, inches, cm;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  
  

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  delay(100);
}
 

  void loop()
  {
    
    long duration, inches, cm;
  
    
    inches = microsecondsToInches(duration);
    cm = microsecondsToCentimeters(duration);
  
    void Scan();
    servo.write(90);
    motorStart(1, MOTOR_ADELANTE);
    setSpeed(1, 140);
    motorStart(2, MOTOR_ADELANTE);
    setSpeed(2, 140);
    
    cm = distance;
    if(cm < 30)
    {
      motorStop(1);
      motorStop(2);
      delay(500);
      servo.write(0);
      delay(500);
      Scan();
      rDistance=distance;
      servo.write(180);
      delay(500);
      Scan();
      lDistance=distance;
      if(lDistance<rDistance)
      {
        turnRight();
        
      }
      else{
        turnLeft();
      }
    }
  }
    
long microsecondsToInches(long microseconds)
{
  
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  
  return microseconds / 29 / 2;
}
  duration = pulseIn(pingPin, HIGH);

  
  

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  delay(100);

Send a pulse. Wait for a reply. Spend a bunch of time printing useless information (the distance in centimeters might be important, in which case the distance in inches is NOT, and vice versa). Then, as if this hasn’t taken long enough already, sit around with your thumb up you ass for a while. How is this useful?

Well, i didn't see it in that way, i apreciate your advice, i don't see it as a problem, i will remove it anyways, as you said, only distance in cm is important, in this case. If you have knowledge about this i'd apreciate even more that you help me with the actual problem :)

    void Scan();

This is a function prototype, in the middle of loop(). It is NOT a call to the function. Lose the void to call the function.

The function does not return a value. It only populates a local variable, which it prints. The local variable goes out of scope, so the information is lost.

Scan() needs to be called properly. It needs to return a value. The value needs to be stored in a variable for use later.

  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

These do nothing, since duration is undefined.

So, you say that i’m not even calling the function to do 1 scan? what’s the difference between the right way to do it and the way i did?

And the others that you said that they do nothing, i put them because in the condition " if(cm<30", if i dont put that, the program crashes, so i must define " cm", if you’re saying that duration isn’t defined, could i define it as in the void scan ?

ex :

The one i have :

void Scan()
{
  

  long duration, inches, cm;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  
  

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  delay(100);
}
 

  void loop()
  {
    
    long duration, inches, cm;
  
    
    inches = microsecondsToInches(duration);
    cm = microsecondsToCentimeters(duration);

Defining duration would be :

  void loop()
  {
    
    long duration, inches, cm;
  
    
    inches = microsecondsToInches(duration);
    cm = microsecondsToCentimeters(duration);
 duration = pulseIn(pingPin, HIGH);

loop() can't see the "duration" in Scan() and vice versa.

So, you say that i’m not even calling the function to do 1 scan? what’s the difference between the right way to do it and the way i did?

The right way works. Your way doesn’t. Prove that to yourself. In the code you posted, add a Serial.print() statement. You’ll never see the statement being executed.

Have you noticed that digitalRead() returns a value? That analogRead() returns a value? Why doesn’t Scan() return a value?

i put them because in the condition " if(cm<30", if i dont put that, the program crashes

The program doesn’t crash. It may fail to compile. It may fail to do anything useful. But, it does not crash.

Quote
i put them because in the condition " if(cm<30", if i dont put that, the program crashes
The program doesn’t crash. It may fail to compile. It may fail to do anything useful. But, it does not crash.

Yes, that’s what i meant to say, the program fails to compile, i just didn’t have the right words to say it.