FOR loop returns "i" was not delcared in this scope

Do I have to really declare a variable type in a for loop?

void loop() 
{
  for(i=1; i<9; i++)
  {
  Serial.println(i);
  }
}

error: "i" was not declared in this scope.

Thanks!

try.

For loop in C++ with example (beginnersbook.com)

You have to declare it somewhere. It can be in the for loop conditional statement, or any scope that the for loop is contained in, for example globally (outside any function), or in setup(), loop() or any other function that it is contained in.

If not, how would the compiler know what data type you want to use?

C++ is a strongly-typed language, and requires every variable to be declared with its type before its first use. This informs the compiler the size to reserve in memory for the variable and how to interpret its value.

https://www.arduino.cc/en/pmwiki.php?n=reference/for

The graphic is misleading - I understand typing but here is my issue -

I want to cycle through some relays that I have defined as 'Relay_1, Relay_2...' They are not on consecutive pins and I am having issues concating a string relay = "Relay_" with'i' in the loop. Works fine in Serial.println() but not in digitalWrite()....

https://www.arduino.cc/en/pmwiki.php?n=reference/for

For advice on code, please post it.

So make an array of pin numbers

Here is an example to fiddle with LEDs defined via an array.

const uint8_t ledPins[4] = { A1, A2, A3, A0 };
const uint8_t lastIndex = sizeof(ledPins) - 1;
const uint16_t blinkDuration = 200;
uint32_t lastBlink;
uint8_t currLed = lastIndex;

void setup() {
  for (int i = 0; i<= lastIndex; i++) {
    pinMode(ledPins[i], OUTPUT);
  }
}

void loop() {
  uint32_t topLoop = millis();
  if (topLoop - lastBlink >= blinkDuration) {
    lastBlink = topLoop;
    digitalWrite(ledPins[currLed], LOW);  // switch off last lit
    if (++currLed > lastIndex) {
      currLed = 0;
    }
    digitalWrite(ledPins[currLed], HIGH); // lite new
  }
}
1 Like

Would it have been a bit more helpful to have disclosed such info in the OP?

2 Likes

I would like to use friendly labels instead of array items.
Serial.print works when "i" is an int and the digitalWrite() are commented out.

Uncommented, I get "cannot convert 'StringSumHelper' to 'uint8_t' {aka 'unsigned char'}

String relay = "Relay_";

void setup() 
{ 

#define Relay_1  10 
#define Relay_2  7
#define Relay_3  3
#define Relay_4  1
#define Relay_5  38
#define Relay_6  33
#define Relay_7  6
#define Relay_8  5

pinMode(Relay_1, OUTPUT);   
pinMode(Relay_2, OUTPUT); 
pinMode(Relay_3, OUTPUT); 
pinMode(Relay_4, OUTPUT);
pinMode(Relay_5, OUTPUT);
pinMode(Relay_6, OUTPUT);
pinMode(Relay_7, OUTPUT);
pinMode(Relay_8, OUTPUT); 

digitalWrite(Relay_1, HIGH);  //HIGH IS ON LED, but open N0/COM circuit
digitalWrite(Relay_2, HIGH);
digitalWrite(Relay_3, HIGH);
digitalWrite(Relay_4, HIGH); 
digitalWrite(Relay_5, HIGH);
digitalWrite(Relay_6, HIGH);
digitalWrite(Relay_7, HIGH);
digitalWrite(Relay_8, HIGH);
}
void loop()
{
for(int i=1; i<9; i++)
  {
  Serial.println(relay + i);    //prints Relay_1, Relay_2...
  delay(1000);
 /* 
  digitalWrite(relay + i, LOW);
  delay(1000);
  digitalWrite(relay + i, HIGH);
  delay(1000);
  */
  } 
}//end of Loop

Friendly names are replaced by addresses by the compiler.

If you want to maintain numerical values alongside "friendly names", you can create a struct that holds both, and then reference the value or the string element depending on your need.

1 Like

What it less friendly when you use

pinMode(Relay[1], OUTPUT);   
pinMode(Relay[2], OUTPUT); 
pinMode(Relay[3], OUTPUT); 
...

instead of

pinMode(Relay_1, OUTPUT);   
pinMode(Relay_2, OUTPUT); 
pinMode(Relay_3, OUTPUT); 

Your program might actually work if you define your Relays as const variables:

const int Relay_1  = 10;