Code not working :(

Hi everyone, I am making this robotic car that can self navigate using an ultrasonic sensor mounted on a servo. In my code, I have "if" statements that check the position of the servo and the distance of the ultrasonic sensor which in return controls the motor's speed. However, this is the part that doesn't work. (This part is in void movement() ). I see all the correct values in the serial monitor so it must be a code thing. Does anyone know why the if statements are not working? (There are no error messages) Thanks :slight_smile:

Here is my code:

#include <NewPing.h>
#include <Servo.h>
Servo servo;
#define TRIGGER_PIN 12
#define ECHO_PIN 11
#define MAX_DISTANCE 200
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
int pos = -60;
unsigned int uS = sonar.ping();
int DIS = uS / US_ROUNDTRIP_CM;
int turntime = 0;
int i = 0;

// D5 is LEFT motor
// D3 is RIGHT motor
// 15 degrees is RIGHT!
//120 degrees is LEFT!

void setup()
{
Serial.begin(9600);
pinMode(5, OUTPUT);
pinMode(3, OUTPUT);
servo.attach(9);
}

void loop(){
for (i = 15; i <= 120; i += 1) {
servo.write(i);
pos = servo.read();
Serial.println(pos);
scan();
delay(10);
movement();
}

for (i = 120; i >= 15; i -= 1) {
servo.write(i);
pos = servo.read();
Serial.println(pos);
scan();
delay(10);
movement();

}
}

void scan() {
//delay(300);
unsigned int uS = sonar.ping();
Serial.print("Ping: ");
int DIS = uS / US_ROUNDTRIP_CM;
if (DIS > 30)
{
int DIS = 20;
}
Serial.print(DIS);
Serial.println("cm");

}

void movement() {
if (DIS < 10 and pos < 26.25) {
turntime = 200;
analogWrite(5, 0); analogWrite(3, 0);
delay(200);
analogWrite(5, 0); analogWrite(3, 220);
delay(turntime);
analogWrite(5, 0); analogWrite(3, 0);
}

if (DIS < 10 and pos > 26.25 and pos < 52.5) {
turntime = 100;
analogWrite(5, 0); analogWrite(3, 0);
delay(200);
analogWrite(5, 0); analogWrite(3, 220);
delay(turntime);
analogWrite(5, 0); analogWrite(3, 0);
}

if (DIS < 10 and pos > 52.5 and pos < 78.75){
turntime = 100;
analogWrite(5, 0); analogWrite(3, 0);
delay(200);
analogWrite(5, 0); analogWrite(3, 220);
delay(turntime);
analogWrite(5, 0); analogWrite(3, 0);
}

if (DIS < 10 and pos > 78.75){
turntime = 200;
analogWrite(5, 0); analogWrite(3, 0);
delay(200);
analogWrite(5, 0); analogWrite(3, 220);
delay(turntime);
analogWrite(5, 0); analogWrite(3, 0);
}

else

{
analogWrite(5, 110); analogWrite(3, 85);
}
}

if (DIS > 30)
{
int DIS = 20;
}

This doesn't work because you are creating a NEW variable called 'DIS' inside the 'if' statement. That variable is NOT the same as the one outside the statement and it disappears when the statement is done. What you have is equivalent to:

if (DIS > 30)
{
}

Hi John, I see what you are saying but what can I do to fix it? I am still just learning Arduino so if you could explain why that would be great. :slight_smile:

Remove the "int" keyword.

I did that but it is still not working even when the distance is less than 10 as indicated in the serial monitor. This is the part that is not working.

void movement() {
if (DIS < 10 and pos < 26.25) {
turntime = 200;
analogWrite(5, 0); analogWrite(3, 0);
delay(200);
analogWrite(5, 0); analogWrite(3, 220);
delay(turntime);
analogWrite(5, 0); analogWrite(3, 0);
}

You should post code in code-tags. Easiest way to to this is
press cntrl-T for auto-formatting your code
then to do a right-click with the mouse inside the Arduino-IDE then choose copy for forum and paste the clipboard-content into the posting.

If you do the ctrl-T for autoformatting your code you will see that there is something wrong with your curly brackets.
If you see it not you were lazy in copy & pasting your code

best regards Stefan

Remember how creating a new 'DIS' inside the 'if' statement prevented it from working on the other variable with the same name? You are also creating a local version of 'DIS' in the scan() function. You are not making any change to the global variable named 'DIS'. Again, the fix is to remove the type 'int' in the line where you set the local 'DIS' variable. That will allow the scan() function to change the global 'DIS' variable so the movement() function can see the value.

It is good practice to use a capital letter at the beginning of global variable names and a lowercase letter at the beginning of local variable names.

1 Like

Hi StefanL38, thanks for the suggestion I didn't know. Here is the code formatted:

#include <NewPing.h>
#include <Servo.h>
Servo servo;
#define TRIGGER_PIN  12
#define ECHO_PIN     11
#define MAX_DISTANCE 200
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
int pos = -60;
unsigned int uS = sonar.ping();
int DIS = uS / US_ROUNDTRIP_CM;
int turntime = 0;
int i = 0;

// D5 is LEFT motor
// D3 is RIGHT motor
// 15 degrees is RIGHT!
//120 degrees is LEFT!

void setup()
{
  Serial.begin(9600);
  pinMode(5, OUTPUT);
  pinMode(3, OUTPUT);
  servo.attach(9);
}

void loop() {
  for (i = 15; i <= 120; i += 1) {
    servo.write(i);
    pos = servo.read();
    Serial.println(pos);
    scan();
    delay(10);
    movement();
  }

  for (i = 120; i >= 15; i -= 1) {
    servo.write(i);
    pos = servo.read();
    Serial.println(pos);
    scan();
    delay(10);
    movement();
  }
}


void scan() {
  //delay(300);
  unsigned int uS = sonar.ping();
  Serial.print("Ping: ");
  int DIS = uS / US_ROUNDTRIP_CM;
  //if (DIS > 30)
  //{
  //DIS + 1;
  //}
  Serial.print(DIS);
  Serial.println("cm");

}


void movement() {
  if (DIS < 10 and pos < 26.25) {
    turntime = 200;
    analogWrite(5, 0); analogWrite(3, 0);
    delay(200);
    analogWrite(5, 0); analogWrite(3, 220);
    delay(turntime);
    analogWrite(5, 0); analogWrite(3, 0);
  }

  if (DIS < 10 and pos > 26.25 and pos < 52.5) {
    turntime = 100;
    analogWrite(5, 0); analogWrite(3, 0);
    delay(200);
    analogWrite(5, 0); analogWrite(3, 220);
    delay(turntime);
    analogWrite(5, 0); analogWrite(3, 0);
  }

  if (DIS < 10 and pos > 52.5 and pos < 78.75) {
    turntime = 100;
    analogWrite(5, 0); analogWrite(3, 0);
    delay(200);
    analogWrite(5, 0); analogWrite(3, 220);
    delay(turntime);
    analogWrite(5, 0); analogWrite(3, 0);
  }

  if (DIS < 10 and pos > 78.75) {
    turntime = 200;
    analogWrite(5, 0); analogWrite(3, 0);
    delay(200);
    analogWrite(5, 0); analogWrite(3, 220);
    delay(turntime);
    analogWrite(5, 0); analogWrite(3, 0);
  }

  else

  {
    analogWrite(5, 110); analogWrite(3, 85);
  }
}

Here is a democode that uses a compiler-macro to "program" a quick titled debug-output in a single line of code.

You can use this to see what values the variables of your code really have

This "function" has two parameters. The first parameter can be used as a title, the second parameter is the variable. The function will print the variables name and the value.

This can only be done with a define-macro. The define-macro resolves to multiple lines of code.

void PrintFileNameDateTime()
{
  Serial.println("Code running comes from file ");
  Serial.println(__FILE__);
  Serial.print("  compiled ");
  Serial.print(__DATE__);
  Serial.print(" ");
  Serial.println(__TIME__);  
}


boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();  
  if ( currentMillis - expireTime >= TimePeriod )
  {
    expireTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  } 
  else return false;            // not expired
}

unsigned long MyTestTimer = 0;                   // variables MUST be of type unsigned long
const byte    OnBoard_LED = 2;


void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);
  
  if ( TimePeriodIsOver(MyBlinkTimer,BlinkPeriod) ) {
    digitalWrite(IO_Pin,!digitalRead(IO_Pin) ); 
  }
}


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  PrintFileNameDateTime();
}

