Arduino - Variables & Constants
Arduino - Variables and Constants
Section titled “Arduino - Variables and Constants”A variable is a named storage location that our program can manipulate. In Arduino (and C++), each variable has a specific type, which determines the size and layout of the variable’s memory, the range of values that can be stored, and the set of operations that can be applied to it.
Common Arduino Data Types
Section titled “Common Arduino Data Types”Choosing the right data type is crucial for writing efficient and bug-free code. Using a type that’s too small will cause errors, while using one that’s too large wastes precious memory.
| Type | Size (on Uno/AVR) | Range | Typical Use |
|---|---|---|---|
bool | 1 byte | true or false | Storing state (e.g., button pressed, LED on) |
byte | 1 byte | 0 to 255 | Working with raw byte data, PWM values |
int | 2 bytes | -32,768 to 32,767 | General purpose integer math, loop counters |
unsigned int | 2 bytes | 0 to 65,535 | When negative numbers are not needed |
long | 4 bytes | -2,147,483,648 to 2,147,483,647 | Large integer values |
unsigned long | 4 bytes | 0 to 4,294,967,295 | Storing the value from millis() |
float | 4 bytes | -3.4028235E+38 to 3.4028235E+38 | Numbers with a decimal point (6-7 digits precision) |
char | 1 byte | -128 to 127 | Storing a single character (e.g., ‘A’) |
Note: The size of int and long can vary on different Arduino boards. On 32-bit boards like the ESP32 or Arduino Due, an int is typically 4 bytes. Always check the documentation for your specific board.
Variable Scope
Section titled “Variable Scope”A variable’s scope defines where in the program it can be accessed. Understanding scope is key to organizing your code and avoiding bugs.
Local Variables
Section titled “Local Variables”Local variables are declared inside a function (like setup() or loop()) or a code block (like a for loop). They are only accessible within that function or block. They are created when the function is called and destroyed when it exits. This is the preferred scope for most variables.
Global Variables
Section titled “Global Variables”Global variables are declared outside of any function, usually at the top of the sketch. They can be accessed and modified from any function in your program. While useful, they should be used sparingly, as they can make your code harder to debug (a bug in one function could unexpectedly change a global variable used by another).
Static Variables
Section titled “Static Variables”A static variable is a special type of local variable. It is only accessible within its function, but its value is preserved between function calls. It’s a great way to maintain state inside a function without using a global variable.
Scope Example Sketch
Section titled “Scope Example Sketch”// --- Global Variable ---// Accessible from anywhere in this file.int globalCounter = 0;
void setup() { Serial.begin(9600);}
void loop() { // --- Local Variable --- // 'loopMessage' is created and destroyed on each run of loop(). String loopMessage = "Inside loop()."; Serial.println(loopMessage);
// We can access and modify the global variable here. globalCounter++; Serial.print("Global counter is now: "); Serial.println(globalCounter);
// Call our custom function myFunction();
delay(1000); Serial.println("----------");}
void myFunction() { // This function CANNOT access 'loopMessage' from loop(). // Trying to do so would cause a compile error. // Serial.println(loopMessage); // <-- THIS WOULD NOT COMPILE
// --- Static Local Variable --- // 'staticCounter' is initialized only ONCE (the first time this function runs). // Its value is remembered across calls to myFunction(). static int staticCounter = 0; staticCounter++;
Serial.print("myFunction() has been called "); Serial.print(staticCounter); Serial.println(" times.");}Defining Constants
Section titled “Defining Constants”A constant is a variable whose value cannot be changed after it is defined. Using constants for pin numbers, sensor thresholds, or configuration settings makes your code much more readable and easier to maintain.
The ‘const’ Keyword (Best Practice)
Section titled “The ‘const’ Keyword (Best Practice)”The modern, preferred way to create a constant is with the const keyword. It tells the compiler the variable is read-only and allows it to perform optimizations.
const int ledPin = 13;const float pi = 3.14159;const long baudRate = 9600;
void setup() { // Now use the constant instead of a "magic number" pinMode(ledPin, OUTPUT); Serial.begin(baudRate);}
void loop() { // ledPin = 12; // This would cause a compile error, which is good!}The ‘#define’ Preprocessor Directive (Legacy)
Section titled “The ‘#define’ Preprocessor Directive (Legacy)”You may see older code use #define to create constants. This is a preprocessor directive that performs a simple text-replacement before the code is compiled. While it works, const is generally safer because it is type-aware and respects scope.
// Legacy method#define LED_PIN 13