DEV Community

Cover image for The Complete Arduino Nano Guide: From Beginner to Projects
Abhishek Nair
Abhishek Nair

Posted on • Originally published at padawanabhi.de

The Complete Arduino Nano Guide: From Beginner to Projects

Setup, Programming, Sensors & Everything You Need to Know


Table of Contents

  1. Introduction
  2. What is Arduino Nano?
  3. Specifications & Pinout
  4. Getting Started: Hardware Setup
  5. Setting Up the Development Environment
  6. Your First Program
  7. Understanding C++ for Arduino
  8. Sensors & Components Guide
  9. Advanced Projects & Code Examples
  10. Troubleshooting & Tips

Introduction

The Arduino Nano is one of the most versatile and beginner-friendly microcontroller boards available. Whether you're interested in robotics, IoT, home automation, or just learning electronics, this guide will walk you through everything you need to know to get started and build amazing projects.

In this comprehensive guide, you'll learn:

  • How to set up and configure your Arduino Nano
  • How to upload code using Arduino IDE and VS Code
  • The fundamentals of C++ programming for microcontrollers
  • How to connect and work with popular sensors
  • Real-world project examples with complete code

What is Arduino Nano?

The Arduino Nano is a small, breadboard-friendly microcontroller board based on the ATmega328P processor (or ATmega4809 in newer versions). It's perfect for embedded projects where space is limited.

Why Choose Arduino Nano?

Advantages:

  • Compact Size: Only 45mm × 18mm, fits easily on breadboards
  • Affordable: Typically costs $8-15
  • Easy to Learn: Extensive community support and documentation
  • Wide Compatibility: Works with most sensors and components
  • Versatile: Suitable for prototyping and production projects
  • Power Efficient: Low power consumption for battery-powered projects

Ideal For:

  • Robotics and autonomous vehicles
  • IoT applications
  • Home automation
  • Environmental monitoring
  • Game controllers
  • Wearable technology

Specifications & Pinout

Technical Specifications (ATmega328P version)

Specification Details
Processor ATmega328P
Operating Voltage 5V
Input Voltage 7-12V (via Vin) or 5V (via USB)
Digital I/O Pins 14 (6 PWM capable)
Analog Input Pins 8
DC Current per I/O 40mA
Flash Memory 32 KB
SRAM 2 KB
EEPROM 1 KB
Clock Speed 16 MHz
Dimensions 45mm × 18mm

Pinout Diagram Description

The Arduino Nano has the following pin groups:

Digital Pins (0-13):

  • Pins 0-1: UART Serial (Tx/Rx)
  • Pins 3, 5, 6, 9, 10, 11: PWM capable
  • Pin 13: Built-in LED

Analog Pins (A0-A7):

  • Can read analog values (0-1023)
  • Can also be used as digital I/O

Special Pins:

  • 5V: Power supply
  • GND: Ground (3 pins)
  • Vin: External power input
  • AREF: Analog reference
  • RST: Reset button

For detailed pinout diagrams, search "Arduino Nano pinout diagram" on Google Images or visit arduino.cc


Getting Started: Hardware Setup

What You'll Need

Essential Components:

  1. Arduino Nano Microcontroller Board

  2. USB Cable (USB Type-A to Mini-B)

  3. Breadboard (400-830 hole)

  4. Jumper Wires

    • Purchase from: DFRobot: Jumper Wires
    • Price: $5-10
    • Get a variety pack with male-to-male, male-to-female, and female-to-female

Step-by-Step Hardware Assembly

Step 1: Prepare Your Workspace

  • Gather all components on a clear, static-free surface
  • Ensure your work area has proper lighting
  • Keep the USB cable nearby for testing

Step 2: Insert Arduino Nano into Breadboard

  1. Take your breadboard and locate the center channel (the gap running down the middle)
  2. Position the Arduino Nano above the breadboard with the USB port facing away from you
  3. Carefully push the Nano into the breadboard, ensuring:
    • All pins on one side go into the breadboard's holes
    • The USB port has clearance from the breadboard edge
    • The board sits flush against the breadboard

Important Note: The two rows of pins should sit on opposite sides of the center channel. This leaves the center section free for adding sensors and other components.

Step 3: Connect Power and Ground

  1. Identify Power Pins on Nano:

    • 5V pin: Supplies power to connected components
    • GND pins: Ground/reference points (there are 3)
  2. Create Power Rails on Breadboard:

    • Use a jumper wire to connect the 5V pin to the positive (red) rail on the breadboard
    • Use a jumper wire to connect a GND pin to the negative (black) rail on the breadboard
    • These rails distribute power to all your components
  3. Visual Layout:

   [Arduino Nano]
       5V → Red Rail (Power)
       GND → Black Rail (Ground)
Enter fullscreen mode Exit fullscreen mode

Step 4: Connect USB Cable

  1. Take the USB Type-A to Mini-B cable
  2. Connect the Type-A end to your computer
  3. Connect the Mini-B end to the Arduino Nano's USB port
  4. You should see a small LED on the Nano light up (this indicates power)

