Arduino logo

Arduino Beginner

Physical computing framework — bare-metal C/C++ flavor, microchip architecture, register controls, and real-world hardware interfacing.

1 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.

ino · main.ino
// 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
}

2 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.

boolean / bool 1-byte logical state value bool state = false;
byte / uint8_t 1-byte unsigned number (0 to 255) byte pinNumber = 13;
int / int16_t 2-byte signed integer on 8-bit AVR int sensorValue = -450;
unsigned long 4-byte large positive number unsigned long time = 0;
float / double 4-byte standard precision decimal float voltage = 4.75;
char 1-byte text character literal char command = 'S';

3 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.

ino · digital.ino
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);
  }
}

4 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).

ino · analog.ino
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
}

5 Serial Monitor Communication

The Serial peripheral manages UART communication streams, enabling telemetry data transmission back to a host computer or connected module grids.

ino · serial.ino
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);
  }
}

6 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.

ino · nonblocking.ino
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
  }
}
Always declare tracking variables for millis() as **unsigned long**. Using standard signed integers causes compilation mismatch faults and breaks timing calculations during counter wrap-arounds.

7 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.

ino · servo.ino
#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);
}

8 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.

ino · interrupts.ino
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
}
With bare-metal fundamentals under control, you are ready to construct low-overhead IoT routines and map peripheral grids leveraging custom architectures.