Question on using 2 variable [i] arrays in main loop

Hello,
A while back AWOL helped me out with a ping code.
The first array is the ping pins and the second is the minimum threshold values.
I was wondering if the following uses of ‘i’ in the main loop would work:

int range [N_PINGS];
  for (int i = 0; i < N_PINGS; ++i) 
  {
    range [i] = ping(pingPins [i]);

    //delay(5);
  }

  int pingThresh [N_PINGS];
  for (int i = 0; i < N_PINGS; ++i) 
  {
    minRanges [i];
    //delay(5);
  }

Here is the full sketch:

//Sabertooth 2X25 motor controlled robot in RC microcontroller (mixed) mode
// with differential & exponential settings.
//S1 controls throttle.
//S2 controls steering.
//Date:  2Jan14

#include <Servo.h>
#define N_PINGS 4
const byte pingPins [N_PINGS] = {
  22, 23, 24, 25};   // PING pins
const int minRanges [N_PINGS] = {
  14, 14, 40, 12};  // Thresholds for PING sensors

Servo servoThrottle; // create servo object for throttle
Servo servoSteering; // create servo object steering

int throtSpeed = 1500; // variable to store the servo position or speed
int steerSpeed = 1500; // variable to store the servo position or speed

//long previousMillis = 0;



void setup()
{
  Serial.begin(9600);
  servoThrottle.attach(53, 1000, 2000); // attach the throttle servo  
  servoSteering.attach(52, 1000, 2000); // attach the steering servo 
}



void loop()
{
  int range [N_PINGS];
  for (int i = 0; i < N_PINGS; ++i) 
  {
    range [i] = ping(pingPins [i]);

    //delay(5);
  }

  int pingThresh [N_PINGS];
  for (int i = 0; i < N_PINGS; ++i) 
  {
    minRanges [i];
    //delay(5);
  }

  if(range [0,1,2] <= minRanges [0,1,2]) 
  {
    motStop();
  }

  if(range [0] <= minRanges [0])
  {
    motRight();
    delay(10);
  }

  if(range [1] <= minRanges [1])
  {
    motLeft();
    delay(10);
  } 

  if(range [2] > minRanges [2])
  {
    motForward(); 
  }

  if((range [0] > range [1]) && (range [0] > range [2]))   //If Left ping distance is greater than the right ping distance and center ping distance
  {
    motLeft();
    delay(10);
  }

  else if((range [1] > range [0]) && (range [1] > range [2]))   //If Right ping distance is greater than the left ping distance and center ping distance
  {
    motRight();
    delay(10);
  }

  else if((range [2] > range [0]) && (range [2] > range [1]))  //If center ping distance is greater than the left ping distance and right ping distance
  {
    motForward();
  }




  //Other conditions here......
  //
  //
}




long ping(int pin)
{

  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);
  delayMicroseconds(2);
  digitalWrite(pin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pin, LOW);
  pinMode(pin, INPUT);

  return (microsecondsToInches(pulseIn(pin, HIGH)));
}

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


void motForward()
{
  for(throtSpeed; throtSpeed < 1800; throtSpeed += 20)
  {
    servoThrottle.write(throtSpeed);
    servoSteering.write(1500);
    if(throtSpeed < 1500);
    motStop();
  }
}


void motBackward()
{
  for(throtSpeed; throtSpeed > 1200; throtSpeed -= 20) 
  {
    servoThrottle.write(throtSpeed);
    servoSteering.write(1500);
    if(throtSpeed > 1500);
    motStop;
  }
}


void motStop()
{
  for(throtSpeed; throtSpeed < 1500; throtSpeed += 20) 
  {
    servoThrottle.write(1500);
    servoSteering.write(1500);
    if(throtSpeed < 1500); 
  }

  for(throtSpeed; throtSpeed > 1500; throtSpeed -= 20)
  {
    servoThrottle.write(1500);
    servoSteering.write(1500);
    if(throtSpeed > 1500);
  }
}


void motRight()
{
  for(steerSpeed; steerSpeed < 1650; steerSpeed += 10)
  {
    servoSteering.write(steerSpeed);
    delay(10);  
  }
}


