Module 11: Arduino Nano & Compact Builds
Level: ๐ก Intermediate
Board: Arduino Nano
Prerequisites: Module 8
Estimated time: 60โ80 minutes
Goal: Build compact, portable projects and understand board selection.
What You'll Learn
The Arduino Uno is great for learning, but it's too bulky for most finished projects. The Arduino Nano is pin-compatible with the Uno, fits directly on a breadboard, and costs less. In this module you'll learn the Nano's differences, deal with USB drivers, solder headers, choose portable power, plan compact builds for enclosures, and put it all together with a battery-powered portable air quality monitor.
11.1 Nano vs. Uno: What's Different and What's the Same
Hardware Comparison
| Spec | Arduino Uno | Arduino Nano |
|---|---|---|
| Microcontroller | ATmega328P | ATmega328P |
| Digital pins | 14 | 14 (same) |
| Analog pins | 6 (A0โA5) | 8 (A0โA7, two extras) |
| PWM pins | 6 | 6 (same: 3, 5, 6, 9, 10, 11) |
| Flash memory | 32 KB | 32 KB |
| RAM | 2 KB | 2 KB |
| Clock speed | 16 MHz | 16 MHz |
| Operating voltage | 5V | 5V |
| USB connector | USB-B (large) | Mini-USB or Micro-USB |
| Size | 68.6 ร 53.4 mm | 45 ร 18 mm |
| Breadboard-friendly | No (needs jumper wires) | Yes (plugs directly in) |
| Price (clone) | ~$3โ5 | ~$2โ4 |
Pin Mapping: What Moves
The pin functions are identical, but the physical locations change:
- Digital pins 0โ13: Same numbering, different physical positions along the Nano's edges
- Analog pins A0โA5: Same as Uno
- A6 and A7: Nano-only, analog input only (cannot be used as digital pins)
- 5V, 3.3V, GND, VIN, RESET: All present, same function
- AREF: Available for analog reference voltage
Key point: Any Uno sketch runs on a Nano without code changes. The pins are numbered the same. Only the physical wiring layout changes.
Power Differences
| Feature | Uno | Nano |
|---|---|---|
| Barrel jack | Yes (7โ12V DC) | No |
| VIN pin | Yes | Yes (6.5โ12V recommended) |
| USB power | USB-B (500 mA) | Mini/Micro-USB (500 mA) |
| Total 5V output current | ~800 mA (barrel) / ~500 mA (USB) | ~500 mA (USB) |
| Onboard regulator | AMS1117 (1A capable) | AMS1117 variant (varies by clone) |
The Nano has no barrel jack. For external power, use the VIN pin (accepts 6.5โ12V, regulated down to 5V) or feed regulated 5V directly to the 5V pin.
11.2 USB Drivers: CH340 vs. FTDI
The Driver Problem
Official Arduino Nanos use the FTDI FT232RL USB-to-serial chip. Most affordable clones use the CH340G chip instead. The CH340G requires a separate driver installation on some operating systems.
How to Know Which You Have
Look at the small IC near the USB connector:
- FTDI FT232RL: Square chip, labeled "FT232RL" or "FTDI"
- CH340G: Rectangular chip, labeled "CH340G"
Installing CH340 Drivers
Windows: Usually auto-installs via Windows Update. If not, download from the CH340 manufacturer's website.
macOS: Older macOS versions need a manual driver. macOS 12+ typically includes it. If your Nano isn't recognized, search "CH340 macOS driver" for the current installer.
Linux: CH340 support is built into the kernel since around 2014. Should work automatically.
Troubleshooting USB Connection
| Symptom | Try This |
|---|---|
| No port appears in IDE | Install CH340 driver, try a different cable (data-capable!) |
| Port appears then disappears | Defective clone, try pressing reset during upload |
| Upload fails with sync error | Select "ATmega328P (Old Bootloader)" in Tools โ Processor |
| Upload works but no serial output | Baud rate mismatch, or TX/RX pins used for other purposes |
The Old Bootloader trick: Many Nano clones use an older bootloader. If upload fails with "not in sync," go to Tools โ Processor and select "ATmega328P (Old Bootloader)". This is the single most common Nano issue.
11.3 Soldering Headers
Many Nano boards arrive without headers soldered. You'll need to solder them yourself to use the board with a breadboard.
Tools Needed
| Tool | Purpose |
|---|---|
| Soldering iron (25โ40W) | Melting solder |
| Solder (0.8mm, rosin core, lead-free) | Joining metal |
| Helping hands or PCB holder | Holding the board still |
| Solder wick or solder sucker | Fixing mistakes |
| Flux pen (optional) | Improves solder flow |
Step-by-Step Header Soldering
1. Prepare:
- Insert the header pins into a breadboard (long pins down)
- Place the Nano on top, aligning the holes with the short pins sticking up
- The breadboard holds everything aligned while you solder
2. Tack corners first:
- Solder one corner pin on each side
- Check alignment: the Nano should sit flat and straight
- If crooked, reheat the tacked pin and adjust
3. Solder remaining pins:
- Touch the iron tip to both the pin and the pad simultaneously
- Feed solder into the joint (not onto the iron)
- Hold for 2โ3 seconds; solder should flow around the pin and form a smooth cone
- Move to the next pin
4. Inspect:
- Every joint should be a shiny, smooth cone (not a dull blob)
- No bridges between adjacent pins
- Test every pin with continuity meter
Common Soldering Mistakes
| Mistake | Looks Like | Fix |
|---|---|---|
| Cold joint | Dull, grainy blob | Reheat and add a tiny bit of fresh solder |
| Too much solder | Large ball covering pad | Use solder wick to remove excess |
| Solder bridge | Two adjacent pins connected | Use solder wick between them |
| Lifted pad | Copper pad separated from PCB | Damaged; use a jumper wire to restore connection |
Safety
- Work in a ventilated area; solder fumes are irritating
- Don't touch the iron tip (300ยฐC+)
- Use a stand for the iron when not holding it
- Wash hands after soldering (especially with leaded solder)
- Wear safety glasses; solder can occasionally spit
11.4 Portable Power Options
Battery Options for Nano Projects
| Source | Voltage | Capacity | Connect To | Notes |
|---|---|---|---|---|
| USB power bank | 5V | 5000โ20000 mAh | USB port | Easiest, but may auto-shutoff at low current |
| 3รAA (alkaline) | 4.5V | ~2500 mAh | 5V pin directly | Marginal: works when fresh, fails as voltage drops |
| 4รAA (alkaline) | 6V | ~2500 mAh | VIN pin | Good option, runs through regulator |
| 9V battery | 9V | ~500 mAh | VIN pin | Short runtime; emergency/demo only |
| 18650 Li-ion (with boost converter) | 3.7V โ 5V | 2000โ3500 mAh | 5V pin | Great capacity, needs boost circuit |
| LiPo + TP4056 charger | 3.7V โ 5V (boosted) | varies | 5V pin | Rechargeable, compact |
| 2ร18650 | 7.4V | 2000โ3500 mAh | VIN pin | Through regulator, good runtime |
| CR2032 coin cell | 3V | ~220 mAh | Not recommended for Nano | Too low voltage and current for ATmega328P at 16 MHz |
Power Bank Auto-Shutoff Problem
Many USB power banks detect low current draw and turn off, thinking the device is fully charged. A basic Arduino Nano draws only ~20 mA, below the detection threshold of many power banks.
Solutions:
- Use a power bank that supports low-current mode (check reviews)
- Add a small resistive load (a 100ฮฉ resistor across 5V and GND draws 50 mA, but wastes battery)
- Use a dedicated battery + regulator instead
Calculating Battery Runtime
Runtime (hours) = Battery capacity (mAh) / Current draw (mA)
Example: Nano (20 mA) + OLED (20 mA) + MQ-135 sensor (150 mA) = 190 mA total
With 4รAA batteries (2500 mAh): 2500 / 190 โ 13 hours
With a 2000 mAh 18650 + boost converter (85% efficient): (2000 ร 0.85) / 190 โ 9 hours
Always measure actual current draw with a multimeter rather than relying on datasheet values. Actual consumption often differs from specifications.
11.5 Designing for Enclosures
Planning Before Building
Before you build the circuit, plan the enclosure:
1. Measure everything:
- Board dimensions (Nano: 45 ร 18 mm)
- Component heights (OLED: ~4 mm above board, sensor: varies)
- Cable clearance for USB connector
- Sensor openings (air quality sensors need airflow)
2. Sketch the layout:
- Draw the interior of your enclosure
- Place components to minimize wire length
- Plan where power switch and USB access will be
- Mark where the display faces outward
- Ensure sensor has access to air/light/whatever it measures
3. Access considerations:
- USB port for reprogramming and charging
- Power switch (SPST toggle or slide switch between battery + and VIN)
- Reset button access (or add an external reset button)
- Sensor exposure (don't seal a gas sensor inside an airtight box)
Enclosure Options
| Type | Skill Required | Cost | Best For |
|---|---|---|---|
| Cardboard box | Minimal | Free | Quick prototypes |
| Plastic project box | Low (drill holes) | $2โ5 | Durable prototypes |
| 3D printed | Medium (CAD skills) | $1โ3 filament | Custom fit, professional look |
| Laser-cut acrylic | Medium (vector design) | $5โ10 | Clean look, precise dimensions |
| Altoids tin | Low | $3 | Classic hack, metal = shielding |
Wire Management
- Use short, solid-core wires for internal connections
- Color-code: red = power, black = ground, others = signals
- Add strain relief where wires pass through enclosure walls (hot glue works)
- Leave enough slack to open the enclosure without pulling wires
- Label internal connections if they aren't obvious
Module Project: Portable Air Quality Monitor
Objective
Build a battery-powered portable monitor using the Arduino Nano, MQ-135 gas sensor, DHT22 for temperature/humidity, and SSD1306 OLED display. The finished project should be compact enough to fit in a small enclosure.
Components Needed
| Component | Quantity | Notes |
|---|---|---|
| Arduino Nano | 1 | With soldered headers |
| Mini/Micro USB cable | 1 | For programming |
| Breadboard (half-size) | 1 | Or perfboard for permanent build |
| MQ-135 Air Quality Sensor module | 1 | Detects NH3, NOx, alcohol, benzene, smoke, CO2 |
| DHT22 sensor | 1 | |
| SSD1306 OLED (128ร64, I2C) | 1 | |
| 10kฮฉ Resistor | 1 | DHT22 pull-up |
| 4รAA battery holder | 1 | Connect to VIN and GND |
| AA batteries | 4 | |
| Slide switch (SPST) | 1 | Power on/off |
| Jumper wires | 8+ | Short ones |
Important: MQ-135 Considerations
The MQ-135 contains a heater element that must warm up for accurate readings:
- Warm-up time: 24โ48 hours for initial calibration (seriously), 2โ5 minutes for approximate readings
- Current draw: ~150 mA (most of the power budget!)
- Output: Analog voltage proportional to gas concentration
- Sensitivity: Responds to multiple gases, not specific enough for precise measurement, but good for "air quality index" approximation
Calibration note: The MQ-135 is not a precision instrument. It gives a relative reading ("better" or "worse" air quality), not exact PPM values. For this project, we'll create a relative scale and track changes over time.
Wiring
| Connection | Details |
|---|---|
| Nano A0 | MQ-135 AOUT (analog output) |
| Nano D2 | DHT22 DATA (+ 10kฮฉ pull-up to 5V) |
| Nano A4 | OLED SDA |
| Nano A5 | OLED SCL |
| Nano 5V | DHT22 VCC, OLED VCC |
| Nano VIN | Battery + (through slide switch) |
| Nano GND | All component GNDs, battery โ |
| MQ-135 VCC | Battery + (through slide switch) directly, or Nano 5V |
Power routing: The MQ-135 draws 150 mA, which is significant. On battery power via VIN, the Nano's regulator handles everything. On USB power, ensure total current stays within USB limits.
The Code
/*
* Module 11 Project: Portable Air Quality Monitor
*
* Arduino Nano with:
* - MQ-135 gas sensor โ A0
* - DHT22 โ D2 (10kฮฉ pull-up)
* - SSD1306 OLED โ A4 (SDA), A5 (SCL)
* - Battery powered via VIN (4รAA through switch)
*
* Libraries: Adafruit SSD1306, Adafruit GFX, DHT
* Board: Arduino Nano (ATmega328P or Old Bootloader)
*/
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
// --- Pins ---
const int MQ135_PIN = A0;
const int DHT_PIN = 2;
// --- Sensors ---
DHT dht(DHT_PIN, DHT22);
// --- OLED ---
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// --- Air quality baseline ---
// After warm-up, read the sensor in clean air to set baseline
int airBaseline = 0;
bool baselineSet = false;
const unsigned long WARMUP_TIME = 120000; // 2 minutes (minimum for approximate readings)
// --- Smoothing ---
float smoothedAir = 0;
float smoothedTemp = 0;
float smoothedHumidity = 0;
const float ALPHA = 0.15;
bool firstReading = true;
// --- Timing ---
unsigned long lastSensorRead = 0;
const unsigned long SENSOR_INTERVAL = 2000;
unsigned long lastDisplayUpdate = 0;
const unsigned long DISPLAY_INTERVAL = 500;
// --- History (last 64 readings for graph) ---
int airHistory[64];
int historyIndex = 0;
bool historyFull = false;
// --- Battery voltage monitoring ---
// Read VIN through the voltage divider on the Nano (A7 on some clones)
// This is approximate โ varies by board
void drawProgressBar(int x, int y, int w, int h, int percent, bool invert) {
percent = constrain(percent, 0, 100);
display.drawRect(x, y, w, h, SSD1306_WHITE);
int fillW = (w - 2) * percent / 100;
if (invert) fillW = (w - 2) - fillW;
display.fillRect(x + 1, y + 1, fillW, h - 2, SSD1306_WHITE);
}
String getAirQualityLabel(int reading) {
if (!baselineSet) return "Warming up...";
int diff = reading - airBaseline;
if (diff < 20) return "Good";
else if (diff < 80) return "Moderate";
else if (diff < 150) return "Poor";
else return "Unhealthy";
}
int getAirQualityPercent(int reading) {
if (!baselineSet) return 0;
int diff = reading - airBaseline;
return constrain(map(diff, 0, 300, 100, 0), 0, 100);
}
void drawMiniGraph(int x, int y, int w, int h) {
display.drawRect(x, y, w, h, SSD1306_WHITE);
int count = historyFull ? 64 : historyIndex;
if (count < 2) return;
// Find min/max for scaling
int minVal = 1023, maxVal = 0;
for (int i = 0; i < count; i++) {
if (airHistory[i] < minVal) minVal = airHistory[i];
if (airHistory[i] > maxVal) maxVal = airHistory[i];
}
if (maxVal == minVal) maxVal = minVal + 1;
// Draw points
for (int i = 0; i < count && i < w - 2; i++) {
int idx = historyFull ? (historyIndex + i) % 64 : i;
int py = map(airHistory[idx], minVal, maxVal, y + h - 2, y + 1);
display.drawPixel(x + 1 + i, py, SSD1306_WHITE);
}
}
void updateDisplay() {
display.clearDisplay();
unsigned long now = millis();
// --- Header ---
display.setTextSize(1);
display.setCursor(0, 0);
display.print("Air Monitor");
// Warm-up indicator
if (!baselineSet) {
int warmPercent = constrain(now * 100 / WARMUP_TIME, 0, 100);
display.setCursor(75, 0);
display.print("W:");
display.print(warmPercent);
display.print("%");
}
display.drawLine(0, 9, 127, 9, SSD1306_WHITE);
// --- Air quality ---
display.setTextSize(1);
display.setCursor(0, 12);
display.print("Air: ");
String label = getAirQualityLabel((int)smoothedAir);
display.print(label);
int aqPercent = getAirQualityPercent((int)smoothedAir);
drawProgressBar(0, 22, 80, 7, aqPercent, false);
display.setCursor(84, 22);
display.print((int)smoothedAir);
// --- Temperature & Humidity ---
display.setCursor(0, 33);
display.print("T:");
display.print(smoothedTemp, 1);
display.print("C");
display.setCursor(64, 33);
display.print("H:");
display.print(smoothedHumidity, 0);
display.print("%");
// --- Mini history graph ---
drawMiniGraph(0, 43, 64, 20);
// --- Uptime ---
display.setCursor(70, 55);
unsigned long secs = now / 1000;
char timeStr[10];
sprintf(timeStr, "%02lu:%02lu:%02lu", secs / 3600, (secs % 3600) / 60, secs % 60);
display.print(timeStr);
display.display();
}
void setup() {
Serial.begin(9600);
dht.begin();
// Initialize history
for (int i = 0; i < 64; i++) airHistory[i] = 0;
// OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED not found");
while (1);
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(5, 10);
display.println("Portable Air");
display.println(" Quality Monitor");
display.println();
display.println(" Warming up sensor");
display.println(" Please wait 2 min");
display.display();
Serial.println("Air Quality Monitor โ Module 11");
Serial.println("MQ-135 warming up...");
}
void loop() {
unsigned long now = millis();
// --- Read sensors ---
if (now - lastSensorRead >= SENSOR_INTERVAL) {
lastSensorRead = now;
// Air quality
int airRaw = analogRead(MQ135_PIN);
// DHT22
float t = dht.readTemperature();
float h = dht.readHumidity();
// Smooth
if (firstReading) {
smoothedAir = airRaw;
if (!isnan(t)) smoothedTemp = t;
if (!isnan(h)) smoothedHumidity = h;
firstReading = false;
} else {
smoothedAir = (ALPHA * airRaw) + ((1 - ALPHA) * smoothedAir);
if (!isnan(t)) smoothedTemp = (ALPHA * t) + ((1 - ALPHA) * smoothedTemp);
if (!isnan(h)) smoothedHumidity = (ALPHA * h) + ((1 - ALPHA) * smoothedHumidity);
}
// Set baseline after warm-up
if (!baselineSet && now >= WARMUP_TIME) {
airBaseline = (int)smoothedAir;
baselineSet = true;
Serial.print("Baseline set: ");
Serial.println(airBaseline);
}
// Record history
airHistory[historyIndex] = (int)smoothedAir;
historyIndex = (historyIndex + 1) % 64;
if (historyIndex == 0) historyFull = true;
// Serial CSV output
Serial.print(now / 1000);
Serial.print(",");
Serial.print(airRaw);
Serial.print(",");
Serial.print(smoothedTemp, 1);
Serial.print(",");
Serial.println(smoothedHumidity, 1);
}
// --- Update display ---
if (now - lastDisplayUpdate >= DISPLAY_INTERVAL) {
lastDisplayUpdate = now;
updateDisplay();
}
}
Circuit Diagram (SVG)
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 420" font-family="monospace" font-size="11">
<!-- Nano (small form factor) -->
<rect x="50" y="120" width="100" height="220" fill="#1a6a7a" stroke="#333" stroke-width="2" rx="6"/>
<text x="100" y="148" text-anchor="middle" fill="white" font-size="13" font-weight="bold">Arduino</text>
<text x="100" y="165" text-anchor="middle" fill="white" font-size="12">Nano</text>
<!-- USB -->
<rect x="78" y="110" width="44" height="16" fill="#888" stroke="#333" stroke-width="1.5" rx="3"/>
<text x="100" y="122" text-anchor="middle" font-size="7" fill="white">ยตUSB</text>
<!-- Pins -->
<rect x="150" y="155" width="22" height="12" fill="#2a8a9a" stroke="white" stroke-width="1" rx="2"/>
<text x="161" y="164" text-anchor="middle" fill="white" font-size="7">VIN</text>
<rect x="150" y="173" width="22" height="12" fill="#2a8a9a" stroke="white" stroke-width="1" rx="2"/>
<text x="161" y="182" text-anchor="middle" fill="white" font-size="7">GND</text>
<rect x="150" y="195" width="22" height="12" fill="#2a8a9a" stroke="white" stroke-width="1" rx="2"/>
<text x="161" y="204" text-anchor="middle" fill="white" font-size="7">5V</text>
<rect x="150" y="225" width="22" height="12" fill="#2a8a9a" stroke="white" stroke-width="1" rx="2"/>
<text x="161" y="234" text-anchor="middle" fill="white" font-size="7">A0</text>
<rect x="150" y="250" width="22" height="12" fill="#2a8a9a" stroke="white" stroke-width="1" rx="2"/>
<text x="161" y="259" text-anchor="middle" fill="white" font-size="7">D2</text>
<rect x="150" y="280" width="22" height="12" fill="#2a8a9a" stroke="white" stroke-width="1" rx="2"/>
<text x="161" y="289" text-anchor="middle" fill="white" font-size="7">A4</text>
<rect x="150" y="300" width="22" height="12" fill="#2a8a9a" stroke="white" stroke-width="1" rx="2"/>
<text x="161" y="309" text-anchor="middle" fill="white" font-size="7">A5</text>
<!-- Battery + Switch -->
<rect x="250" y="120" width="90" height="55" fill="#dd9933" stroke="#333" stroke-width="2" rx="6"/>
<text x="295" y="142" text-anchor="middle" fill="white" font-size="10" font-weight="bold">4รAA</text>
<text x="295" y="158" text-anchor="middle" fill="white" font-size="9">6V</text>
<rect x="355" y="132" width="50" height="22" fill="#999" stroke="#333" stroke-width="1.5" rx="4"/>
<text x="380" y="147" text-anchor="middle" font-size="8" fill="white">Switch</text>
<line x1="340" y1="140" x2="355" y2="140" stroke="red" stroke-width="2"/>
<line x1="405" y1="140" x2="440" y2="140" stroke="red" stroke-width="2"/>
<line x1="440" y1="140" x2="440" y2="161" stroke="red" stroke-width="2"/>
<line x1="440" y1="161" x2="172" y2="161" stroke="red" stroke-width="2"/>
<text x="300" y="100" font-size="9" fill="red">Battery + โ Switch โ VIN</text>
<line x1="250" y1="165" x2="250" y2="179" stroke="blue" stroke-width="2"/>
<line x1="250" y1="179" x2="172" y2="179" stroke="blue" stroke-width="2"/>
<!-- MQ-135 -->
<rect x="350" y="210" width="100" height="55" fill="#cc6633" stroke="#333" stroke-width="2" rx="6"/>
<text x="400" y="232" text-anchor="middle" fill="white" font-size="11" font-weight="bold">MQ-135</text>
<text x="400" y="250" text-anchor="middle" fill="white" font-size="8">Air Quality</text>
<text x="400" y="260" text-anchor="middle" fill="#ffaa88" font-size="7">~150 mA!</text>
<line x1="172" y1="231" x2="350" y2="231" stroke="green" stroke-width="1.5"/>
<text x="260" y="226" font-size="8" fill="green">AOUT (A0)</text>
<line x1="172" y1="201" x2="350" y2="220" stroke="red" stroke-width="1"/>
<line x1="172" y1="179" x2="350" y2="255" stroke="blue" stroke-width="1"/>
<!-- DHT22 -->
<rect x="350" y="290" width="100" height="45" fill="#4488aa" stroke="#333" stroke-width="2" rx="6"/>
<text x="400" y="312" text-anchor="middle" fill="white" font-size="10" font-weight="bold">DHT22</text>
<text x="400" y="328" text-anchor="middle" fill="white" font-size="8">Temp+Humidity</text>
<line x1="172" y1="256" x2="350" y2="308" stroke="green" stroke-width="1.5"/>
<text x="260" y="280" font-size="8" fill="green">DATA (D2)</text>
<rect x="280" y="295" width="35" height="12" fill="none" stroke="#333" stroke-width="1" rx="2"/>
<text x="298" y="304" text-anchor="middle" font-size="7">10kฮฉโ</text>
<!-- OLED -->
<rect x="530" y="180" width="130" height="85" fill="#222" stroke="#333" stroke-width="2" rx="6"/>
<rect x="543" y="190" width="104" height="50" fill="#000" stroke="#555" stroke-width="1" rx="3"/>
<text x="595" y="210" text-anchor="middle" fill="#00ccff" font-size="10">Air: Good</text>
<text x="595" y="222" text-anchor="middle" fill="#00ccff" font-size="8">โโโโโโโโโ 78%</text>
<text x="595" y="234" text-anchor="middle" fill="#00ccff" font-size="8">T:23.5 H:52%</text>
<text x="595" y="258" text-anchor="middle" fill="white" font-size="9">SSD1306 OLED</text>
<line x1="172" y1="286" x2="530" y2="220" stroke="#cc8800" stroke-width="1.5"/>
<text x="350" y="252" font-size="8" fill="#cc8800">SDA (A4)</text>
<line x1="172" y1="306" x2="530" y2="240" stroke="#008800" stroke-width="1.5"/>
<text x="350" y="280" font-size="8" fill="#008800">SCL (A5)</text>
<!-- Size comparison -->
<rect x="550" y="310" width="170" height="60" fill="#f8f8f8" stroke="#ccc" stroke-width="1" rx="4"/>
<text x="635" y="330" text-anchor="middle" font-size="10" font-weight="bold">Form Factor</text>
<text x="560" y="348" font-size="8">Nano: 45ร18mm</text>
<text x="560" y="362" font-size="8">Fits half-size breadboard</text>
</svg>
Circuit Schema (JSON)
{
"module": 11,
"project": "Portable Air Quality Monitor",
"board": "Arduino Nano",
"schematic": {
"components": [
{
"id": "U1", "type": "arduino_nano",
"pins_used": {
"VIN": "net_vin", "GND": "net_gnd", "5V": "net_5v",
"A0": "net_mq_aout", "D2": "net_dht_data",
"A4": "net_sda", "A5": "net_scl"
}
},
{ "id": "BAT1", "type": "battery_pack", "value": "6V", "description": "4รAA",
"pins": { "positive": "net_bat_pos", "negative": "net_gnd" } },
{ "id": "SW1", "type": "spst_switch", "purpose": "Power on/off",
"pins": { "pin1": "net_bat_pos", "pin2": "net_vin" } },
{ "id": "MQ1", "type": "mq135", "current_draw": "150mA", "warmup": "2-5 min approximate",
"pins": { "vcc": "net_5v", "gnd": "net_gnd", "aout": "net_mq_aout" } },
{ "id": "DHT1", "type": "dht22",
"pins": { "vcc": "net_5v", "data": "net_dht_data", "gnd": "net_gnd" } },
{ "id": "R1", "type": "resistor", "value": "10000", "unit": "ohm",
"purpose": "DHT22 data pull-up",
"pins": { "pin1": "net_5v", "pin2": "net_dht_data" } },
{ "id": "OLED1", "type": "ssd1306", "address": "0x3C",
"pins": { "vcc": "net_5v", "gnd": "net_gnd", "sda": "net_sda", "scl": "net_scl" } }
],
"nets": [
{ "name": "net_gnd", "nodes": ["U1.GND", "BAT1.negative", "MQ1.gnd", "DHT1.gnd", "OLED1.gnd"] },
{ "name": "net_vin", "nodes": ["U1.VIN", "SW1.pin2"] },
{ "name": "net_bat_pos", "nodes": ["BAT1.positive", "SW1.pin1"] },
{ "name": "net_5v", "nodes": ["U1.5V", "MQ1.vcc", "DHT1.vcc", "R1.pin1", "OLED1.vcc"] },
{ "name": "net_mq_aout", "nodes": ["U1.A0", "MQ1.aout"] },
{ "name": "net_dht_data", "nodes": ["U1.D2", "DHT1.data", "R1.pin2"] },
{ "name": "net_sda", "nodes": ["U1.A4", "OLED1.sda"] },
{ "name": "net_scl", "nodes": ["U1.A5", "OLED1.scl"] }
],
"power": {
"source": "4รAA via VIN (6V, regulated to 5V internally)",
"total_current_ma": 193,
"breakdown": "Nano(23) + MQ-135(150) + DHT22(2.5) + OLED(17.5)",
"estimated_runtime": "~13 hours on 2500mAh AA batteries"
}
},
"code": { "filename": "module11_air_monitor.ino", "language": "cpp" },
"validation": {
"expected_behavior": "OLED shows air quality level with bar and history graph, temp, humidity. MQ-135 warms up for 2 min, then sets baseline.",
"common_mistakes": [
"Upload fails: select 'ATmega328P (Old Bootloader)' in Tools โ Processor",
"No port appears: install CH340 driver for your OS",
"MQ-135 reads constant 0 or 1023: sensor not powered, or AOUT not connected to A0",
"Air readings never change: sensor hasn't warmed up yet (needs 2+ minutes minimum)",
"Battery dies fast: MQ-135 draws 150mA โ calculated runtime is correct, consider larger battery",
"Power bank keeps shutting off: current draw may be too low during idle periods"
]
}
}
Self-Check: Module 11
Before moving to Module 12, make sure you can:
- Explain the key differences and similarities between Nano and Uno
- Install CH340 drivers and resolve the "Old Bootloader" upload issue
- Solder header pins onto a Nano (clean, cone-shaped joints, no bridges)
- Choose an appropriate battery for a given project's power needs
- Calculate expected battery runtime from component current draws
- Plan a compact layout suitable for an enclosure
- Build the portable air quality monitor with battery power and display
Key Terms Glossary
| Term | Definition |
|---|---|
| Arduino Nano | Compact ATmega328P board (45ร18mm) that plugs directly into a breadboard |
| CH340G | Common USB-to-serial chip on Nano clones. May require driver installation |
| FTDI FT232RL | USB-to-serial chip on official Nanos. Drivers included in most OSes |
| Old Bootloader | Legacy bootloader on many Nano clones. Requires different upload timing |
| VIN | Voltage Input pin. Accepts 6.5โ12V, feeds the onboard regulator |
| Soldering | Joining metal with melted solder alloy to create electrical connections |
| Cold joint | A failed solder joint. Dull, grainy appearance, unreliable connection |
| Solder bridge | Unintended solder connection between two adjacent pins or pads |
| Strain relief | Securing a wire where it enters an enclosure to prevent breakage from movement |
| MQ-135 | Gas sensor for air quality monitoring. Detects multiple gases |
| Baseline | A reference reading taken in known conditions for comparison |
| Boost converter | Switching regulator that increases voltage (e.g., 3.7V โ 5V) |
Previous: โ Module 10: Motors & Movement Next: Module 12: Troubleshooting & Debugging: The Essential Skill โ