For loop behaving strangely

Please examine the code and the attached serial output.
The set up loop is initialised to 0, but the first time around the loop the value selected for i is 0 and the value selected for ServoPins is 4. It should 1 and the ServoPins[i] should therefore contain 3, 4, 5, 6 but they don't, they have 4,5,6,0 which means my code is selecting the wrong servo.
What is going wrong?

[code]
#include <Servo.h>

Servo servo[4];

//constants
const byte InputPins[] = {8, 9, 10, 11};
const byte NrServos = sizeof(InputPins);
const byte ServoPins[NrServos] = {3, 4, 5, 6};

//Variables

bool previousButtonState1 = 0;
bool previousButtonState2 = 0;

int pos1 = 90;    // variable to store the servo position // Crossing 1 - left gate servo
int pos2 = 90;    // variable to store the servo position // Crossing 1 - right gate servo
int pos3 = 90;    // variable to store the servo position // Crossing 2 - left gate servo
int pos4 = 90;    // variable to store the servo position // Crossing 2 - right gate servo

void setup() {
     Serial.begin(9600);
     Serial.println("Start");

  for (byte i = 0; i < NrServos; i++) {
    
    Serial.println(ServoPins[i]);
    Serial.println(i);
    pinMode(InputPins[i], INPUT_PULLUP);       // set pins to INPUT with pullup
    servo[i].attach(ServoPins[i]);
    servo[i].write(90);       // move servo to Initial position
    delay(500);
    Serial.println("done");
 
     }
   Serial.println(pos1);
   Serial.println(pos2);
   Serial.println(pos3);
   Serial.println(pos4);

   Serial.println("NrServos");
   Serial.println(NrServos);

   Serial.println("ServoPins"); 
   Serial.println(ServoPins[1]);
   Serial.println(ServoPins[2]);
   Serial.println(ServoPins[3]);
   Serial.println(ServoPins[4]);
  
}

Serial Output
Start
3
0
done
4
1
done
5
2
done
6
3
done
90
90
90
90
NrServos
4
ServoPins
4
5
6
0


[/code]

Hello rynd2it

The array starts with the index 0:

   Serial.println("ServoPins"); 
   Serial.println(ServoPins[0]);
   Serial.println(ServoPins[1]);
   Serial.println(ServoPins[2]);
   Serial.println(ServoPins[3]);

Check this mods.

hth

1 Like

Or:

for (int i=0; i<NrServos); i++) {
    Serial.println(ServoPins[i]);
}

Well, that did alter the behaviour and the correct value is now shown in the ServoPins. I have changed the rest of my code to use servo[0] etc but for some reason servo[0] does not move even though the code shows all the loop values are used. servo[1] works fine as does servo[2] and servo[3]

