Methods for passing variables between functions

I've heard that global variables are generally frowned upon since they take up memory, and that instead you should look into methods of passing variables between functions. The only way I know to do it is to use the variable as an input to the function, as in "myFunction(variable to pass)".

But I feel like this wouldn't be good programming practices for something like passing from setup() to loop(). Are there any other methods for passing variables?

If you want something to be initialized in setup and used in loop, it may as well be global. If you're using it all the time in loop, it has to live somewhere and as you can see there's no mechanism to pass anything between those two functions.

The more serious issue with globals isn't that they take up memory, it's that every routine in your program can access them which makes it harder to debug.

of course setup() and loop() are defined as (void)()(void) and have no arguments.

global variables used within the scope of a file that isn't very long and has a well defined purpose are acceptable. it is frowned upon to accesses global variables between files (i.e. extern).

putting a group of functions acting on the same data in a separate file is good practice. the data can be global in that file (similar to private data in a class). defining the data as static prevents if from being accessed outside the file.

any values passed into that code is thru function arguments, arguments that are pointers for placing results or return values from functions. pointer arguments are often used if the return value is used to indicate an error

if your interested is in a good example, see chapter 8 of The Unix Programming Environment

The "correct" way to deal with variable scope is to make the scope of each variable as narrow as possible - so each variable can ONLY be changed by the functions that have a valid reason to change it. If a variable is only needed within a for loop, it should be declared within the scope of that for loop. If it is only needed within a function, it should be declared within that function. Use of global variables should, to the extent possible, be minimized. Many c/c++ rules about "file" scope go out the window in Arduino-land, due to the munging the Arduino build system does on files, as files will often be combined into a single, larger file during the build process. So, if you expect to manage things at file scope, you better understand when that will actually work, and when it won't.

Regards,
Ray L.

RayLivingston:
So, if you expect to manage things at file scope, you better understand when that will actually work, and when it won't.

My recommendation for handling that (FWIW) is in Reply #3 of this Thread.

Are there any other methods for passing variables?

this seems to be a very simple question, but it will get quite complex.

Basically there are two options

  • function call by value
  • function call by reference

The first one is what you know currently, you pass a value into a local variable to the function.
You will have a copy of your value during the existance of the function.
it will ocupy additional RAM from the stack.

In the second option you pass a reference to the existing variable. The value will not be duplicated - you just hand over a "reference" to your variable (it will ocupy some memory, because the controller needs some kind of adressing to find your referenced variable, but it will not be a 1:1 copy).

I'm not a native speaker and I guess you can easily google for the differences of the two options and you will get an even better explanation for them.

When you are dealing about "global" or local try to keep your variables as narrow scoped as possible like already proposed.
If you need a variable only in loop, declare it in the loop.
If you need it within an if, declare it under the if.
Be carefull if you need variables in a switch/case case. It's pain in the a.. and I prefer to declare it outside of the switch.

Lot of global variables in Arduino beginner project don't need to be globally.
E.g. if you need a variable only within a function you can declare it in the function.
Local variables will be destroyed when the function ends.
If you want to keep value of the variable alive AFTER the function has ended for the next function call use the keyword static. E.g. an "uint32_t previousMillis" could be a static variable within a function if it is only needed for timekeeping in that function.

Declaring a variable globally, static or locally has a big impact on your memory usage and the remaining free memory. As you are using microcontrollers with a very limited amount of free memory, always care about the least possible static data usage.

If you want to get some first insights how an ATmega handles variables and how they effect RAM usage, read this beginner friendly
article Optimizing SRAM | Memories of an Arduino | Adafruit Learning System.
If this was not enough, try this article, but concentrate on the Arduino parts Memory and the Arduino | Electronics | Sumida Crossing