Functions and Variables

I am struggling with writing my own functions and I am getting various different compile errors. I think the problem is I don’t fully understand the scope of variables outside and within the function.

So the first question I have is about arguments/pass parameters. Can I define them outside the function definition? For example:

int mode = 0;
int type = 0;

void functioname (mode, type) {

etc etc.

or do I have to do this

void functioname (int mode, int type) ?

My second question is can I define the function anywhere within the program? Can it be before or after Loop() ? Does it need to be within setup() ?

You have to use type specifiers in the function definition.

can I define the function anywhere within the program?

The Arduino IDE gets up to some jiggery pokery and sometimes gets caught out but in general the function definition can be anywhere outside of a function.

Does it need to be within setup() ?

Most specifically not within any function.

If you define a variable outside of a function it is a global variable and will be visible everywhere in your program so there is no need to pass it as a parameter.

If you define a variable inside a function it will only be visible within that function. If you want a local variable to retain its value between calls to the function you can prefix it with static - for example

void myFunction() {
   static byte myVariable;
  
}

If you define a function that receives parameters you must define their types in the function definition - for example

void functioname (int mode, int type)

You should avoid using the same name for global variables and local variables unless you like really late nights debugging.

...R

Robin2:
If you define a variable outside of a function it is a global variable and will be visible everywhere in your program so there is no need to pass it as a parameter.

Thank you, but in that case its not obvious to me why there is any need to bother with pass parameters. Just use global variables.

This Arduino site page may help you with that.

Thank you, but in that case its not obvious to me why there is any need to bother with pass parameters. Just use global variables.

That's just fine with small code but in larger code it's a PITA.

yendis:
Thank you, but in that case its not obvious to me why there is any need to bother with pass parameters. Just use global variables.

But the idea of a lot of functions is to make them multi functional. It’s a bit weird if you make two functions like:

void blink1(){
  digitalWrite(1, HIGH);
  delay(500);
  digitalWrite(1, LOW);
}
void blink2(){
  digitalWrite(2, HIGH);
  delay(500);
  digitalWrite(2, LOW);
}
[code]
And think of all the work if you want to expand it for 3, 5, 500 pins!

While I can just make a universal function like:
[code]
void blink(int pin, int time){
  digitalWrite(pin, HIGH);
  delay(time);
  digitalWrite(pin, LOW);
}

Just one function which I can use for every pin and every time!

yendis:
Thank you, but in that case its not obvious to me why there is any need to bother with pass parameters. Just use global variables.

That is a perfectly practical solution.

In a larger program it can be useful to use local variables and parameters to make the code easier to understand and to debug.

And a function that is self contained and takes parameters can be used easily in any other program.

…R

Robin2:
If you define a variable outside of a function it is a global variable and will be visible everywhere in your program so there is no need to pass it as a parameter.

well… you may find a need to pass a global variable to a function, from time to time.

Serial.println(myGlobalSomething);

You can't have generality with global variables alone. For example, this function increments a global variable:

int something;
void incrementSomething()
{
  something++;
}
//...
incrementSomething();

Kind of useless if you have to increment variable "somethingElse".
When you pass a parameter, the function can be used with any appropriate variable:

int something;
int somethingElse;
int increment(int val)
{
  return val++;
}
//...
foo = increment(something);
bar = increment(somethingElse);
/...

It's about code re-use, factoring and modularity.

aarg:
When you pass a parameter, the function can be used with any appropriate variable:

100% agree. Anonymous variables manipulated inside a function kind of scare me. Passing the variable, even if it is global (i.e. pass by reference) says a lot more about what's likely to get mucked with (and I find more readable/understandable later on down the road).

Also, using returns versus just manipulating a global variable is easier (for me, later on) to understand what's what in a function.

The function prototype provides a lot of clues about what's to come.

I am still having problems.

void aud ()

Too many arguments? But I didnt list any arguments!

So I put in the (global) variables I used in the function

void aud (mode, on)

Then I got an error aud declared void!

I am not getting the hang of this am I :o

I am still having problems

So are we.

You didn't post your code or the actual error messages you're seeing.

First of all, don’t use global variables for everything. You don’t want a function to modify a variable by accident because you made a coding mistake. Personally I try to avoid them as much as possible.

Pick one of the two :wink:

int x = 1, y = 2;
void aud()
{
  Serial.Println(x * y);
}

void loop()
{
  aud();
}
[code]

or

[code]
void aud(int a, int b)
{
  Serial.Println(a * b);
}

void loop()
{
  int x = 1, y =2;
  aud(x, y);
}
[code]