Step 5: Verify Connection

  • Open your computer's device manager (Windows) or system information (Mac/Linux)
  • Look for a new COM port or /dev/ttyUSB device
  • This confirms your Nano is recognized by your computer

Setting Up the Development Environment

You have two excellent options for programming your Arduino Nano. We'll cover both.

Option 1: Arduino IDE (Official & Easiest)

Arduino IDE is the official development environment, perfect for beginners.

Installation Steps:

  1. Download Arduino IDE:

  2. Install the IDE:

    • Windows: Run the installer and follow the prompts
    • Mac: Drag the Arduino app to Applications folder
    • Linux: Extract the tar file and run ./install.sh
  3. Launch Arduino IDE:

    • Open the application
    • You should see a blank sketch with setup() and loop() functions

Configure for Arduino Nano:

  1. Select Board:

    • Click ToolsBoard:Arduino AVR BoardsArduino Nano
  2. Select Processor:

    • Click ToolsProcessor:ATmega328P (or ATmega328P (Old Bootloader) if your Nano is older)
  3. Select COM Port:

    • Connect your Nano via USB
    • Click ToolsPort: → Select the COM port that appeared
    • On Windows: Usually COM3 or higher
    • On Mac: Usually /dev/cu.usbserial-####
    • On Linux: Usually /dev/ttyUSB0
  4. Test Connection:

    • Click ToolsGet Board Info
    • If successful, you'll see board details

Option 2: Visual Studio Code (Advanced & Powerful)

VS Code offers a professional development environment with better code editing.

Installation Steps:

  1. Install VS Code:

  2. Install Arduino Extension:

    • Open VS Code
    • Click the Extensions icon (left sidebar)
    • Search for "Arduino" by Microsoft
    • Click Install
  3. Install Arduino CLI (Required backend):

    • Visit arduino.github.io/arduino-cli
    • Download for your operating system
    • Follow installation instructions
    • Verify installation by running arduino-cli version in terminal
  4. Configure VS Code:

    • Open VS Code
    • Press Ctrl+Shift+P (Cmd+Shift+P on Mac)
    • Type "Arduino: Board Manager"
    • Search and install Arduino AVR Boards
  5. Create Your First Project:

    • Create a new folder for your project
    • Inside, create a file: sketch.ino
    • VS Code should recognize it as Arduino code
  6. Configure Board Settings:

    • Click on the Arduino icon in the bottom status bar
    • Select "Arduino Nano" as your board
    • Select "ATmega328P" as your processor
    • Select your COM port

Uploading Code in VS Code:

  • With your .ino file open, press Ctrl+Alt+U to upload
  • Or click the Upload button in the status bar

Your First Program

Let's write and upload your first program: a simple LED blink.

The Classic Blink Program

Physical Setup:

  1. Insert an LED into the breadboard (longer leg positive)
  2. Connect LED's positive leg → Pin 13 (through breadboard)
  3. Connect LED's negative leg → Ground (through a 220Ω resistor to ground)

Code:

// Arduino Nano - Simple LED Blink
// This program blinks the built-in LED on pin 13

void setup() {
  // setup() runs once when the board starts
  // Configure pin 13 as an output
  pinMode(13, OUTPUT);
}

void loop() {
  // loop() runs repeatedly, forever

  // Turn LED on
  digitalWrite(13, HIGH);

  // Wait for 1000 milliseconds (1 second)
  delay(1000);

  // Turn LED off
  digitalWrite(13, LOW);

  // Wait for 1000 milliseconds (1 second)
  delay(1000);
}
Enter fullscreen mode Exit fullscreen mode

Upload Instructions:

  1. Arduino IDE:

    • Copy the code above into the IDE editor
    • Click SketchUpload (or Ctrl+U)
    • Wait for "Done uploading" message
  2. VS Code:

    • Copy the code into your .ino file
    • Press Ctrl+Alt+U
    • Watch the upload progress

Expected Result:

  • The LED on your breadboard will blink on and off every second
  • If you see this, congratulations! You've successfully programmed an Arduino Nano

Understanding the Code

pinMode(pin, mode)

  • Configures a pin as either INPUT or OUTPUT
  • Must be called in setup()
  • Example: pinMode(13, OUTPUT) makes pin 13 an output

digitalWrite(pin, value)

  • Sets a digital pin to HIGH (5V) or LOW (0V)
  • HIGH turns things on, LOW turns them off
  • Example: digitalWrite(13, HIGH) sends 5V to pin 13

delay(milliseconds)

  • Pauses program execution for specified milliseconds
  • 1000 ms = 1 second
  • Example: delay(500) pauses for 500ms (half second)

setup() vs loop()

  • setup(): Runs once at startup, used for initialization
  • loop(): Runs repeatedly forever, where your main program logic goes

Understanding C++ for Arduino

Arduino code is actually a simplified version of C++. Understanding the basics will help you write better programs.

Variables and Data Types

Variables store information. Here are the common types:

// Integer - whole numbers
int age = 25;
int count = 0;

// Float - decimal numbers
float temperature = 23.5;
float voltage = 3.14;

