Introduction
Arduino is an open-source electronics platform based on easy-to-use hardware and software. Arduino boards can read inputs (light sensors, buttons, etc.) and convert them into outputs (activating motors, turning on LEDs, etc.). You control the board by sending instructions to the microcontroller using the Arduino programming language (based on C/C++) and the Arduino IDE. This cheat sheet provides a comprehensive reference for Arduino programming, from basic syntax to advanced techniques.
Arduino Program Structure
Every Arduino sketch (program) consists of two essential functions:
void setup() {
// Runs once at startup
// Initialize pins, serial communication, etc.
}
void loop() {
// Runs continuously after setup()
// Main program code goes here
}
Core Language Elements
Variables and Data Types
Data Type | Size (bytes) | Range | Usage |
---|---|---|---|
boolean | 1 | true /false | Logic operations |
byte | 1 | 0 to 255 | Unsigned 8-bit value |
char | 1 | -128 to 127 | Signed character/small number |
unsigned char | 1 | 0 to 255 | Unsigned character |
int | 2 | -32,768 to 32,767 | Primary integer type |
unsigned int | 2 | 0 to 65,535 | Unsigned integer |
long | 4 | -2,147,483,648 to 2,147,483,647 | Extended-size integer |
unsigned long | 4 | 0 to 4,294,967,295 | For large positive numbers (millis) |
float | 4 | -3.4028235E+38 to 3.4028235E+38 | Floating-point numbers |
double | 4 | Same as float on Arduino | Floating-point (same as float) |
String | Variable | Limited by available memory | Text strings (use with caution) |
Variable Declaration Examples
// Variable declarations
int sensorValue = 0;
float temperature;
boolean buttonPressed = false;
char myChar = 'A';
byte myByte = 255;
unsigned long previousMillis = 0;
// Constants
const int ledPin = 13;
#define BUTTON_PIN 2 // Preprocessor constant (no memory used)
// Arrays
int sensorReadings[5] = {0, 0, 0, 0, 0};
char message[10] = "Arduino";
Operators
Category | Operators | Description |
---|---|---|
Arithmetic | + , - , * , / , % | Addition, subtraction, multiplication, division, modulo |
Comparison | == , != , < , > , <= , >= | Equal, not equal, less than, greater than, less than or equal, greater than or equal |
Boolean | && , || , ! | AND, OR, NOT |
Bitwise | & , | , ^ , ~ , << , >> | AND, OR, XOR, NOT, left shift, right shift |
Compound | += , -= , *= , /= , %= , &= , |= | Shorthand operations |
Increment/Decrement | ++ , -- | Add one, subtract one |
Control Structures
Conditional Statements
// If-else statement
if (sensorValue > threshold) {
// Do something when condition is true
} else {
// Do something when condition is false
}
// If-else if-else statement
if (sensorValue > highThreshold) {
// Do something for high values
} else if (sensorValue > lowThreshold) {
// Do something for medium values
} else {
// Do something for low values
}
// Switch case
switch (sensorValue) {
case 0:
// Code for case 0
break;
case 1:
// Code for case 1
break;
default:
// Default code
break;
}
// Ternary operator (shorthand if-else)
result = (condition) ? trueValue : falseValue;
Loops
// For loop
for (int i = 0; i < 10; i++) {
// Do something 10 times
}
// While loop
while (condition) {
// Do something while condition is true
}
// Do-while loop
do {
// Do something at least once
} while (condition);
// Break and continue
for (int i = 0; i < 10; i++) {
if (i == 5) continue; // Skip iteration when i is 5
if (i == 8) break; // Exit loop when i is 8
}
Arduino-Specific Functions
Digital I/O
// Pin modes
pinMode(pin, mode); // mode: INPUT, OUTPUT, or INPUT_PULLUP
// Digital I/O
digitalWrite(pin, value); // value: HIGH or LOW
int value = digitalRead(pin); // Returns HIGH or LOW
Analog I/O
// Analog input
int value = analogRead(pin); // Returns 0-1023 (10-bit resolution)
// Analog output (PWM)
analogWrite(pin, value); // value: 0-255 (8-bit resolution)
// Reference voltage
analogReference(type); // type: DEFAULT, INTERNAL, EXTERNAL
Time Functions
delay(ms); // Pause program for ms milliseconds (blocks code execution)
delayMicroseconds(us); // Pause program for us microseconds (blocks code execution)
unsigned long time = millis(); // Returns milliseconds since program started
unsigned long time = micros(); // Returns microseconds since program started
Serial Communication
// Initialize serial
Serial.begin(baudRate); // Common rates: 9600, 115200
// Sending data
Serial.print(data); // Send data as text
Serial.println(data); // Send data as text with newline
Serial.write(byteData); // Send raw bytes
// Receiving data
if (Serial.available() > 0) { // Check if data is available
int incomingByte = Serial.read(); // Read a single byte
String incomingString = Serial.readString(); // Read a whole string
}
// Other serial functions
Serial.available(); // Returns number of bytes available
Serial.flush(); // Wait for transmission to complete
Serial.peek(); // Read a byte without removing from buffer
Advanced I/O
// Interrupts
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); // mode: CHANGE, RISING, FALLING, LOW, HIGH
detachInterrupt(digitalPinToInterrupt(pin));
interrupts(); // Enable interrupts
noInterrupts(); // Disable interrupts
// Tone generation
tone(pin, frequency); // Generate tone on pin
tone(pin, frequency, duration); // Generate tone for duration milliseconds
noTone(pin); // Stop tone on pin
// Shift register functions
shiftIn(dataPin, clockPin, bitOrder); // bitOrder: MSBFIRST or LSBFIRST
shiftOut(dataPin, clockPin, bitOrder, value);
// Direct port manipulation (faster than digitalWrite)
PORTB |= B00100000; // Set pin 13 HIGH (Arduino Uno)
PORTB &= B11011111; // Set pin 13 LOW (Arduino Uno)
Common Arduino Libraries
Servo Library
#include <Servo.h>
Servo myServo; // Create servo object
void setup() {
myServo.attach(9); // Attach servo to pin 9
}
void loop() {
myServo.write(angle); // angle: 0-180
int pos = myServo.read(); // Read current angle
myServo.writeMicroseconds(us); // us: typically 1000-2000
}
Wire Library (I2C)
#include <Wire.h>
// As master
void setup() {
Wire.begin(); // Initialize as master
}
void loop() {
Wire.beginTransmission(address);
Wire.write(byte); // Send single byte
Wire.write(buffer, length); // Send buffer
Wire.endTransmission();
Wire.requestFrom(address, quantity);
if (Wire.available()) {
byte data = Wire.read();
}
}
// As slave
void setup() {
Wire.begin(address); // Initialize as slave with address
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
}
void receiveEvent(int howMany) {
// Handle received data
while (Wire.available()) {
byte data = Wire.read();
}
}
void requestEvent() {
// Send data when requested
Wire.write(data);
}
SPI Library
#include <SPI.h>
void setup() {
SPI.begin();
pinMode(SS, OUTPUT); // Set slave select pin as output
digitalWrite(SS, HIGH); // Ensure slave is not selected
}
void loop() {
SPI.beginTransaction(SPISettings(speed, dataOrder, dataMode));
digitalWrite(SS, LOW); // Select slave
byte result = SPI.transfer(data); // Send and receive
SPI.transfer(buffer, size); // Transfer buffer
digitalWrite(SS, HIGH); // Deselect slave
SPI.endTransaction();
}
EEPROM Library
#include <EEPROM.h>
// Read/write single byte
byte value = EEPROM.read(address);
EEPROM.write(address, value);
EEPROM.update(address, value); // Write only if different (reduces wear)
// Read/write other data types
int intValue;
EEPROM.get(address, intValue);
EEPROM.put(address, intValue); // Works with any data type including structs
LiquidCrystal Library (LCD)
#include <LiquidCrystal.h>
// Initialize with pins (RS, E, D4, D5, D6, D7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
lcd.begin(16, 2); // Initialize 16x2 LCD
lcd.clear(); // Clear display
lcd.home(); // Move cursor to home position
}
void loop() {
lcd.setCursor(column, row); // Set cursor position
lcd.print("Text"); // Print text
lcd.cursor(); // Show cursor
lcd.noCursor(); // Hide cursor
lcd.blink(); // Blink cursor
lcd.noBlink(); // Stop cursor blinking
lcd.display(); // Turn on display
lcd.noDisplay(); // Turn off display
lcd.scrollDisplayLeft(); // Scroll display left
lcd.scrollDisplayRight(); // Scroll display right
lcd.autoscroll(); // Enable autoscroll
lcd.noAutoscroll(); // Disable autoscroll
}
Memory Management
RAM Usage
// Reduce RAM usage with F() macro for constant strings
Serial.println("Regular string uses RAM");
Serial.println(F("This string uses only flash memory"));
// Use const for constant variables
const int ledPin = 13; // Compiler optimized
// Use static for variables that persist between function calls
void myFunction() {
static int counter = 0; // Value persists between calls
counter++;
}
// Use PROGMEM for large constant data
#include <avr/pgmspace.h>
const PROGMEM uint16_t lookupTable[] = { 0, 2, 4, 6, 8 };
uint16_t value = pgm_read_word_near(lookupTable + index);
Memory Functions
// Available memory functions
#include <MemoryFree.h> // External library
int freeMem = freeMemory(); // Get free RAM
void* malloc(size_t size); // Allocate memory dynamically
free(pointer); // Free allocated memory
// Print free memory (simple method)
Serial.print(F("Free memory: "));
Serial.println(freeRam());
int freeRam() {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
Debugging Techniques
Serial Debugging
// Debug print
Serial.print(F("Debug: "));
Serial.println(variable);
// Print free memory periodically
unsigned long lastDebugTime = 0;
if (millis() - lastDebugTime >= 5000) { // Every 5 seconds
lastDebugTime = millis();
Serial.print(F("Free RAM: "));
Serial.println(freeRam());
}
// Trace execution
Serial.println(F("Entering function"));
// Function code
Serial.println(F("Exiting function"));
Timing Functions
// Measure execution time
unsigned long startTime = micros();
// Code to measure
unsigned long elapsedTime = micros() - startTime;
Serial.print(F("Execution time: "));
Serial.println(elapsedTime);
LED Debugging
// Heartbeat LED to show program is running
void loop() {
static unsigned long lastBlink = 0;
if (millis() - lastBlink >= 1000) {
lastBlink = millis();
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
// Main program code
}
// Error codes with blink patterns
void errorBlink(int errorCode) {
for (int i = 0; i < errorCode; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(200);
digitalWrite(LED_BUILTIN, LOW);
delay(200);
}
delay(1000); // Pause between repetitions
}
Best Practices & Optimization
Code Structure
// Use functions to organize code
void setup() {
initializePins();
setupSensors();
beginCommunication();
}
// Use descriptive function and variable names
void readTemperatureSensor() {
int rawTemperature = analogRead(temperaturePin);
float celsius = convertRawToTemperature(rawTemperature);
// Process temperature...
}
// Avoid global variables when possible
void processReading(int sensorValue) {
// Local variables are only in scope when needed
int mappedValue = map(sensorValue, 0, 1023, 0, 255);
// Process value...
}
Non-Blocking Code
// Non-blocking delay using millis()
unsigned long previousMillis = 0;
const long interval = 1000; // Interval in milliseconds
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// Code to execute periodically
}
// Other code runs without being blocked
}
// Multiple timed tasks
unsigned long task1Millis = 0;
unsigned long task2Millis = 0;
const long task1Interval = 1000;
const long task2Interval = 5000;
void loop() {
unsigned long currentMillis = millis();
// Task 1 (every 1 second)
if (currentMillis - task1Millis >= task1Interval) {
task1Millis = currentMillis;
// Task 1 code
}
// Task 2 (every 5 seconds)
if (currentMillis - task2Millis >= task2Interval) {
task2Millis = currentMillis;
// Task 2 code
}
}
State Machines
// Simple state machine
enum State {
STATE_IDLE,
STATE_RUNNING,
STATE_ERROR
};
State currentState = STATE_IDLE;
unsigned long stateTimer = 0;
void loop() {
switch (currentState) {
case STATE_IDLE:
// Idle state code
if (condition) {
currentState = STATE_RUNNING;
stateTimer = millis(); // Reset timer on state change
}
break;
case STATE_RUNNING:
// Running state code
if (errorCondition) {
currentState = STATE_ERROR;
} else if (millis() - stateTimer >= 10000) { // After 10 seconds
currentState = STATE_IDLE;
}
break;
case STATE_ERROR:
// Error state code
if (resetCondition) {
currentState = STATE_IDLE;
}
break;
}
}
Power Management
// Reduce power using sleep modes
#include <avr/sleep.h>
#include <avr/power.h>
void setup() {
// Setup pins and other configurations
}
void loop() {
// Do necessary work
// Enter sleep mode
goToSleep();
}
void goToSleep() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Maximum power saving
sleep_enable();
// Disable unused peripherals
power_adc_disable();
power_spi_disable();
power_twi_disable();
power_timer0_disable();
power_timer1_disable();
power_timer2_disable();
// Enter sleep mode
sleep_mode();
// Code resumes here on wake (after interrupt)
sleep_disable();
// Re-enable peripherals
power_all_enable();
}
// Wake on external interrupt
void setupWakeupInterrupt() {
attachInterrupt(digitalPinToInterrupt(2), wakeupISR, LOW);
}
void wakeupISR() {
// Keep empty - just used to wake the Arduino
}
Arduino Board-Specific Information
Common Arduino Boards
Board | Microcontroller | Digital I/O | Analog In | PWM | UART | I2C | SPI | LED | Flash | SRAM | EEPROM |
---|---|---|---|---|---|---|---|---|---|---|---|
Uno | ATmega328P | 14 | 6 | 6 | 1 | 1 | 1 | 13 | 32KB | 2KB | 1KB |
Mega 2560 | ATmega2560 | 54 | 16 | 15 | 4 | 1 | 1 | 13 | 256KB | 8KB | 4KB |
Nano | ATmega328P | 14 | 8 | 6 | 1 | 1 | 1 | 13 | 32KB | 2KB | 1KB |
Leonardo | ATmega32U4 | 20 | 12 | 7 | 1 | 1 | 1 | 13 | 32KB | 2.5KB | 1KB |
Pro Mini | ATmega328P | 14 | 6 | 6 | 1 | 1 | 1 | 13 | 32KB | 2KB | 1KB |
ESP32 | ESP32 | 36+ | 18 | 16 | 3 | 2 | 4 | 2 | 4MB | 520KB | – |
ESP8266 | ESP8266 | 17 | 1 | 8 | 2 | 1 | 1 | 1 | 4MB | 80KB | – |
Arduino Uno Pin Map
+-----+
+---------| |---------+
| | | |
| TX-|1 0|----RX |
| RX-|2 1|----TX |
| RESET-|3 | |
| GND-|4 | |
Digital 2| D2-|5 2|----D2 |Digital 2, INT0
Digital 3| D3-|6 3|----D3 |Digital 3, INT1, PWM
Digital 4| D4-|7 4|----D4 |Digital 4
Digital 5| D5-|8 5|----D5 |Digital 5, PWM
Digital 6| D6-|9 6|----D6 |Digital 6, PWM
Digital 7| D7-|10 7|----D7 |Digital 7
Digital 8| D8-|11 8|----D8 |Digital 8
Digital 9| D9-|12 9|----D9 |Digital 9, PWM
Digital 10| D10-|13 10|----D10 |Digital 10, PWM, SS
Digital 11| D11-|14 11|----D11 |Digital 11, PWM, MOSI
Digital 12| D12-|15 12|----D12 |Digital 12, MISO
Digital 13| D13-|16 13|----D13 |Digital 13, SCK, LED
| 3V3-|17 14|----AREF |
| 5V-|18 15|----SDA |Analog 4, SDA
| GND-|19 16|----SCL |Analog 5, SCL
| GND-|20 17|----A0 |Analog 0
| VIN-|21 18|----A1 |Analog 1
| |19 |----A2 |Analog 2
| |20 |----A3 |Analog 3
| |21 |----A4 |Analog 4, SDA
| |22 |----A5 |Analog 5, SCL
| | | |
+---------+ +---------+
Resources for Further Learning
Official Documentation
- Arduino Reference – Complete language reference
- Arduino Playground – Community-contributed examples and tutorials
Books
- “Arduino Cookbook” by Michael Margolis
- “Programming Arduino: Getting Started with Sketches” by Simon Monk
- “Arduino Workshop” by John Boxall
- “Exploring Arduino” by Jeremy Blum
Online Courses
- Arduino’s Official Getting Started Guide
- Adafruit’s Arduino Tutorials
- Sparkfun’s Arduino Tutorials
- Udemy and Coursera Arduino courses
Component Libraries
- Arduino Libraries – Official Arduino libraries
- Adafruit Arduino Libraries – Libraries for Adafruit products
- SparkFun Arduino Libraries – Libraries for SparkFun products
Project Inspiration
- Arduino Project Hub – Official Arduino project repository
- Instructables Arduino Projects – DIY Arduino projects
- Hackster.io Arduino Projects – Community Arduino projects
Remember: The best way to learn Arduino is through hands-on practice. Start with simple projects and gradually increase complexity as you become more comfortable with the platform.