R2-D2 beeps softly, as if this is a deeply personal topic.
LUKE: "Today we give him that. The sensor eye. And this timeβ" he gestures at the screen "βCodey's going to show us something called Auto Error Fixing. Because I have a feeling we're going to need it."
From somewhere unseen, a voice floats through the Force.
VADER: "Your lack of a level-shifted data pin... disturbs me."
LUKE: "We're on 5V. We'll be fine."
ποΈ SIPOC β The Sensor Eye System
| Suppliers |
Inputs |
Process |
Outputs |
Customers |
| You (the maker) |
"Add HC-SR04 on pins 9/10 and PIR on pin 2, react with beeps and dome color changes" |
Codey writes sensor code, integrates with sound and dome systems from previous episodes |
Unified firmware: sense β respond with light + sound |
R2-D2 β who now reacts to the world around him |
| HC-SR04 Sensor |
5V power, TRIG pulse from Arduino |
Emits ultrasonic pulse, measures return echo time |
Distance in centimetres |
The code β which decides how close is "too close" |
| PIR Motion Sensor |
5V power, GPIO input to Arduino |
Digital HIGH when motion detected |
A HIGH signal on the interrupt pin |
The code β which triggers the alert sequence |
| Auto Error Fixing |
A compilation error from incorrect code |
Codey reads the error log, rewrites the offending lines, recompiles |
Fixed code that compiles successfully |
You β who get working firmware without decoding C++ error messages |
| Vision Feature |
A photo of your breadboard |
Codey reads the image and identifies component placement |
A verification report: "Wiring looks correct" or specific mismatches |
You β who confirm wiring before upload |
The Components π§
C-3PO enters with a tray of precisely arranged components.
C-3PO: "Today we add perception to R2-D2's capabilities. The HC-SR04 ultrasonic sensor β which I should note operates at 5V and is therefore perfectly compatible with the Arduino UNO without any level shifting, which is a relief β and the HC-SR501 PIR motion sensor, also 5V compatible. I have pre-sorted them by height to prevent any confusion."
R2-D2 beeps something that sounds like "nobody asked you to sort them."
| Component |
Quantity |
Notes |
| Arduino UNO R3 |
1 |
Our trusted base |
| HC-SR04 ultrasonic sensor |
1 |
5V, TRIG + ECHO pins |
| HC-SR501 PIR sensor |
1 |
5V, single digital output |
| 10kΞ© resistor |
1 |
PIR output pull-down (some modules need it) |
| Jumper wires |
6 |
| USB cable |
1 |
Plus the buzzer from Episode 2 and NeoPixel ring from Episode 3 β we are building on the complete system.
The Codey Prompt β Building on What We Have π¬
Han Solo points at the screen.
HAN: "Here's the thing about AI coding tools β you don't start from scratch every time. You tell it what already exists and what you want to add. Context is everything. Same in the smuggling business."
LUKE: "You're comparing Codey to smuggling?"
HAN: "I'm saying context matters. Do you want the lecture or the sensor?"
Open your Codey project (from Episode 3 milestone). In Agent mode:
We're continuing the R2-D2 build from the previous episodes.
Existing systems:
- Piezo buzzer on pin 8 (tone-based sounds)
- NeoPixel ring (12 LEDs) on pin 6 (dome animations)
Add these sensor systems:
1. HC-SR04 ultrasonic sensor
- TRIG on pin 9, ECHO on pin 10
- Measure distance every 150ms (non-blocking)
- If distance < 30cm: trigger alert animation + alert sound
- If distance < 15cm: trigger full RED dome + rapid alert beeps
2. PIR motion sensor on pin 2 (interrupt-capable)
- On motion detected: trigger scan animation for 3 seconds
- Then return to idle
Extend animations.h with these reactive behaviors.
Keep the state machine approach.
Use millis() everywhere β no delay().
Generated Code Addition to animations.h
// ββ Sensor additions (append to animations.h) βββββββββββββββββββ
// ββ HC-SR04 βββββββββββββββββββββββββββββββββββββββββββββββββββββ
#define TRIG_PIN 9
#define ECHO_PIN 10
unsigned long lastSonarMs = 0;
float lastDistance = 999.0f;
float readDistance() {
// Non-blocking: only trigger if enough time has passed
unsigned long now = millis();
if (now - lastSonarMs < 150) return lastDistance;
lastSonarMs = now;
// Send 10ΞΌs TRIG pulse
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Read echo duration (timeout 30ms = ~5m max range)
long duration = pulseIn(ECHO_PIN, HIGH, 30000UL);
if (duration == 0) return 999.0f;
// Convert to centimetres
lastDistance = (duration * 0.0343f) / 2.0f;
return lastDistance;
}
// ββ PIR Motion Sensor ββββββββββββββββββββββββββββββββββββββββββββ
#define PIR_PIN 2
volatile bool motionDetected = false;
void IRAM_ATTR onMotion() {
motionDetected = true;
}
// ββ Reactive behaviour in updateAnimations() βββββββββββββββββββββ
// (replaces/extends the existing updateAnimations function)
void updateAnimationsSensors() {
unsigned long now = millis();
// ββ Check PIR first (interrupt-driven, higher priority) βββββ
if (motionDetected) {
motionDetected = false;
currentState = SCAN;
stateStartMs = now;
Serial.println("Motion detected β scan mode!");
}
// ββ Check HC-SR04 distance βββββββββββββββββββββββββββββββββ
float dist = readDistance();
if (dist < 15.0f) {
// Very close β full red alert
if (currentState != ALERT) {
currentState = ALERT;
stateStartMs = now;
tone(BUZZER_PIN, 2637); // C6 β high alert tone
}
// Override: set all LEDs red while this close
for (int i = 0; i < NUMPIXELS; i++) {
ring.setPixelColor(i, ring.Color(BRIGHTNESS, 0, 0));
}
ring.show();
return;
} else if (dist < 30.0f) {
// Approaching β amber warning
if (currentState == IDLE) {
currentState = ALERT;
stateStartMs = now;
}
} else {
noTone(BUZZER_PIN); // Silence if moved away
}
// ββ Normal state machine ββββββββββββββββββββββββββββββββββββ
updateAnimations(); // existing function handles the rest
}
Updated r2d2-dome.ino
// r2d2-dome.ino β updated for sensor eye
#include <Adafruit_NeoPixel.h>
#include "animations.h"
void setup() {
Serial.begin(9600);
initAnimations();
// Sensor pins
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(PIR_PIN, INPUT);
// PIR interrupt β fires on rising edge (motion start)
attachInterrupt(digitalPinToInterrupt(PIR_PIN), onMotion, RISING);
Serial.println("R2-D2 sensor eye online!");
}
void loop() {
updateAnimationsSensors(); // new unified call
}
Auto Error Fixing in Action π οΈ
And then it happens.
LUKE: "I tried to compile andβ"
Compilation Error:
animations.h:47: error: 'IRAM_ATTR' was not declared in this scope
animations.h:47: note: 'IRAM_ATTR' is an ESP32 attribute, not available on AVR
LUKE: "What does that mean? I justβ"
Before Luke can panic, the screen updates automatically.
CODEY AUTO ERROR FIX:
I see the error! IRAM_ATTR is an ESP32-specific macro for placing
interrupt handlers in IRAM (fast memory). The Arduino UNO uses
an ATmega328P β it doesn't have IRAM at all.
For Arduino UNO, the interrupt handler just needs the ISR() attribute,
which I used in the function signature. I'll remove IRAM_ATTR.
Fixed:
Before: void IRAM_ATTR onMotion() {
After: void onMotion() {
Recompiling...
β Compilation successful (after auto-fix)
Board: Arduino UNO R3
Sketch: r2d2-dome.ino + animations.h
Size: 9,104 bytes (28% of flash)
LUKE: "It... fixed it. By itself."
HAN: "Never tell me the odds."
LUKE: "That's not the sameβ"
HAN: "The AI fixed its own mistake without you having to understand why. That's what matters."
The Wiring Diagram β Three Systems Now π§
Click Wiring Diagram. The diagram now shows all three systems:
R2-D2 Sensor Eye + Dome + Sound β Wiring Diagram
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[Arduino UNO R3]
POWER RAIL:
5V ββββββββββ¬ββ NeoPixel 5V
βββ HC-SR04 VCC
βββ PIR Sensor VCC
βββ (100ΞΌF cap +)
GND ββββββββββ¬ββ NeoPixel GND
βββ HC-SR04 GND
βββ PIR Sensor GND
βββ (100ΞΌF cap β)
SIGNALS:
Pin 6 ββββ (470Ξ©) ββββ NeoPixel DIN
Pin 8 ββββ (100Ξ©) ββββ Piezo Buzzer +
Pin 9 βββββββββββββββ HC-SR04 TRIG
Pin 10 βββββββββββββββ HC-SR04 ECHO
Pin 2 βββββββββββββββ PIR Sensor OUT
Color code:
RED = 5V / power rail
BLACK = GND rail
GREEN = NeoPixel data (pin 6)
ORANGE = Buzzer signal (pin 8)
BLUE = HC-SR04 TRIG (pin 9)
PURPLE = HC-SR04 ECHO (pin 10)
YELLOW = PIR output (pin 2)
GREY = Through resistors
Connection Table:
ββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ
β From β To β
ββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββ€
β Arduino 5V β NeoPixel Ring: 5V β
β Arduino 5V β HC-SR04: VCC β
β Arduino 5V β PIR HC-SR501: VCC β
β Arduino 5V β 100ΞΌF Cap: + (long leg) β
β Arduino GND β NeoPixel Ring: GND β
β Arduino GND β HC-SR04: GND β
β Arduino GND β PIR HC-SR501: GND β
β Arduino GND β 100ΞΌF Cap: β (short leg) β
β Arduino Pin 6 β Resistor 470Ξ© β NeoPixel DIN β
β Arduino Pin 8 β Resistor 100Ξ© β Piezo (+) β
β Arduino Pin 9 β HC-SR04: TRIG β
β Arduino Pin 10 β HC-SR04: ECHO β
β Arduino Pin 2 β PIR HC-SR501: OUT β
ββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββ
C-3PO: "Seven signals on eight wires plus the power rail. The color-coded system makes it genuinely manageable. Download the PDF immediately β this is the most complex wiring diagram we have produced so far and I do not trust organic memory."
Vision Feature: "Is My Breadboard Wired Correctly?" ποΈ
Luke takes a photo of his assembled breadboard.
LUKE: "Before I upload β can I check this with Codey? Just to be sure?"
Click the Vision icon in Codey (Pro feature). Upload the breadboard photo.
Codey responds:
I can see your breadboard. Here's what I observe:
β HC-SR04 ultrasonic sensor connected:
- VCC to 5V rail β correct
- GND to GND rail β correct
- TRIG appears connected to the digital pin area (looks like pin 9) β correct
- ECHO appears connected to pin 10 β correct
β PIR sensor:
- VCC and GND connections look correct
- Signal wire appears to go to pin 2 β correct
β οΈ One potential issue:
I notice what looks like the NeoPixel data wire may not have the
470Ξ© resistor in line β it appears to connect directly. Check that
the resistor is seated in the breadboard between pin 6 and the DIN
input. A direct connection may cause LED flickering or data errors.
Everything else looks correctly laid out!
Luke examines the breadboard.
LUKE: "The resistor... it's in the wrong row. It's not actually connected to anything."
R2-D2 beeps in the tone of "I could have told you that."
LUKE: "Vision just saved R2's dome lights."
What's Next: The Holographic Projector π½οΈ
Obi-Wan's presence fills the workshop like warm light.
OBI-WAN: "You have given R2-D2 his lights. His sounds. His sense of the world around him. But the moment that first made the galaxy fall in love with this droid β do you remember it, Luke?"
LUKE: "Help me, Obi-Wan Kenobi. You're my only hope."
OBI-WAN: "In Episode 5, we give Artoo his projector. The SSD1306 OLED display β small, crisp, I2C wired β will show R2's status, messages, and a recreation of that famous message. Milestones and Rollback will save us if anything goes wrong."
R2-D2 beeps the opening notes of the Princess Leia theme.
π Resources
-
HC-SR04 with Arduino: Search "HC-SR04 Arduino tutorial"
-
PIR HC-SR501: Search "HC-SR501 Arduino interrupt"
-
Codey Online Vision: codey.online β Pro feature
-
Auto Error Fixing: built into all Codey plans
π€ R2D2 Creation with Codey β building the galaxy's greatest droid, one episode at a time. May the Force β and the cloud compiler β be with you.