// Byte - 0 to 255 (saves memory)
byte brightness = 255;

// Boolean - true or false
boolean isMotorRunning = true;
bool ledIsOn = false;

// Character - single character
char initial = 'A';

// String - text
String sensorName = "Temperature Sensor";
Enter fullscreen mode Exit fullscreen mode

Constants

Constants are values that never change. Use them for pin numbers:

// Define constants at the top of your program
const int LED_PIN = 13;
const int BUTTON_PIN = 2;
const int SENSOR_PIN = A0;

// Use them in your code
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
Enter fullscreen mode Exit fullscreen mode

Operators

Perform operations on variables:

// Arithmetic
int result = 10 + 5;    // addition
int math = 20 - 8;      // subtraction
int product = 4 * 5;    // multiplication
int quotient = 20 / 4;  // division
int remainder = 17 % 5; // modulo (remainder)

// Comparison (returns true or false)
if (10 > 5) { }         // greater than
if (5 < 10) { }         // less than
if (5 == 5) { }         // equals
if (5 != 10) { }        // not equals

// Logical
if (a > 5 && b < 10) { }  // AND (both must be true)
if (a > 5 || b < 10) { }  // OR (at least one true)
if (!isRunning) { }       // NOT (opposite of true/false)
Enter fullscreen mode Exit fullscreen mode

Control Structures

Control what your program does:

// IF statement
if (temperature > 30) {
  digitalWrite(COOLER_PIN, HIGH);
}

// IF-ELSE
if (buttonPressed) {
  digitalWrite(LED_PIN, HIGH);
} else {
  digitalWrite(LED_PIN, LOW);
}

// FOR loop - repeat a specific number of times
for (int i = 0; i < 10; i++) {
  digitalWrite(LED_PIN, HIGH);
  delay(100);
  digitalWrite(LED_PIN, LOW);
  delay(100);
}

// WHILE loop - repeat until condition is false
while (sensorValue > 500) {
  Serial.println(sensorValue);
  sensorValue = analogRead(A0);
}
Enter fullscreen mode Exit fullscreen mode

Functions

Create reusable blocks of code:

// Function declaration
void blinkLED(int times) {
  for (int i = 0; i < times; i++) {
    digitalWrite(LED_PIN, HIGH);
    delay(200);
    digitalWrite(LED_PIN, LOW);
    delay(200);
  }
}

// Function that returns a value
int readSensorValue() {
  int value = analogRead(A0);
  return value;
}

// Using functions
void loop() {
  blinkLED(3);              // Call function with parameter
  int sensorReading = readSensorValue();
}
Enter fullscreen mode Exit fullscreen mode

Serial Communication

Communicate with your computer:

void setup() {
  // Start serial communication at 9600 baud rate
  Serial.begin(9600);

  // Print messages
  Serial.println("System started!");
}

void loop() {
  // Print sensor value
  int value = analogRead(A0);
  Serial.print("Sensor: ");
  Serial.println(value);

  delay(1000);
}
Enter fullscreen mode Exit fullscreen mode

Viewing Serial Output:

  1. Open Arduino IDE
  2. Click ToolsSerial Monitor
  3. Set baud rate to 9600
  4. View live data from your Nano

Sensors & Components Guide

Now let's connect and use popular sensors with your Arduino Nano.

1. Infrared (IR) Sensor

What It Does: Detects motion or objects using infrared light

Where to Buy:

Specifications:

  • Operating Voltage: 3.3-5V
  • Detection Range: Up to 7 meters
  • Detection Angle: 100 degrees
  • Output: Digital HIGH/LOW
  • Working Current: 15µA (ultra-low power)

Wiring Diagram Description:

        ┌─────────────────┐
        │   IR Sensor     │
        │   (PIR)         │
        ├─────────────────┤
        │ Vcc  Out  GND   │
        └─────────────────┘
        │     │    │
        │     │    └──→ GND (Nano)
        │     │
        │     └──→ Pin 2 (Nano)
        │
        └──→ 5V (Nano)
Enter fullscreen mode Exit fullscreen mode

Code Example:

const int PIR_PIN = 2;

void setup() {
  pinMode(PIR_PIN, INPUT);
  Serial.begin(9600);
}

void loop() {
  int motionDetected = digitalRead(PIR_PIN);

  if (motionDetected == HIGH) {
    Serial.println("Motion detected!");
    digitalWrite(13, HIGH);  // Turn on LED
  } else {
    Serial.println("No motion");
    digitalWrite(13, LOW);   // Turn off LED
  }

  delay(100);
}
Enter fullscreen mode Exit fullscreen mode

Tips:

  • The sensor needs 30-60 seconds to calibrate on startup
  • Mount it at 2 meters height for best coverage
  • Avoid direct sunlight on the sensor

2. Ultrasonic Distance Sensor

What It Does: Measures distance to objects using sound waves

Where to Buy:

