Question:
In several code examples for Arduino I notice that there is almost no use of variables in local scope. One of the examples present in the IDE: Analog > AnalogInput
:
int sensorPin = A0;
int ledPin = 13;
int sensorValue = 0;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
sensorValue = analogRead(sensorPin);
digitalWrite(ledPin, HIGH);
delay(sensorValue);
digitalWrite(ledPin, LOW);
delay(sensorValue);
}
The sensorValue
variable is global, while its use is only inside the loop
function. Another case is the Moving-Average-Filter library. A part of the code:
#define MAX_DATA_POINTS 20
class MovingAverageFilter {
public:
MovingAverageFilter(unsigned int newDataPointsCount);
float process(float in);
private:
float values[MAX_DATA_POINTS];
int k;
int dataPointsCount;
float out;
int i;
};
Here the members out
and i
are used only in process
, they must be local:
float MovingAverageFilter::process(float in) {
out = 0;
values[k] = in;
k = (k+1) % dataPointsCount;
for (i=0; i<dataPointsCount; i++) {
out += values[i];
}
return out/dataPointsCount;
}
Using variables in this way seems absurd to me. Is this on purpose? If yes, what is the reason?
The only possibility I can imagine is that the address of local variables would be known at compile time, so they can be accessed regardless of the stack register. Does it really make a difference?
But in the case of the class, I can't see how it could be faster to read an object through the this
pointer than to read it from the stack, relative to the registered one.
Another explanation might be to avoid having to allocate a stack frame to the function. But this allocation should be as simple as incrementing a register, I don't understand why it should be avoided. Also functions that take arguments will have a stack frame anyway.
Answer:
I researched it and didn't find any good answers about it. The reasons I was able to raise are the following:
-
Programs written for Arduino are generally quite simple and there is little memory available. As a result, few people care much about modularization and encapsulation in Arduino programs.
-
Arduino doesn't use a single
main()
method to execute the program. Instead, it uses two independentsetup()
andloop()
methods. The result of this is that in order for you to use within aloop()
what was defined insetup()
, you end up being forced to use global variables. -
Often the variables used in the
loop()
method must be remembered between one iteration and another. This makes you end up being forced to use global variables. -
Arduino is too simple and limited for you to use events, callbacks and messaging effectively.
-
Most of the examples are written for beginners who know little about C, so everything is a little too simplified. Furthermore, most Arduino users do not have much interest, practice or training in software programming, as their focus is on hardware.
Helpful but inconclusive discussions can be found here and here .
In conclusion: I recommend following good traditional programming practices. Constants can be easily optimized by the compiler, so you can declare them in global scope without problems (the problem with global variables is when the value changes, which constants don't). Anything that might change in value is better off in a local scope, unless you don't have a choice. If you are going to use global scope, remember the static
modifier to make the variable private and make getters
and setters
functions available if you need to export it.