void loop() 
{
   const bool State1 = digitalRead(8);      // Has crossing 1 changed?
   Serial.println(State1);
    if (State1 != previousButtonState1) {
        previousButtonState1 = State1;   
        
        if (pos1 <= 90)                     // move left gate
            {
            Serial.println(pos1);
            Serial.println("Move left gate to 179"); 
            for (; pos1 < 179; pos1 ++)       
              {
                servo[0].write(pos1); 
                Serial.println(pos1); 
                 delay(100);                 // tell servo to go to position in variable 'pos'
              }
            }             
        else  
            { 
            Serial.println(pos1);
            Serial.println("Move left gate to 1");
            for (; pos1 >= 90; pos1 --) 
              {  
                servo[0].write(pos1); 
                 delay(100);                 // tell servo to go to position in variable 'pos'
              }         
            }        
      
        if (pos2 >=1)                       // move right gate
            {
            Serial.println(pos2);
            Serial.println("Move right gate to 1"); 
            for (; pos2 >=1; pos2 --)       
              {
                servo[1].write(pos2); 
                 delay(100);                 // tell servo to go to position in variable 'pos'
              }
            }             
        else  
            { 
            Serial.println(pos2);
            Serial.println("Move right gate to 90");          
            for (; pos2 <90; pos2 ++) 
              {  
                servo[1].write(pos2); 
                 delay(100);                 // tell servo to go to position in variable 'pos'
              }   
            }
    }
        

Hello rynd2it

Insert Serial.println (what I want to know) at interesting points to check the programme logic.

I have and the monitor shows the "Move left gate to 179" so it is being executed but the servo doesn't move.
I don't seem to be able to Serial.println the value that is in servo[0] it won't compile. Thats what I want to know :wink:

Check all of this again

Always post your complete code. As a beginner, you may be wrong about where the problem truly lies.

Please always click Tools->Auto Format before posting your code, to make it easier to read and spot errors.

If your code will not compile, also post the complete set of error messages. Post these in code tags, but not the same code tags as your code.

Here's the entire sketch, note the part where servo[0] moves the left gate to 179 and look at the trace from the serial monitor I posted above. The servo does not actually move, all the other three do, and correctly

[code]
#include <Servo.h>

Servo servo[4];

//constants
const byte InputPins[] = {8, 9, 10, 11};
const byte NrServos = sizeof(InputPins);
const byte ServoPins[NrServos] = {3, 4, 5, 6};

//Variables

bool previousButtonState1 = 0;
bool previousButtonState2 = 0;

int pos1 = 90;    // variable to store the servo position // Crossing 1 - left gate servo
int pos2 = 90;    // variable to store the servo position // Crossing 1 - right gate servo
int pos3 = 90;    // variable to store the servo position // Crossing 2 - left gate servo
int pos4 = 90;    // variable to store the servo position // Crossing 2 - right gate servo

void setup() {
  Serial.begin(9600);
  Serial.println("Start");

  for (byte i = 0; i <= NrServos; i++) {

    Serial.println(ServoPins[i]);
    Serial.println(i);
    Serial.println(Servo[i]);
    pinMode(InputPins[i], INPUT_PULLUP);       // set pins to INPUT with pullup
    servo[i].attach(ServoPins[i]);
    servo[i].write(90);       // move servo to Initial position
    delay(500);
    Serial.println("done");

  }
  Serial.println(pos1);
  Serial.println(pos2);
  Serial.println(pos3);
  Serial.println(pos4);

  Serial.println("NrServos");
  Serial.println(NrServos);

  Serial.println("ServoPins");
  Serial.println(ServoPins[0]);
  Serial.println(ServoPins[1]);
  Serial.println(ServoPins[2]);
  Serial.println(ServoPins[3]);

}

void loop()
{
  const bool State1 = digitalRead(8);      // Has crossing 1 changed?
  Serial.println(State1);
  if (State1 != previousButtonState1) {
    previousButtonState1 = State1;

    if (pos1 <= 90)                     // move left gate
    {
      Serial.println(pos1);
      Serial.println("Move left gate to 179");
      for (; pos1 < 179; pos1 ++)
      {
        servo[0].write(pos1);
        Serial.println(pos1);
        delay(100);                 // tell servo to go to position in variable 'pos'
      }
    }
    else
    {
      Serial.println(pos1);
      Serial.println("Move left gate to 1");
      for (; pos1 >= 90; pos1 --)
      {
        servo[0].write(pos1);
        delay(100);                 // tell servo to go to position in variable 'pos'
      }
    }

    if (pos2 >= 1)                      // move right gate
    {
      Serial.println(pos2);
      Serial.println("Move right gate to 1");
      for (; pos2 >= 1; pos2 --)
      {
        servo[1].write(pos2);
        delay(100);                 // tell servo to go to position in variable 'pos'
      }
    }
    else
    {
      Serial.println(pos2);
      Serial.println("Move right gate to 90");
      for (; pos2 < 90; pos2 ++)
      {
        servo[1].write(pos2);
        delay(100);                 // tell servo to go to position in variable 'pos'
      }
    }
  }

  const bool State2 = digitalRead(9);      // Has crossing 2 changed?

  if (State2 != previousButtonState2) {
    previousButtonState2 = State2;

    if (pos3 <= 90)                    //move left gate
    {
      for (; pos3 < 179; pos3 ++)
      {
        servo[2].write(pos3);
        delay(100);                 // tell servo to go to position in variable 'pos'
      }
    }
    else
    {
      for (; pos3 >= 90; pos3 --)
      {
        servo[2].write(pos3);
        delay(100);                 // tell servo to go to position in variable 'pos'
      }

    }

    if (pos4 >= 1)
    {
      for (; pos4 >= 1; pos4 --)      // move right gate
      {
        servo[3].write(pos4);
        delay(100);                 // tell servo to go to position in variable 'pos'
      }
    }
    else
    {
      for (; pos4 < 90; pos4 ++)
      {
        servo[3].write(pos4);
        delay(100);                 // tell servo to go to position in variable 'pos'
      }
    }
  }
}
[/code]

Shouldn't that be:

for (pos1; pos1 < 179; pos1 ++)

?

You need to post the error messages for this.

Blockquote [quote="rynd2it, post:9, topic:1290954"]
for (; pos1 < 179; pos1 ++)
[/quote]

Shouldn't that be:

for (pos1; pos1 < 179; pos1 ++)

?
/quote

Why, that syntax works OK on the other three loops?

My guess: a wiring issue with servo 1.
Post a picture of your setup... maybe we can find what is wrong...

Shouldn't that be:

   Serial.println("ServoPins"); 
   Serial.println(ServoPins[0]);
   Serial.println(ServoPins[1]);
   Serial.println(ServoPins[2]);
   Serial.println(ServoPins[3]);
?

That IS legal syntax, but is saving 4 keystrokes worth the confusion to others reading your code?

Blockquote JCA34F

17mpost #14

Shouldn't that be:

   Serial.println("ServoPins"); 
   Serial.println(ServoPins[0]);
   Serial.println(ServoPins[1]);
   Serial.println(ServoPins[2]);
   Serial.println(ServoPins[3]);
?
```/quote

It is, I think you are looking at an older version when that was wrong, see the full listing above

It's good to see you using arrays in your code:

Servo servo[4];

const byte InputPins[] = {8, 9, 10, 11};

const byte ServoPins[NrServos] = {3, 4, 5, 6};

But not consistently. I guess you copied some parts of the code from others, but when you came to adding more code to it, you forgot about using arrays. These should be arrays:

bool previousButtonState1 = 0;
bool previousButtonState2 = 0;

int pos1 = 90;    // variable to store the servo position // Crossing 1 - left gate servo
int pos2 = 90;    // variable to store the servo position // Crossing 1 - right gate servo
int pos3 = 90;    // variable to store the servo position // Crossing 2 - left gate servo
int pos4 = 90;

Any time you find yourself declaring variables with the same name except for a number, that should almost certainly be an array.

BlockquoteMy guess: a wiring issue with servo 1.
Post a picture of your setup... maybe we can find what is wrong...
/quote

Blockquote It's good to see you using arrays in your code:

Servo servo[4];
```/quote
As a programmer with over 40 years experience (not in C++) I agree with you, but this was a quick test rig build and I copied chunks of code from samples. The aesthetics can always be improved later, I need it to work and right now it doesn't and I cannot find out why. Hence my questions. It seems there might be a hardware issue, I'll need to do some more testing by switching servos around to see if it make a difference.

Try swapping the wires between the non-working servo and a working servo. This will help you diagnose whether the problem is with the servo or the Arduino.