Specifications:

  • Operating Voltage: 3.3-5.5V
  • Measurement Range: 15cm to 900cm (URM13) or 2cm to 400cm (HC-SR04 compatible mode)
  • Resolution: 1cm
  • Accuracy: 1%
  • Interfaces: TRIG/ECHO (HC-SR04 compatible), UART, I2C
  • Automatic noise detection and real-time calibration

Wiring Diagram Description (HC-SR04 Compatible Mode):

The DFRobot URM13 sensor supports HC-SR04 compatible TRIG/ECHO mode, so you can use the same wiring:

        ┌──────────────────┐
        │   Ultrasonic     │
        │   URM13/HC-SR04  │
        ├──────────────────┤
        │ Vcc  Trig Ech Gnd│
        └──────────────────┘
        │     │    │   │
        │     │    │   └──→ GND (Nano)
        │     │    │
        │     │    └──→ Pin 3 (Nano) - ECHO
        │     │
        │     └──→ Pin 4 (Nano) - TRIG
        │
        └──→ 5V (Nano)
Enter fullscreen mode Exit fullscreen mode

Note: The URM13 also supports I2C and UART interfaces for more advanced applications, but the TRIG/ECHO mode works with the same code as HC-SR04.

Code Example:

const int TRIG_PIN = 4;
const int ECHO_PIN = 3;

void setup() {
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  Serial.begin(9600);
}

void loop() {
  // Send 10 microsecond pulse to trigger
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Measure the echo time
  long duration = pulseIn(ECHO_PIN, HIGH);

  // Calculate distance
  // Speed of sound: 343 m/s = 0.0343 cm/microsecond
  // Distance = (duration * 0.0343) / 2 (divide by 2 for round trip)
  int distance = duration * 0.034 / 2;

  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  delay(100);
}
Enter fullscreen mode Exit fullscreen mode

Tips:

  • URM13: Keep objects at least 15cm away (minimum range)
  • HC-SR04 mode: Keep objects at least 2cm away
  • Works best on solid surfaces
  • Avoid measuring very soft or angled surfaces
  • Sensor needs clear line of sight to object
  • URM13 features automatic noise detection for more reliable readings

3. LED (Light Emitting Diode)

What It Does: Emits light when current flows through it

Where to Buy:

Specifications:

  • Operating Voltage: 2-3.3V (depends on color)
  • Typical Current: 20mA
  • Requires current-limiting resistor

Color Specifications:

  • Red: 2V, 20mA (use 220Ω resistor)
  • Green: 2.2V, 20mA (use 220Ω resistor)
  • Blue: 3.2V, 20mA (use 150Ω resistor)
  • Yellow: 2.1V, 20mA (use 220Ω resistor)

Wiring Diagram Description:

        Positive (Long leg)
        │
        ├─────[LED]─────[220Ω Resistor]─────┐
        │                                    │
     Pin 13                                GND
Enter fullscreen mode Exit fullscreen mode

Code Example:

const int RED_LED = 5;
const int GREEN_LED = 6;
const int BLUE_LED = 9;

void setup() {
  pinMode(RED_LED, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
  pinMode(BLUE_LED, OUTPUT);
}

void loop() {
  // Blink red
  digitalWrite(RED_LED, HIGH);
  delay(500);
  digitalWrite(RED_LED, LOW);

  // Blink green
  digitalWrite(GREEN_LED, HIGH);
  delay(500);
  digitalWrite(GREEN_LED, LOW);

  // Fade blue using PWM
  for (int brightness = 0; brightness <= 255; brightness += 5) {
    analogWrite(BLUE_LED, brightness);
    delay(50);
  }
}
Enter fullscreen mode Exit fullscreen mode

Tips:

  • Always use a resistor (never connect directly to power)
  • Longer leg = positive (anode), shorter leg = negative (cathode)
  • PWM-capable pins (3, 5, 6, 9, 10, 11) allow brightness control
  • Use digitalWrite for full on/off, analogWrite for brightness
  • DFRobot LED pack includes 10 of each color (red, green, yellow, blue, white)

4. Stepper Motor

What It Does: Rotates in precise steps, excellent for positioning

Where to Buy:

Specifications:

  • Type: Unipolar stepper motor with integrated driver
  • Operating Voltage: 5V
  • Steps per Revolution: 4096 (with 1/64 gear ratio, half-step mode)
  • Holding Torque: 0.9 kgf·cm
  • Integrated Driver: A4988 (included on module)
  • Physical Interface: 4-Pin (STEP, DIR, 5V, GND)

Wiring Diagram Description:

The DFRobot 28BYJ-48 module includes an integrated A4988 driver with a simplified 4-pin interface:

    ┌─────────────────────┐
    │ 28BYJ-48 Module      │
    │ (Motor + Driver)     │
    ├─────────────────────┤
    │ STEP  DIR  5V  GND  │
    └─────────────────────┘
      │    │    │    │
      │    │    │    └──→ GND (Nano)
      │    │    │
      │    │    └──→ 5V (Nano)
      │    │
      │    └──→ Pin 11 (Nano) - Direction
      │
      └──→ Pin 10 (Nano) - Step
Enter fullscreen mode Exit fullscreen mode

Note: For traditional ULN2003 driver setups (without integrated driver), use pins 10-13 as shown in the code example below.

Code Example (for DFRobot module with STEP/DIR interface):

const int STEP_PIN = 10;
const int DIR_PIN = 11;

void setup() {
  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIR_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // Set direction (HIGH = clockwise, LOW = counter-clockwise)
  digitalWrite(DIR_PIN, HIGH);

  // Rotate one full revolution (4096 steps with 1:64 gear ratio)
  for (int i = 0; i < 4096; i++) {
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(500);  // Adjust for speed
    digitalWrite(STEP_PIN, LOW);
    delayMicroseconds(500);
  }

  delay(1000);

  // Reverse direction
  digitalWrite(DIR_PIN, LOW);
  for (int i = 0; i < 4096; i++) {
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(500);
    digitalWrite(STEP_PIN, LOW);
    delayMicroseconds(500);
  }

  delay(1000);
}
Enter fullscreen mode Exit fullscreen mode

Code Example (for traditional ULN2003 driver - manual control):

const int IN1 = 10;
const int IN2 = 11;
const int IN3 = 12;
const int IN4 = 13;

void setup() {
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
}

// Step sequence for motor
void step(int stepNum) {
  switch(stepNum) {
    case 0:
      digitalWrite(IN1, HIGH);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, LOW);
      break;
    case 1:
      digitalWrite(IN1, HIGH);
      digitalWrite(IN2, HIGH);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, LOW);
      break;
    case 2:
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, HIGH);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, LOW);
      break;
    case 3:
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, HIGH);
      digitalWrite(IN3, HIGH);
      digitalWrite(IN4, LOW);
      break;
    case 4:
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, HIGH);
      digitalWrite(IN4, LOW);
      break;
    case 5:
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, HIGH);
      digitalWrite(IN4, HIGH);
      break;
    case 6:
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, HIGH);
      break;
    case 7:
      digitalWrite(IN1, HIGH);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, HIGH);
      break;
  }
}

