Arrays are one of the most useful tools in Arduino programming. An array lets you store multiple values of the same data type under one variable name. Instead of creating separate variables like led1, led2, and led3, you can store them in one array and access them by number.
What Is an Array?
An array is a fixed-size list of values. Each value inside the array is called an element. Every element has an index number, and Arduino arrays start counting at 0, not 1.
int numbers[5] = {10, 20, 30, 40, 50};
This array contains five integers:
numbers[0]is10numbers[1]is20numbers[2]is30numbers[3]is40numbers[4]is50
The last valid index is always one less than the array size. For an array with 5 elements, the valid indexes are 0 through 4.
Declaring an Array
The basic format for creating an array is:
dataType arrayName[arraySize];
Example:
int sensorValues[4];
This creates an array named sensorValues that can hold four integer values. At this point, the values are not manually assigned yet.
Creating an Array with Starting Values
You can assign values when the array is created:
int ledPins[3] = {8, 9, 10};
This creates an array with three values. These values could represent three Arduino pins connected to LEDs.
You can also let the compiler count the number of elements automatically:
int ledPins[] = {8, 9, 10};
In this case, Arduino knows the array has three elements because three values were provided.
Accessing Array Values
You access an array element by using its index number inside square brackets.
int ledPins[] = {8, 9, 10};
void setup() {
pinMode(ledPins[0], OUTPUT); // Pin 8
pinMode(ledPins[1], OUTPUT); // Pin 9
pinMode(ledPins[2], OUTPUT); // Pin 10
}
void loop() {
}
Remember: ledPins[0] is the first item, not ledPins[1].
Changing Array Values
Array values can be changed after they are created.
int readings[3] = {100, 200, 300};
void setup() {
Serial.begin(9600);
readings[1] = 250;
Serial.println(readings[0]); // Prints 100
Serial.println(readings[1]); // Prints 250
Serial.println(readings[2]); // Prints 300
}
void loop() {
}
The value at index 1 was changed from 200 to 250.
Using Arrays with Loops
Arrays are especially useful with for loops. Instead of writing repeated code, you can loop through the array.
int ledPins[] = {8, 9, 10};
void setup() {
for (int i = 0; i < 3; i++) {
pinMode(ledPins[i], OUTPUT);
}
}
void loop() {
for (int i = 0; i < 3; i++) {
digitalWrite(ledPins[i], HIGH);
delay(500);
digitalWrite(ledPins[i], LOW);
}
}
This code turns on each LED one at a time. The loop starts at index 0 and stops before index 3. That means it uses indexes 0, 1, and 2.
Finding the Number of Elements in an Array
Hardcoding the number of elements works, but it can cause problems if you later add or remove items from the array. A better method is to calculate the array size using sizeof().
int ledPins[] = {8, 9, 10, 11};
int numberOfPins = sizeof(ledPins) / sizeof(ledPins[0]);
sizeof(ledPins) gives the total number of bytes used by the array. sizeof(ledPins[0]) gives the number of bytes used by one element. Dividing them gives the number of elements.
Complete example:
int ledPins[] = {8, 9, 10, 11};
int numberOfPins = sizeof(ledPins) / sizeof(ledPins[0]);
void setup() {
for (int i = 0; i < numberOfPins; i++) {
pinMode(ledPins[i], OUTPUT);
}
}
void loop() {
for (int i = 0; i < numberOfPins; i++) {
digitalWrite(ledPins[i], HIGH);
delay(250);
digitalWrite(ledPins[i], LOW);
}
}
Using Arrays for Sensor Readings
Arrays are useful when storing multiple readings from sensors.
const int sensorPin = A0;
int readings[5];
void setup() {
Serial.begin(9600);
}
void loop() {
for (int i = 0; i < 5; i++) {
readings[i] = analogRead(sensorPin);
delay(100);
}
for (int i = 0; i < 5; i++) {
Serial.print("Reading ");
Serial.print(i);
Serial.print(": ");
Serial.println(readings[i]);
}
delay(1000);
}
This code stores five analog readings from pin A0, then prints them to the Serial Monitor.
Calculating an Average with an Array
Arrays can also be used to smooth sensor data by averaging several readings.
const int sensorPin = A0;
int readings[10];
int total = 0;
float average = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
total = 0;
for (int i = 0; i < 10; i++) {
readings[i] = analogRead(sensorPin);
total += readings[i];
delay(20);
}
average = total / 10.0;
Serial.print("Average reading: ");
Serial.println(average);
delay(500);
}
The 10.0 is used instead of 10 so the result can include decimal values.
Using Arrays with Buttons
Arrays can organize multiple input pins, such as buttons.
int buttonPins[] = {2, 3, 4};
int numberOfButtons = sizeof(buttonPins) / sizeof(buttonPins[0]);
void setup() {
Serial.begin(9600);
for (int i = 0; i < numberOfButtons; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
}
void loop() {
for (int i = 0; i < numberOfButtons; i++) {
if (digitalRead(buttonPins[i]) == LOW) {
Serial.print("Button pressed: ");
Serial.println(i);
}
}
}
This example uses INPUT_PULLUP, so the button reads HIGH when not pressed and LOW when pressed.
Character Arrays
A character array stores text as a sequence of characters. In Arduino C/C++, strings written in double quotes automatically include a hidden null terminator character, '\0', at the end.
char message[] = "Hello";
void setup() {
Serial.begin(9600);
Serial.println(message);
}
void loop() {
}
The word Hello uses six characters in memory: H, e, l, l, o, and the null terminator '\0'.
Array of Text Strings
You can create an array of text messages using pointers to constant character arrays:
const char* messages[] = {
"System Ready",
"Sensor Active",
"Error Detected"
};
void setup() {
Serial.begin(9600);
for (int i = 0; i < 3; i++) {
Serial.println(messages[i]);
}
}
void loop() {
}
This is useful for menus, status messages, display text, and serial output.
Two-Dimensional Arrays
A two-dimensional array works like a table with rows and columns.
int grid[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
This array has 2 rows and 3 columns.
void setup() {
Serial.begin(9600);
Serial.println(grid[0][0]); // Prints 1
Serial.println(grid[0][2]); // Prints 3
Serial.println(grid[1][0]); // Prints 4
Serial.println(grid[1][2]); // Prints 6
}
void loop() {
}
Two-dimensional arrays are useful for keypads, LED matrices, lookup tables, and grid-based data.
Example: LED Pattern Table
This example uses a two-dimensional array to store LED patterns.
int ledPins[] = {8, 9, 10};
int patterns[][3] = {
{HIGH, LOW, LOW},
{LOW, HIGH, LOW},
{LOW, LOW, HIGH},
{HIGH, HIGH, HIGH},
{LOW, LOW, LOW}
};
int numberOfLeds = sizeof(ledPins) / sizeof(ledPins[0]);
int numberOfPatterns = sizeof(patterns) / sizeof(patterns[0]);
void setup() {
for (int i = 0; i < numberOfLeds; i++) {
pinMode(ledPins[i], OUTPUT);
}
}
void loop() {
for (int row = 0; row < numberOfPatterns; row++) {
for (int col = 0; col < numberOfLeds; col++) {
digitalWrite(ledPins[col], patterns[row][col]);
}
delay(500);
}
}
Each row in patterns represents one LED state pattern. Each column represents one LED.
Passing Arrays to Functions
Arrays can be passed to functions. When doing this, pass the array and its size. The function usually cannot determine the full array length by itself after the array is passed in.
int ledPins[] = {8, 9, 10};
int numberOfPins = sizeof(ledPins) / sizeof(ledPins[0]);
void setup() {
setupPins(ledPins, numberOfPins);
}
void loop() {
blinkPins(ledPins, numberOfPins);
}
void setupPins(int pins[], int count) {
for (int i = 0; i < count; i++) {
pinMode(pins[i], OUTPUT);
}
}
void blinkPins(int pins[], int count) {
for (int i = 0; i < count; i++) {
digitalWrite(pins[i], HIGH);
delay(250);
digitalWrite(pins[i], LOW);
}
}
Passing the array size prevents the function from reading past the end of the array.
Important Warning: Stay Inside Array Bounds
Arduino does not automatically stop you from reading or writing outside the valid indexes of an array. This can cause incorrect values, unstable behavior, memory corruption, or crashes.
Incorrect example:
int values[3] = {10, 20, 30};
void setup() {
Serial.begin(9600);
Serial.println(values[3]); // Wrong: valid indexes are 0, 1, and 2
}
void loop() {
}
The array has three elements, but values[3] tries to access a fourth element. The valid indexes are values[0], values[1], and values[2].
Using const with Arrays
If an array should not change while the program runs, use const. This helps protect the values from accidental changes.
const int ledPins[] = {8, 9, 10};
This is useful for pin numbers, fixed lookup tables, and fixed configuration values.
Using byte to Save Memory
On small Arduino boards, memory is limited. If your numbers only need to store values from 0 to 255, you can use byte instead of int.
const byte ledPins[] = {8, 9, 10};
This saves RAM compared to using int on many Arduino boards.
Common Arduino Array Uses
- Storing multiple LED pins
- Reading multiple buttons
- Saving sensor readings
- Creating menu text
- Building LED patterns
- Working with keypads
- Creating lookup tables
- Controlling groups of relays, motors, or outputs
Complete Example: Multiple LEDs and Buttons
This example uses two arrays: one for button pins and one for LED pins. Pressing a button turns on the matching LED.
const byte buttonPins[] = {2, 3, 4};
const byte ledPins[] = {8, 9, 10};
const byte numberOfItems = sizeof(ledPins) / sizeof(ledPins[0]);
void setup() {
for (byte i = 0; i < numberOfItems; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
pinMode(ledPins[i], OUTPUT);
}
}
void loop() {
for (byte i = 0; i < numberOfItems; i++) {
if (digitalRead(buttonPins[i]) == LOW) {
digitalWrite(ledPins[i], HIGH);
} else {
digitalWrite(ledPins[i], LOW);
}
}
}
The first button controls the first LED, the second button controls the second LED, and the third button controls the third LED.
Best Practices
- Start counting array indexes at
0. - Never access an index outside the array size.
- Use
sizeof(array) / sizeof(array[0])to calculate the number of elements when possible. - Pass the array size when sending an array to a function.
- Use
constfor arrays that should not change. - Use
byteinstead ofintfor small pin-number arrays when appropriate. - Use arrays with loops to avoid repeated code.
Final Summary
Arrays make Arduino programs cleaner, shorter, and easier to expand. They are especially useful when working with repeated hardware such as LEDs, buttons, sensors, relays, and display messages. The most important rule is to remember that arrays start at index 0 and must not be accessed outside their valid range.