Function - Variable don't want to set?

Hi, im fighting whit this problem:

int sogliaBuilder(){
if(irReader() <= 1){
int soglia = 0;
}else{
int soglia = 1;
}
return soglia;

where irReader is a function than returns an analog input around 20/30. (That'a an infrared sensore, than switch to 0 when i give it a signal).
When I try to print "soglia" whit Serial.println(soglia), soglia is equal to 0. I can't undertand why! I've tried to print irReader and it returns correctly values around 20/30. So, why soglia is not = 0? Please, i can't understand where is the problem!

I'm guessing you've got multiple variables with the same name.

That's a snippet of an answer, to match the snippet of code you posted.

Hint: SCOPE

Move the int before the if

int sogliaBuilder(){
  int soglia = 0; // or what value you want
  if(irReader() <= 1){
   soglia = 0;
    }else{
     soglia = 1;
     }
   return soglia;

Your code did not know that soglia exist outside the if statement.

Your code did not know that soglia exist outside the if statement.

It knew that "a" soglia" existed, otherwise it wouldn't have compiled.

Can you post all the code?


  1. Why did he used int inside the if?
  2. Did he tried to use 1 and 2 as values instead of 0 and 1?

gvs_ro:
Can you post all the code?


  1. Why did he used int inside the if?
  2. Did he tried to use 1 and 2 as values instead of 0 and 1?

Sure! Here it is!

/* MULTY-ACTION WITH TIMER
Utilizzare per trarre diverse azioni da un unico sensore/bottone.
In basso sono indicate tutte le funzioni utilizzate!
*/

//Dichiaro le variabili all'esterno per renderle globali. Una variabile è valida da dove è stata dichiarata in giù, quindi se dichiarata esternamente a tutto, sarà sempre valida (globale)
int infrared1;
int infrared2;
int infrared3;
int infrared4;
int infrared5;
int infrared6;
int infraredValue;
int soglia;

int pinPila = 13;
int destraAvanti = 12; //se ON le ruote di destra vanno avanti
int destraIndietro = 2;
int sinistraAvanti = 3;
int sinistraIndietro = 4;
int pinLuci = 6;

void setup() { //SETUP viene eseguito una volta. E' OBBLIGATIORIO!!
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
pinMode(pinPila, OUTPUT);
}

void loop() { // Il LOOP viene eseguito di continuo. arrivato alla fine ricomincia. E' OBBLIGATORIO!!
//automFari(); //La funzione controlla la luminostà e accende o spegne i fari.

int infraredValue = irReader(); //carico i dati del sensore
int soglia = sogliaBuilder(); //avvio la costruzione della soglia

if(soglia == 1){soglia = 0; delay(3000); sogliaBuilder();
if(soglia == 1){soglia = 0; delay(3000); sogliaBuilder();
if(soglia == 1){soglia = 0; delay(3000); sogliaBuilder();
if(soglia == 1){soglia = 0; delay(3000); sogliaBuilder();
if(soglia == 1){soglia = 0; delay(3000); sogliaBuilder();
}else{engineAvanti();} //se meno di 5 tempi: AVATI
}else{engineRetro();} //se meno di 4 tempi: RETROMARCIA
}else{sxRotate();} //se meno 3 tre tempi: RUOTA SINISTRA
}else{dxRotate();} //se meno di 2 tempi: RUOTA DESTRA
}else{engineStop();} //se meno di 1 tempo: STOP

Serial.println(soglia);
} //end of LOOP

//------------------------------------------------------------------F U N Z I O N I D'A U T O R E--------------------------------------------------------- :wink:

//--------IR reader------------------
int irReader(){
int infrared1 = analogRead(A0);
delay(1);
int infrared2 = analogRead(A0);
delay(1);
int infrared3 = analogRead(A0);
delay(1);
int infrared4 = analogRead(A0);
delay(1);
int infrared5 = analogRead(A0);
delay(1);
int infrared6 = analogRead(A0);
int infraredValue = (infrared1 + infrared2 + infrared3 + infrared4 + infrared5 + infrared6)/6;
return infraredValue;
}
//-------------------------------------

//-----------Creatore di soglie--------
int sogliaBuilder(){
int soglia;
if(irReader() <= 1){
int soglia = 0;
}else{
int soglia = 1;
}
}

int sogliaBuilder(){
  int soglia;
  if(irReader() <= 1){
    int soglia = 0;
    }else{
      int soglia = 1;
           }
}

That is not the same as the code you originally posted.

You are defining three variables named soglia in that code. Two of them are spurious.

gvs_ro:
Move the int before the if

int sogliaBuilder(){

int soglia = 0; // or what value you want
 if(irReader() <= 1){
  soglia = 0;
   }else{
    soglia = 1;
    }
  return soglia;
}



Your code did not know that soglia exist outside the if statement.

It didn't need to know. The function, as written, will work just fine.
soglia was not declared before the if or the else, but it did not need to be. The if/else is dependent on the return from irReader(), which has nothing to do with the local variable soglia. Only one declaration and assignment would be performed, and the value of soglia was returned in the last line of the function.
The call to this function returns a 0 or a 1, and assigns it to soglia (the global variable). Ugly, yes, but it will work.
Granted, declaring soglia before the if/else is better coding, but it will not change the operation of the function.
Better still would be to completely change the name of the local variable, to avoid confusion later, or to have the function just change the global, and not return anything.

oops.. never mind. soglia disappears after the if or else.

A few things... first, global variables are visible all through the code in the file they are declared in. Local variables, declared inside a function, are only visible in that function. Local variables declared inside a block (a block is delimited with { and }, like in an if, else, while, for, etc.), are only visible inside that block.

So, you should either use a different name in your function than the global variable, or use a void function that returns nothing, but modifies the global variable.

The problem with sogliaBuilder() has already been pointed out to you, but I think you might have another problem.

In irReader(), you average 6 analogRead() values, and return that to the global variable infraredValue. This is fine, but you never use it. Instead, you call sogliaBuilder() and do the irReader() all over again, and make a decision based on a returned average value of <=1 or >1. The analogRead() will return a value between 0 and 1023, and you stated in the first post that irReader() returns a value of around 20 or 30. So unless irReader() returns 0 0r 1, soglia will always be 1.

Ok, I solved with another method... However, I'm new in programming, I hope i'll learn fast :wink:
Thanks guys!