void loop() {
  // Rotate 2048 steps (one full revolution)
  for (int i = 0; i < 2048; i++) {
    step(i % 8);
    delay(2);  // Delay between steps
  }

  delay(1000);
}
Enter fullscreen mode Exit fullscreen mode

Better Approach: Use Stepper.h Library

#include <Stepper.h>

const int STEPS_PER_REVOLUTION = 2048;
Stepper stepper(STEPS_PER_REVOLUTION, 10, 11, 12, 13);

void setup() {
  stepper.setSpeed(10);  // Speed in RPM
}

void loop() {
  // Rotate clockwise
  stepper.step(STEPS_PER_REVOLUTION);
  delay(1000);

  // Rotate counter-clockwise
  stepper.step(-STEPS_PER_REVOLUTION);
  delay(1000);
}
Enter fullscreen mode Exit fullscreen mode

Tips:

  • The DFRobot module includes an integrated A4988 driver (no separate driver needed)
  • Current draw: Check module specifications (power from separate supply recommended for high torque)
  • Motor speed affects torque (slower = more torque)
  • Stepper.h library makes programming much easier
  • The module provides 4-pin interface (STEP, DIR, 5V, GND) for simplified wiring

5. Temperature & Humidity Sensor

What It Does: Measures temperature and humidity

Where to Buy:

Specifications:

  • Voltage: 3-5V
  • Temperature Range: -40°C to 80°C
  • Humidity Range: 0-100%
  • Accuracy: ±0.5°C, ±2%

Wiring Diagram Description:

        ┌─────────────┐
        │  DHT22      │
        ├─────────────┤
        │ 1   2   4   │
        │ +5V Data GND│
        └─────────────┘
        │   │    │
        │   │    └──→ GND
        │   │
        │   └──→ Pin 2 (with 10kΩ pull-up resistor to +5V)
        │
        └──→ +5V
Enter fullscreen mode Exit fullscreen mode

Code Example:

#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  dht.begin();
}

void loop() {
  delay(2000);  // Sensor needs 2 seconds between readings

  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("Failed to read from sensor!");
    return;
  }

  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.println(" °C");

  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println(" %");
}
Enter fullscreen mode Exit fullscreen mode

Installation of DHT Library:

  1. Open Arduino IDE
  2. Click SketchInclude LibraryManage Libraries
  3. Search for "DHT by Adafruit"
  4. Click Install

Tips:

  • Need pull-up resistor (10kΩ) on data pin
  • Avoid direct water contact
  • Allow sensor to stabilize before taking readings
  • Read interval should be at least 2 seconds

Advanced Projects & Code Examples

Project 1: Motion-Activated Alarm System

Components Needed:

  • PIR Motion Sensor
  • Buzzer (or speaker)
  • LED

Wiring:

  • PIR sensor → Pin 2
  • Buzzer → Pin 5
  • LED → Pin 13

Complete Code:

#include <Arduino.h>

const int PIR_SENSOR = 2;
const int BUZZER = 5;
const int LED = 13;
const int DEBOUNCE_DELAY = 100;

unsigned long lastMotionTime = 0;
boolean alarmActive = false;