void motLeft()
{
  for(steerSpeed; steerSpeed > 1350; steerSpeed -= 10)
  {
    servoSteering.write(steerSpeed);
    delay(10);
  }
}

*Also, if I wanted to make the min. thresholds array variable according to the current motor speed, would this work?:

const byte pingPins [N_PINGS] = {22, 23, 24, 25};   // PING pins
int minRanges [N_PINGS] = {A, B, C, D};           // Variable thresholds for PING sensors

t

The are an operator. They cause some code to be executed to compute the location of the nth element of the array, based on the starting address of the array, the value in the brackets, and the type of the elements in the array.

That you use i or n or index or sduRThw in the brackets is completely irrelevant.

In your snippets, i is a local variable in both loops. It is NOT the same variable in each case.

Hey Paul, good to hear from you again :slight_smile:

So is i independent in each of the For loops?

What about making the minRange thresholds variable in an array?

int range [N_PINGS];
  for (int i = 0; i < N_PINGS; ++i) 
  {
    range [i] = ping(pingPins [i]);

    //delay(5);
  }

  int range2 [N_PINGS];
  for (int i = 0; i < N_PINGS; ++i) 
  {
    range2 [i] = minRanges [i];
    //delay(5);
  }

So is i independent in each of the For loops?

Completely. There would be no difference in the way the code behaves if, in fact, you changed i to j in one of the loops.

What about making the minRange thresholds variable in an array?

What about it?

PaulS:

What about making the minRange thresholds variable in an array?

What about it?

In this array:

int A;  // Variable to hold left ping min. threshold
int B;  // Variable to hold right ping min. threshold
int C;  // Variable to hold center ping min. threshold
int D;  // Variable to hold rear ping min. threshold
int minRanges [N_PINGS] = {A, B, C, D};

Would this array work to hold variable values of min. thresholds that change according to the motor speed?

Next reply I'll type up a sketch of what I'd like to do.

Would this array work to hold variable values of min. thresholds that change according to the motor speed?

Yes, but you don’t need the A,B,C,D variables as well - you can use the array members directly.

wildbill:

Would this array work to hold variable values of min. thresholds that change according to the motor speed?

Yes, but you don’t need the A,B,C,D variables as well - you can use the array members directly.

Thanks for the reply.
If I don’t declare A, B, C and D, when I verify, it tells me A, B, C, D are not declared in this scope (global).

Here is a sketch I put together:

#include <Servo.h>
Servo servoThrottle;         // Initialize servos
Servo servoSteering;

int A;  // Variable to hold left ping min threshold
int B;  // Variable to hold right ping min threshold
int C;  // Variable to hold center ping min threshold
int D;  // Variable to hold rear ping min threshold

#define N_PINGS 4
const byte pingPins [N_PINGS] = {
  22, 23, 24, 25};   // PING pins
int minRanges [N_PINGS] = {
  A, B, C, D};  // Thresholds for PING sensors

int actualSpeed = 0; // the speed the motor is currently running at
int targetSpeed = 0; // the speed we want the motor to be running at
unsigned long lastSpeedUpdateTime = 0;
const unsigned long SPEED_UPDATE_INTERVAL = 10; // ms

void setup()
{	
  Serial.begin(9600);
  servoThrottle.attach(53, 1000, 2000);  // Attach servos throttle and steering
  servoSteering.attach(52, 1000, 2000);
}


long ping(int pin)
{
  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);
  delayMicroseconds(2);
  digitalWrite(pin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pin, LOW);
  pinMode(pin, INPUT);

  return (microsecondsToInches(pulseIn(pin, HIGH)));
}


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


void speedThresh()
{
  int range2 [N_PINGS];
  for (int i = 0; i < N_PINGS; ++i) 
  {    
    range2 [i] = minRanges[i];
    int currentSpeed = map(range2 [i], 14, 60, 150, 200);
    actualSpeed = currentSpeed * 10;
  } 
}


void setSpeed(int requiredSpeed)
{
  targetSpeed = requiredSpeed;
}


