Array function is not working [SOLVED]

Guys, my code is kicking my ass here! >:( (Compiles okay)
I have 5 ultrasonic sensors; when an object is sensed, I need the Sensor_Trigger() to run through once and then have the main loop run again.
I know the issue lies on line 47 but I don’t know the correct way to write it for my array. I’ve tried everything I can think of: if, for, while, switch, etc.
What it’s doing is as soon as the serial monitor reads all 5 sensors (0-4), it automatically triggers the Sensor_Trigger() as if an object is detected even though there’s no object (All 5 sensors read between 59-60) 57 should be the trigger point.

IDE 1.8.5

#include <NewPing.h>
#include <L298N.h>

#define SONAR_NUM 5 //Number of sensors.
#define MAX_DISTANCE 61 //Maximum distance (in cm) to ping.

//Driver# 1 - Cube Motor# 1.
  //L298N Motor Driver, Outputs 1-2. Cube motor# 1.
    #define ENA 12 //A PWM Pin (~)
    #define IN1 22 //A digital pin
    #define IN2 23 //A digital pin

L298N Motor_Driver_1_RS(ENA, IN1, IN2);

NewPing sonar[SONAR_NUM] = //Sensor object array. 
{   
  NewPing(2, 3, MAX_DISTANCE), //Sensor 1      
  NewPing(4, 5, MAX_DISTANCE), //Sensor 2
  NewPing(6, 7, MAX_DISTANCE), //Sensor 3
  NewPing(8, 9, MAX_DISTANCE), //Sensor 4
  NewPing(10, 11, MAX_DISTANCE) //Sensor 5
};

void setup() 
{
  Serial.begin(9600); //Starts serial monitor at 9600 bauds.
  Motor_Driver_1_RS.setSpeed(90);
}

void loop() 
{ 
  for (uint8_t i = 0; i < SONAR_NUM; i++) //Loop through each sensor and display results.
    { 
    delay(1000); //Wait 50ms between pings (about 20 pings per second)
    Serial.print(i);
    Serial.print("=");
    Serial.print(sonar[i].ping_cm());
    Serial.print("cm ");
    }
  Serial.println();
  Sensor_Trigger();
}


void Sensor_Trigger()
{
  if(sonar[SONAR_NUM].ping_cm() <= 57)
    {
      Motor_Driver_1_RS.backward();
      Serial.println("Motor Driver 1 L/S is ON - Forward");
      delay(500);
      Motor_Driver_1_RS.stop();
      Serial.println("Motor Driver 1 L/S is OFF");
    }
}

if(sonar[SONAR_NUM].ping_cm() <= 57)

There is no sonar[SONAR_NUM].
There are only sonar[0] to sonar[SONAR_NUM - 1]

I already told DR2727 that in http://forum.arduino.cc/index.php?topic=548301

@ arduino_new
Yes! I’ve tried doing the (sonar[0].ping_cm <= 57) and that works… but only for sonar 0, none of the other sensors. I just can’t figure out how to include ALL 5 of my sensors.
I’ve tried:

  • [0][1][2][3][4]
  • [0-4]
  • [0,1,2,3,4]
  • [5]

It’s not clear to me when the motor should be switched on. You should give a better description.

But this should give the idea how to check all sensors. If all sensors measure more than 57cm, the motor will be activated.

void Sensor_Trigger()
{
  bool isMatch = true;
  for (int sonarCnt = 0; sonarCnt < SONAR_NUM; sonarCnt++)
  {
    if (sonar[sonarCnt].ping_cm() <= 57)
    {
      isMatch = false;
    }
  }

  // if all sensors measure more than 57
  if (isMatch == true)
  {
    Motor_Driver_1_RS.backward();
    Serial.println("Motor Driver 1 L/S is ON - Forward");
    delay(500);
    Motor_Driver_1_RS.stop();
    Serial.println("Motor Driver 1 L/S is OFF");
  }
}

@ sterretje

Thank you so much! I'm still new to coding so I'm trying to break your example down ASAP.

The motor should only be switched on when any of the 5 sensors measure anything less than 57cm.

@ sterretje

Okay, I understand.

  1. set the bool true/false = true.
  2. you made the Arduino start checking from sensor 0 and add 1 each time.
  3. If any sensor (0-4) measures anything less than 57:
  4. Set the bool to false.
  5. If bool is true:
  6. do the whole motor thing.

Yes? Because it’s triggering now every time. (I’ve tried changing the 2nd bool to false as well)

#include <NewPing.h>
#include <L298N.h>

#define SONAR_NUM 5 //Number of sensors.
#define MAX_DISTANCE 61 //Maximum distance (in cm) to ping.

//Driver# 1 - Cube Motor# 1.
  //L298N Motor Driver, Outputs 1-2. Cube motor# 1.
    #define ENA 12 //A PWM Pin (~)
    #define IN1 22 //A digital pin
    #define IN2 23 //A digital pin

L298N Motor_Driver_1_RS(ENA, IN1, IN2);

NewPing sonar[SONAR_NUM] = //Sensor object array. 
{   
  NewPing(2, 3, MAX_DISTANCE), //Sensor 1      
  NewPing(4, 5, MAX_DISTANCE), //Sensor 2
  NewPing(6, 7, MAX_DISTANCE), //Sensor 3
  NewPing(8, 9, MAX_DISTANCE), //Sensor 4
  NewPing(10, 11, MAX_DISTANCE) //Sensor 5
};

void setup() 
{
  Serial.begin(9600); //Starts serial monitor at 9600 bauds.
  Motor_Driver_1_RS.setSpeed(90);
}

void loop() 
{ 
  for (uint8_t i = 0; i < SONAR_NUM; i++) //Loop through each sensor and display results.
    { 
    delay(1000); //Wait 50ms between pings (about 20 pings per second)
    Serial.print(i);
    Serial.print("=");
    Serial.print(sonar[i].ping_cm());
    Serial.print("cm ");
    }
  Serial.println();
  Sensor_Trigger();
}

void Sensor_Trigger()
{
  bool isMatch = true;
  for (int sonarCnt = 0; sonarCnt < SONAR_NUM; sonarCnt++)
  {
    if (sonar[sonarCnt].ping_cm() <= 57)
    {
      isMatch = false;
    }
  }

  // if all sensors measure more than 57
  if (isMatch == true)
  {
    Motor_Driver_1_RS.backward();
    Serial.println("Motor Driver 1 L/S is ON - Forward");
    delay(500);
    Motor_Driver_1_RS.stop();
    Serial.println("Motor Driver 1 L/S is OFF");
  }
}

change to

if (isMatch == false)

to achieve what you are describing

@ arduino_new

Yes, I’ve tried changing the code to “if (isMatch == false)”. But it even if the sensors are all measuring above 57, it still runs the motor anyways. (See attachment)

Please post your full code as it is now

@UKHeliBob

IDE V1.8.5

#include <NewPing.h>
#include <L298N.h>

#define SONAR_NUM 5 //Number of sensors.
#define MAX_DISTANCE 61 //Maximum distance (in cm) to ping.

//Driver# 1 - Cube Motor# 1.
  //L298N Motor Driver, Outputs 1-2. Cube motor# 1.
    #define ENA 12 //A PWM Pin (~)
    #define IN1 22 //A digital pin
    #define IN2 23 //A digital pin

L298N Motor_Driver_1_RS(ENA, IN1, IN2);

NewPing sonar[SONAR_NUM] = //Sensor object array. 
{   
  NewPing(2, 3, MAX_DISTANCE), //Sensor 1      
  NewPing(4, 5, MAX_DISTANCE), //Sensor 2
  NewPing(6, 7, MAX_DISTANCE), //Sensor 3
  NewPing(8, 9, MAX_DISTANCE), //Sensor 4
  NewPing(10, 11, MAX_DISTANCE) //Sensor 5
};

void setup() 
{
  Serial.begin(9600); //Starts serial monitor at 9600 bauds.
  Motor_Driver_1_RS.setSpeed(90);
}

void loop() 
{ 
  for (uint8_t i = 0; i < SONAR_NUM; i++) //Loop through each sensor and display results.
    { 
    delay(1000); //Wait 50ms between pings (about 20 pings per second)
    Serial.print(i);
    Serial.print("=");
    Serial.print(sonar[i].ping_cm());
    Serial.print("cm ");
    }
  Serial.println();
  Sensor_Trigger();
}

void Sensor_Trigger()
{
  boolean isMatch = true;
  for (int sonarCnt = 0; sonarCnt < SONAR_NUM; sonarCnt++)
  {
    if (sonar[sonarCnt].ping_cm() < 57)
    {
      isMatch = false;
    }
  }

  // if all sensors measure more than 57
  if (isMatch == false)
  {
    Motor_Driver_1_RS.backward();
    Serial.println("Motor Driver 1 R/S is ON - Backward");
    delay(500);
    Motor_Driver_1_RS.stop();
    Serial.println("Motor Driver 1 R/S is OFF");
  }
}
  // if all sensors measure more than 57
  if (isMatch == false)

Either the comment is wrong or the code is wrong.

isMatch will be false if any of the sensors return less than 57. It will be true if all of the sensors return more than 57

You will have to reverse all logic.

void Sensor_Trigger()
{
  bool isWithin57 = false;
  for (int sonarCnt = 0; sonarCnt < SONAR_NUM; sonarCnt++)
  {
    if (sonar[sonarCnt].ping_cm() < 57)
    {
      isWithin57 = true;
    }
  }

  // if any of the sensors sensor measures less than 57
  if (isWithin57 == true)
  {
    Motor_Driver_1_RS.backward();
    Serial.println("Motor Driver 1 L/S is ON - Forward");
    delay(500);
    Motor_Driver_1_RS.stop();
    Serial.println("Motor Driver 1 L/S is OFF");
  }
}

@ UKHeliBob
@ sterretje
@ arduino_new

Thank you guys very much for your time and advice.
I would agree with you all about reversing the logic in the code to make it function right. I’ve tried to change the bool logic around but it still doesn’t act right. I’m sure it’s something I’m doing wrong. But I’m not going to give up! You guys have REALLY helped me out; thank you!
I’m going to strip the code bare bones and play around with it line by line until I fully understand what’s going on. I will make sure to post a good working code on this thread when I get it working :slight_smile:

UPDATE:
Got it working thanks to all your guys’ help! +1 Karma for all. There was just no boolean logic to change the state back to the original state once a sensor was tripped and the function executed. A very valuable lesson learned!

IDE v1.8.5

#include <NewPing.h>
#include <L298N.h>

#define SONAR_NUM 5 //Number of sensors.
#define MAX_DISTANCE 61 //Maximum distance (in cm) to ping.

//Driver# 1 - Cube Motor# 1.
  //L298N Motor Driver, Outputs 1-2. Cube motor# 1.
    #define ENA 12 //A PWM Pin (~)
    #define IN1 22 //A digital pin
    #define IN2 23 //A digital pin

L298N Motor_Driver_1_RS(ENA, IN1, IN2);

NewPing sonar[SONAR_NUM] = //Sensor object array. 
{   
  NewPing(2, 3, MAX_DISTANCE), //Sensor 1      
  NewPing(4, 5, MAX_DISTANCE), //Sensor 2
  NewPing(6, 7, MAX_DISTANCE), //Sensor 3
  NewPing(8, 9, MAX_DISTANCE), //Sensor 4
  NewPing(10, 11, MAX_DISTANCE) //Sensor 5
};

void setup() 
{
  Serial.begin(9600); //Starts serial monitor at 9600 bauds.
  Motor_Driver_1_RS.setSpeed(90);
}

void loop() 
{ 
  for (uint8_t i = 0; i < SONAR_NUM; i++) //Loop through each sensor and display results.
    { 
    delay(1000); //Wait 50ms between pings (about 20 pings per second)
    Serial.print(i);
    Serial.print("=");
    Serial.print(sonar[i].ping_cm());
    Serial.print("cm ");
    }
  Serial.println();
  Sensor_Trigger();
}

void Sensor_Trigger()
{
  boolean State = false;
  for (int sonarCount = 0; sonarCount < SONAR_NUM; sonarCount++)
  {
    if (sonar[sonarCount].ping_cm() < 57)
    {
      State = true;
    }
  }

  if (State == true)
  {
    Motor_Driver_1_RS.backward();
    Serial.println ("Motor Driver 1 R/S is ON - Backward");
    delay(500);
    Motor_Driver_1_RS.stop();
    Serial.println ("Motor Driver 1 R/S is OFF");
    boolean State = false;
  }
}

There was just no boolean logic to change the state back to the original state once a sensor was tripped and the function executed.

But in the original code you did set the isMatch variable to true before testing the inputs

What was wrong was that you had the logic inverted. Using a better name for the flag variable would have made that more obvious

That was my 'mistake'; I used isMatch because it was not clear what was needed.

Once that was clear, I did change it in the next code.