Arduino Beginner
Physical computing framework — bare-metal C/C++ flavor, microchip architecture, register controls, and real-world hardware interfacing.
Table of Contents
Sketch Structure (Setup vs Loop)
An Arduino program is called a *sketch*. Instead of a standard C main() entry point, it requires exactly two main wrapper structures that dictate initialization and sequential infinite cycling.
// Runs exactly once when the microcontoller powers on or resets void setup() { // Setup system parameters, configure pin layouts, or init serial lines } // Runs continuously in an infinite sequential loop right after setup() finishes void loop() { // Read sensor data, evaluate states, drive outputs indefinitely }
Data Types & Pin Architecture
Since microcontrollers like the ATmega328P have highly constrained SRAM (often just 2KB), memory optimization is vital. Choosing the right primitive data type prevents overflows.
Digital Output & Input Pins
Digital pins operate strictly on binary states: HIGH (5V or 3.3V) or LOW (0V). You must initialize their mode before interacting with them.
const int ledPin = 13; // External LED indicator pin const int buttonPin = 2; // Button switch pin input void setup() { pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); // Enables internal resistor to avoid floating states } void loop() { int buttonState = digitalRead(buttonPin); if (buttonState == LOW) { // Active-low syntax when using INPUT_PULLUP digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } }
Analog Reading & PWM Control
Analog inputs translate voltages (0V-5V) into a 10-bit integer range (0 to 1023). Analog outputs emulate variable voltages using Pulse Width Modulation (PWM) with an 8-bit scale (0 to 255).
const int potPin = A0; // Potentiometer input line const int pwmPin = 9; // PWM capable pin descriptor (marked with ~) void loop() { int rawInput = analogRead(potPin); // Returns a value between 0 and 1023 // Remap the 10-bit resolution down to an 8-bit PWM scale int brightness = map(rawInput, 0, 1023, 0, 255); analogWrite(pwmPin, brightness); // Modulates pulse width frequency }
Serial Monitor Communication
The Serial peripheral manages UART communication streams, enabling telemetry data transmission back to a host computer or connected module grids.
void setup() { Serial.begin(9600); // Establishes a connection channel at 9600 baud rate Serial.println("Telemetry console online..."); } void loop() { if (Serial.available() > 0) { char incomingByte = Serial.read(); Serial.print("Echoing payload chunk: "); Serial.println(incomingByte); } }
Non-Blocking Code via Millis()
The delay() function halts execution entirely, locking up the CPU core. Using millis() allows you to create non-blocking timers so multiple tasks can run concurrently.
unsigned long previousTime = 0; const long taskInterval = 1000; // Execute task every 1000ms void loop() { unsigned long currentTime = millis(); // Tracks time elapsed since boot if (currentTime - previousTime >= taskInterval) { previousTime = currentTime; // Save timestamp threshold // Perform scheduled hardware routine updates here safely } }
millis() as **unsigned long**. Using standard signed integers causes compilation mismatch faults and breaks timing calculations during counter wrap-arounds.
Servo Motor Control API
Arduino can easily incorporate structured software libraries. The Servo.h library wraps low-level PWM timing loops, exposing a clean API to position actuators directly by degree input.
#include <Servo.h> Servo steeringActuator; // Instantiate servo object tracking context void setup() { steeringActuator.attach(10); // Binds target control mapping line onto pin 10 } void loop() { steeringActuator.write(90); // Forces center sweep alignment angle directly delay(500); steeringActuator.write(180); // Rotates target edge array limit delay(500); }
Hardware Asynchronous Interrupts
Interrupts monitor pin transitions asynchronously. When triggered, they instantly pause the main execution cycle to run an explicit Interrupt Service Routine (ISR) for high-priority events.
const int interruptPin = 2; volatile bool emergencySignal = false; // volatile forces SRAM evaluation lookup void setup() { pinMode(interruptPin, INPUT_PULLUP); // Binds hardware event transitions directly to the ISR function handler attachInterrupt(digitalPinToInterrupt(interruptPin), triggerISR, FALLING); } void loop() { if (emergencySignal) { // Instantly act upon urgent sensor changes or limit triggers emergencySignal = false; } } void triggerISR() { emergencySignal = true; // ISR routine must be kept as fast and lean as possible }