void setup() {
  pinMode(PIR_SENSOR, INPUT);
  pinMode(BUZZER, OUTPUT);
  pinMode(LED, OUTPUT);
  Serial.begin(9600);

  Serial.println("Motion alarm system initialized");
  Serial.println("PIR sensor warming up...");
  delay(30000);  // 30 seconds for sensor calibration
  Serial.println("System ready!");
}

void loop() {
  int motionDetected = digitalRead(PIR_SENSOR);

  if (motionDetected == HIGH) {
    unsigned long currentTime = millis();

    // Debounce: ignore if less than 100ms since last motion
    if (currentTime - lastMotionTime > DEBOUNCE_DELAY) {
      if (!alarmActive) {
        triggerAlarm();
        alarmActive = true;
      }
      lastMotionTime = currentTime;
    }
  } else {
    if (alarmActive) {
      stopAlarm();
      alarmActive = false;
    }
  }

  delay(50);
}

void triggerAlarm() {
  Serial.println("MOTION DETECTED - ALARM TRIGGERED!");

  // Alarm pattern: beep and flash
  for (int i = 0; i < 5; i++) {
    digitalWrite(BUZZER, HIGH);
    digitalWrite(LED, HIGH);
    delay(200);

    digitalWrite(BUZZER, LOW);
    digitalWrite(LED, LOW);
    delay(200);
  }
}

void stopAlarm() {
  digitalWrite(BUZZER, LOW);
  digitalWrite(LED, LOW);
  Serial.println("Motion stopped - alarm deactivated");
}
Enter fullscreen mode Exit fullscreen mode

Project 2: Distance Measurement with LCD Display

Components Needed:

  • Ultrasonic Sensor (HC-SR04)
  • 16x2 LCD Display
  • 10kΩ potentiometer (for LCD contrast)

Wiring for LCD I2C Module:

  • SDA → Arduino A4
  • SCL → Arduino A5
  • VCC → 5V
  • GND → GND

Complete Code:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

const int TRIG_PIN = 4;
const int ECHO_PIN = 3;

// LCD address 0x27 (adjust if different)
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  // Initialize LCD
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Distance Meter");
  lcd.setCursor(0, 1);
  lcd.print("Ready");

  Serial.begin(9600);
  delay(2000);
  lcd.clear();
}

void loop() {
  int distance = measureDistance();

  // Display on LCD
  lcd.setCursor(0, 0);
  lcd.print("Distance: ");
  lcd.print(distance);
  lcd.print(" cm  ");

  // Display on Serial
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  // Status on LCD
  lcd.setCursor(0, 1);
  if (distance < 10) {
    lcd.print("CLOSE!          ");
  } else if (distance < 30) {
    lcd.print("NEAR            ");
  } else {
    lcd.print("FAR             ");
  }

  delay(500);
}

int measureDistance() {
  // Send trigger pulse
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Measure echo duration
  long duration = pulseIn(ECHO_PIN, HIGH, 30000);  // 30ms timeout

  // Calculate distance
  // Speed of sound: 343 m/s = 0.0343 cm/microsecond
  int distance = duration * 0.034 / 2;

  return distance;
}
Enter fullscreen mode Exit fullscreen mode

Installation of LiquidCrystal I2C Library:

  1. Arduino IDE → SketchInclude LibraryManage Libraries
  2. Search "LiquidCrystal I2C" by Frank de Brabander
  3. Install

Project 3: Temperature Monitor with LED Indicators

Components Needed:

  • DHT22 Temperature Sensor
  • 3 LEDs (Green, Yellow, Red)
  • 3 × 220Ω Resistors

Wiring:

  • DHT22 Data → Pin 2
  • Green LED → Pin 9
  • Yellow LED → Pin 10
  • Red LED → Pin 11

Complete Code:

#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT22

const int GREEN_LED = 9;
const int YELLOW_LED = 10;
const int RED_LED = 11;

DHT dht(DHTPIN, DHTTYPE);

// Temperature thresholds
const float COLD_TEMP = 15.0;
const float WARM_TEMP = 25.0;
const float HOT_TEMP = 35.0;

void setup() {
  pinMode(GREEN_LED, OUTPUT);
  pinMode(YELLOW_LED, OUTPUT);
  pinMode(RED_LED, OUTPUT);

  Serial.begin(9600);
  dht.begin();

  Serial.println("Temperature Monitor Started");
}

void loop() {
  delay(2000);

  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();

  // Check for sensor errors
  if (isnan(temperature) || isnan(humidity)) {
    Serial.println("Sensor read failed!");
    return;
  }

  // Print to Serial
  Serial.print("Temp: ");
  Serial.print(temperature);
  Serial.print("°C, Humidity: ");
  Serial.print(humidity);
  Serial.println("%");

  // Turn on appropriate LED
  updateLEDs(temperature);
}