//#define debugTxtVar(abc, def) Serial.print("<  "#abc" = "); Serial.print(def); Serial.println('>')

// using the #define "statement" to make the compiler "write" code
// #define can be used to make the compiler replace text that describes something with (almost) anything else
// easy example 
// let's assume IO-pin number 4 shall be set to work as output 
// the command for defining an IO-pin to be configured as output is
//
// pinMode(4,OUTPUT); 
// the number "4" says nothing about he purpose of this IO-pin

// let's assume the IO-pin shall switch On/Off a buzzer

// you would have to add a comment to explain
// pinMode(4,OUTPUT); // IO-pin 4 is buzzer

// the compiler needs the number. To make the code easier to read and understand
// #define BuzzerPin 4
// So the command looks like this
// pinMode(BuzzerPin,OUTPUT);

// the descriptive word "BuzzerPin" gets replaced through the compiler by a "4"
// so what the compiler compiles is still 'pinMode(4,OUTPUT);'

// the #define can do much more than just replace a word by a single number
// it can even take parameters like in this example

#define debugTxtVar(myParameterText, variableName) \
        Serial.print(#myParameterText " " #variableName"="); \
        Serial.println(variableName); 
        
int myVar = 1234;
int mySecondVar = 999;

void loop() {
  BlinkHeartBeatLED(OnBoard_LED,250);

  if ( TimePeriodIsOver(MyTestTimer,1000) ) {
    debugTxtVar("first line " , myVar);
    mySecondVar++;
    debugTxtVar("second line" , mySecondVar);
  }  
}

best regards Stefan

Thank you guys it worked!

#include <NewPing.h>
#include <Servo.h>

const byte RightMotorPin = 3;
const byte LeftMotorPin = 5;
const byte ServoPin = 9;
const byte ECHO_PIN = 11;
const byte TRIGGER_PIN = 12;

Servo servo;

const unsigned MAX_DISTANCE = 200;
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

unsigned MinDistance;
int MinDistanceAngle;

// D5 is LEFT motor
// D3 is RIGHT motor

const byte RightLimit = 15;
const byte LeftLimit = 120;


void setup()
{
  Serial.begin(9600);

  pinMode(RightMotorPin, OUTPUT);
  pinMode(LeftMotorPin, OUTPUT);

  servo.attach(ServoPin);
}

void loop()
{
  MinDistance = MAX_DISTANCE;
  MinDistanceAngle = 90;

  // Sweep the servo, recording the angle with
  // the shortest distance to an obstacle
  for (int i = RightLimit; i <= LeftLimit; i++)
  {
    scan(i);
  }

  // Sweep the servo, recording the angle with
  // the shortest distance to an obstacle
  for (int i = LeftLimit; i >= RightLimit; i--)
  {
    scan(i);
  }

  // Turn if there is an obstacle within 10cm
  movement();
}

// Record the angle with the closest obstacle
void scan(int angle)
{
  servo.write(angle);
  delay(10);

  unsigned distance = sonar.ping_cm();
  Serial.print("Ping: ");
  Serial.print(distance);
  Serial.println(" cm");

  // Record the angle if the distance is smaller
  // than the previously recorded minimum.
  if (distance != 0 && distance < MinDistance)
  {
    MinDistance = distance;
    MinDistanceAngle = angle;
  }
}

void turnLeft(int turntime)
{
  analogWrite(LeftMotorPin, 0);
  analogWrite(RightMotorPin, 0);
  delay(200);
  analogWrite(LeftMotorPin, 0);
  analogWrite(RightMotorPin, 220);
  delay(turntime);
  analogWrite(LeftMotorPin, 0);
  analogWrite(RightMotorPin, 0);
}

void movement()
{
  // If no obsticles are within 10cm, go forward
  if (MinDistance > 10)
  {
    analogWrite(LeftMotorPin, 110);
    analogWrite(RightMotorPin, 85);
    return;
  }

  // If an obstacle is close, steer away
  if (MinDistanceAngle < 27)
  {
    turnLeft(200);
  }
  else if (MinDistanceAngle < 53)
  {
    turnLeft(100);
  }
  else if (MinDistanceAngle < 79)
  {
    turnLeft(100);
  }
  else // MinDistanceAngle >= 79
  {
    turnLeft(200);
  }
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.