void handleAcceleration()
{
  speedThresh();
  unsigned long now = millis();
  if(now - lastSpeedUpdateTime > SPEED_UPDATE_INTERVAL)
  {
    // time to check the motor speed again
    if(actualSpeed < targetSpeed)
    {
      // accelerating
      actualSpeed++;
      servoThrottle.write(actualSpeed);
    }
    else if(actualSpeed > targetSpeed)
    {
      // deccelerating
      actualSpeed--;
      servoThrottle.write(actualSpeed);
    }
    else
    {
      // motor is already at the target speed - no action required
    }
    lastSpeedUpdateTime = now;
  }
}


void loop()
{
  //For PING sensors:  
  int range [N_PINGS];
  for (int i = 0; i < N_PINGS; ++i) 
  {
    range [i] = ping(pingPins [i]);
    //delay(5);
  }  

  handleAcceleration();
  //... etc
}

If I don't declare A, B, C and D, when I verify, it tells me A, B, C, D are not declared in this scope (global).

Put the values that would have been in A, B, C and D directly into the array.

int minRanges [N_PINGS] = {20, 30, 20, 10};  // Thresholds for PING sensors

UKHeliBob:

If I don’t declare A, B, C and D, when I verify, it tells me A, B, C, D are not declared in this scope (global).

Put the values that would have been in A, B, C and D directly into the array.

int minRanges [N_PINGS] = {20, 30, 20, 10};  // Thresholds for PING sensors

Thanks for the help.
So possibly something like this?:

#include <Servo.h>
Servo servoThrottle;         // Initialize servos
Servo servoSteering;

#define N_PINGS 4
const byte pingPins [N_PINGS] = {
  22, 23, 24, 25};   // PING pins
int minRanges [N_PINGS] = {
  14, 14, 36, 14};  // Thresholds for PING sensors

int actualSpeed = 0; // the speed the motor is currently running at
int targetSpeed = 0; // the speed we want the motor to be running at
unsigned long lastSpeedUpdateTime = 0;
const unsigned long SPEED_UPDATE_INTERVAL = 10; // ms

void setup()
{	
  Serial.begin(9600);
  servoThrottle.attach(53, 1000, 2000);  // Attach servos throttle and steering
  servoSteering.attach(52, 1000, 2000);
}


long ping(int pin)
{
  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);
  delayMicroseconds(2);
  digitalWrite(pin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pin, LOW);
  pinMode(pin, INPUT);

  return (microsecondsToInches(pulseIn(pin, HIGH)));
}


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


void speedThresh()
{
  int range2 [N_PINGS];
  for (int i = 0; i < N_PINGS; ++i) 
  {    
    range2 [i] = minRanges[i];
    int currentSpeed = map(range2 [i], 14, 60, 150, 200);
    actualSpeed = currentSpeed * 10;
  } 
}


void setSpeed(int requiredSpeed)
{
  targetSpeed = requiredSpeed;
}


void handleAcceleration()
{
  speedThresh();
  unsigned long now = millis();
  if(now - lastSpeedUpdateTime > SPEED_UPDATE_INTERVAL)
  {
    // time to check the motor speed again
    if(actualSpeed < targetSpeed)
    {
      // accelerating
      actualSpeed++;
      servoThrottle.write(actualSpeed);
    }
    else if(actualSpeed > targetSpeed)
    {
      // deccelerating
      actualSpeed--;
      servoThrottle.write(actualSpeed);
    }
    else
    {
      // motor is already at the target speed - no action required
    }
    lastSpeedUpdateTime = now;
  }
}


void loop()
{
  //For PING sensors:  
  int range [N_PINGS];
  for (int i = 0; i < N_PINGS; ++i) 
  {
    range [i] = ping(pingPins [i]);
    //delay(5);
  }  

  handleAcceleration();
  //... etc
}

Btw, this is the function that handles the threshold/speed (not sure if it’s right though)

void speedThresh()
{
  int range2 [N_PINGS];
  for (int i = 0; i < N_PINGS; ++i) 
  {    
    range2 [i] = minRanges[i];
    int currentSpeed = map(range2 [i], 14, 60, 150, 200);
    actualSpeed = currentSpeed * 10;
  } 
}

The values are up to you of course but the principle looks OK.

Now you can read the pingPins in a for loop and test the distance returned by using the loop variable as the index to the minRanges array to get the correct range for the pingPin being used.