void updateLEDs(float temp) {
  // Turn all off first
  digitalWrite(GREEN_LED, LOW);
  digitalWrite(YELLOW_LED, LOW);
  digitalWrite(RED_LED, LOW);

  // Determine which LED to turn on
  if (temp < COLD_TEMP) {
    // Cold - Blue would be nice, but we use GREEN
    digitalWrite(GREEN_LED, HIGH);
    Serial.println("Status: COLD");
  } 
  else if (temp < WARM_TEMP) {
    // Comfortable
    digitalWrite(GREEN_LED, HIGH);
    Serial.println("Status: COMFORTABLE");
  } 
  else if (temp < HOT_TEMP) {
    // Warm - warning
    digitalWrite(YELLOW_LED, HIGH);
    Serial.println("Status: WARM");
  } 
  else {
    // Hot - alarm
    digitalWrite(RED_LED, HIGH);
    Serial.println("Status: HOT ALERT!");
  }
}
Enter fullscreen mode Exit fullscreen mode

Project 4: Multi-Sensor Data Logger

Components Needed:

  • DHT22 Temperature Sensor
  • Ultrasonic Distance Sensor
  • SD Card Module (optional, for data logging)

Complete Code (with Serial data logging):

#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT22

const int TRIG_PIN = 4;
const int ECHO_PIN = 3;

DHT dht(DHTPIN, DHTTYPE);

struct SensorData {
  float temperature;
  float humidity;
  int distance;
  unsigned long timestamp;
};

SensorData currentReading;

void setup() {
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  Serial.begin(9600);
  dht.begin();

  Serial.println("=== Arduino Nano Multi-Sensor Logger ===");
  Serial.println("Time(ms),Temperature(C),Humidity(%),Distance(cm)");
}

void loop() {
  // Read all sensors
  currentReading.timestamp = millis();
  currentReading.temperature = dht.readTemperature();
  currentReading.humidity = dht.readHumidity();
  currentReading.distance = measureDistance();

  // Log data
  logData(currentReading);

  delay(5000);  // Read every 5 seconds
}

int measureDistance() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  long duration = pulseIn(ECHO_PIN, HIGH, 30000);
  int distance = duration * 0.034 / 2;

  return distance;
}

void logData(SensorData data) {
  // Print in CSV format for easy import to spreadsheet
  Serial.print(data.timestamp);
  Serial.print(",");
  Serial.print(data.temperature);
  Serial.print(",");
  Serial.print(data.humidity);
  Serial.print(",");
  Serial.println(data.distance);
}
Enter fullscreen mode Exit fullscreen mode

How to use the logged data:

  1. Open the Serial Monitor
  2. Copy all the data
  3. Paste into a text file and save as .csv
  4. Open in Excel/Google Sheets for analysis

Troubleshooting & Tips

Common Issues and Solutions

Issue 1: "Unknown Serial Port"

  • Problem: Arduino Nano not recognized by computer
  • Solutions:
    • Install CH340 driver (clone boards): Search "CH340 driver" + your OS
    • Try different USB cable
    • Try different USB port
    • Restart computer
    • Reinstall Arduino IDE

Issue 2: "Failed to upload sketch"

  • Problem: Code won't upload to board
  • Solutions:
    • Verify correct board selected (Arduino Nano)
    • Verify correct processor selected (ATmega328P)
    • Verify correct COM port
    • Try older bootloader: Select "ATmega328P (Old Bootloader)"
    • Wait 1-2 seconds between uploads

Issue 3: Sensor not responding

  • Problem: Sensor values always zero or invalid
  • Solutions:
    • Check wiring connections (especially GND)
    • Test with a known working circuit
    • Verify power supply (5V from USB)
    • Check if library is installed (DHT, etc.)
    • Verify pin numbers in code match physical connections

Issue 4: LED won't light up

  • Problem: LED remains dark
  • Solutions:
    • Check LED polarity (long leg = positive)
    • Verify resistor value (220Ω typical)
    • Check if pin voltage with multimeter
    • Try different LED and resistor
    • Verify pinMode() is set to OUTPUT

Issue 5: Motor won't spin

  • Problem: Stepper motor unresponsive
  • Solutions:
    • Ensure ULN2003 driver is used (required!)
    • Check all 4 motor wires connected to driver
    • Verify driver pins match code
    • Try slower speed: stepper.setSpeed(5)
    • Check power supply (500mA available)
    • Use separate power supply if possible

Pro Tips for Better Code

1. Use Constants Instead of Magic Numbers

// BAD
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);

// GOOD
const int LED_PIN = 13;
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
Enter fullscreen mode Exit fullscreen mode

2. Add Comments to Explain Logic

// Check if temperature exceeds threshold
if (temperature > MAX_TEMP) {
  // Turn on cooling fan
  digitalWrite(FAN_PIN, HIGH);
}
Enter fullscreen mode Exit fullscreen mode

3. Use Functions for Repeated Code

// Instead of repeating this pattern multiple times:
void blinkPattern(int pin, int times) {
  for (int i = 0; i < times; i++) {
    digitalWrite(pin, HIGH);
    delay(200);
    digitalWrite(pin, LOW);
    delay(200);
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Manage Your Pins

// Define all pins at the top
const int LED_PIN = 13;
const int SENSOR_PIN = 2;
const int BUTTON_PIN = 4;
const int MOTOR_PIN = 5;
Enter fullscreen mode Exit fullscreen mode

5. Use Serial for Debugging

void loop() {
  int sensorValue = analogRead(A0);

  Serial.print("Raw value: ");
  Serial.println(sensorValue);

  if (sensorValue > 500) {
    Serial.println("Threshold exceeded!");
  }
}
Enter fullscreen mode Exit fullscreen mode

6. Avoid Long Delays in Critical Loops

// BAD - blocks everything for 5 seconds
void loop() {
  doSomething();
  delay(5000);  // Nothing else runs!
}

// BETTER - use millis() for non-blocking timing
unsigned long lastTime = 0;
void loop() {
  unsigned long currentTime = millis();

  if (currentTime - lastTime > 5000) {
    doSomething();
    lastTime = currentTime;
  }
}
Enter fullscreen mode Exit fullscreen mode

Performance Optimization

Memory Tips:

  • Arduino Nano has only 2KB SRAM
  • Use byte instead of int when possible
  • Use constants for strings instead of creating them in loop
  • Avoid large arrays

Speed Tips:

  • Use digital I/O instead of analog when possible (faster)
  • Minimize Serial.print() statements in fast loops
  • Use bitwise operations for efficiency
  • Profile code with Serial timestamps

Safety Precautions

  1. Never connect:

    • 5V directly to analog pins without resistor
    • Motors directly to GPIO pins (use driver)
    • High voltage to any pin
  2. Always use:

    • Resistors with LEDs
    • Proper power supply for motors
    • Driver modules for high-current devices
  3. Protect your USB port:

    • Use separate power for motors/sensors when possible
    • Don't draw more than 500mA from USB
  4. Prevent shorts:

    • Insulate exposed connections
    • Keep workspace organized
    • Double-check wiring before power on

Next Steps and Further Learning

Project Ideas

  1. Home Automation: Control lights and temperature
  2. Robotics: Build a line-following or obstacle-avoiding robot
  3. Weather Station: Log temperature, humidity, and pressure
  4. Smart Garden: Automatic watering system
  5. Security System: Motion detection with alerts
  6. Game Controller: Build a custom gaming device

Useful Resources

Advanced Topics to Explore

  • Interrupts: Respond instantly to events
  • EEPROM: Store data persistently
  • PWM: More sophisticated motor and LED control
  • I2C Communication: Connect multiple sensors
  • SPI Communication: Fast data transfer
  • Custom Libraries: Write your own reusable code
  • Wireless Communication: Bluetooth, WiFi (with additional modules)

Conclusion

You now have a comprehensive understanding of the Arduino Nano, from basic setup through advanced projects. Start with simple LED blinkers, move to sensor integration, and gradually tackle more complex projects.

Remember:

  • Start small: Master one component before combining multiple
  • Test thoroughly: Use Serial Monitor to verify sensor data
  • Reuse code: Save working examples for future projects
  • Read errors carefully: Arduino IDE messages are usually helpful
  • Don't give up: Every error is a learning opportunity

The Arduino Nano opens a world of creative possibilities. Happy building!


Quick Reference Cheat Sheet

Common Arduino Functions

pinMode(pin, OUTPUT/INPUT)          // Configure pin mode
digitalWrite(pin, HIGH/LOW)         // Digital output
digitalRead(pin)                    // Digital input
analogRead(pin)                     // Analog input (0-1023)
analogWrite(pin, value)             // PWM output (0-255)
delay(milliseconds)                 // Pause execution
delayMicroseconds(microseconds)    // Pause (tiny delay)
millis()                           // Milliseconds since start
Serial.begin(9600)                 // Start serial at baud rate
Serial.println(value)              // Print with newline
Serial.print(value)                // Print without newline
pulseIn(pin, HIGH/LOW)             // Measure pulse width
Enter fullscreen mode Exit fullscreen mode

Pin Summary

Digital I/O:  0-13 (0,1 = serial, 13 = built-in LED)
PWM Pins:     3, 5, 6, 9, 10, 11
Analog Input: A0-A7
Power:        5V, 3.3V, GND (×3)
Special:      AREF, RST, ICSP
Enter fullscreen mode Exit fullscreen mode

Common Sensor Pins

PIR Motion Sensor:           Pin 2 (Digital)
Ultrasonic Echo:             Pin 3 (Digital)
DHT Temperature:             Pin 2 (Digital)
Buzzer/Speaker:              Pin 5 (PWM)
Stepper Motor (4 pins):      Pins 10-13
LED (PWM for brightness):    Pins 3, 5, 6, 9, 10, 11
Button:                      Any digital pin
Analog Sensor:               A0-A7
Enter fullscreen mode Exit fullscreen mode

Document Version: 1.0

Last Updated: December 2025

Target Audience: Complete Beginners to Intermediate Makers

Total Content: Comprehensive Guide with Code Examples and Component Links

Happy coding and building amazing projects!


Originally published at padawanabhi.de

Top comments (0)