DEV Community

Cover image for R2D2 Creation with Codey ๐Ÿค– Ep.5

R2D2 Creation with Codey ๐Ÿค– Ep.5

Episode 5: The Projector of Hope

"Help Me, Codey Online โ€” You're My Only Hope" ๐Ÿ“ฝ๏ธ

The workshop is quiet. R2-D2 sits in the corner, dome LEDs softly breathing their blue-white rhythm. Then, suddenly โ€” a holographic projection flickers from somewhere inside his chassis. Princess Leia. Eighteen centimetres tall. Looping silently.

Luke stares.

LUKE: "That's what I want. That's exactly what I want. An OLED screen mounted in his dome, showing status messages, projecting text like a mission briefing. Something that makes him feel... alive."

R2-D2 beeps with the energy of someone who has been waiting patiently for this episode.

LUKE: "But Obi-Wan said something about upgrading the brain first. Moving to a bigger board."

Obi-Wan's voice arrives like dawn.

OBI-WAN: "The Arduino UNO served us well through four episodes, young one. But what lies ahead โ€” the motion systems, the voice responses, the wireless capabilities โ€” these require a more powerful foundation. It is time to meet the ESP32-S3 N16R8."

๐Ÿ—‚๏ธ SIPOC โ€” The Great Upgrade

Suppliers Inputs Process Outputs Customers
You (the maker) "Migrate to ESP32-S3 N16R8 and add SSD1306 OLED via I2C" Codey recognises the new board, updates pin mappings, rewrites I2C addresses, flags 3.3V implications Correct ESP32-S3 firmware with Adafruit_SSD1306, new I2C pins ESP32-S3 N16R8 โ€” which drives the OLED and all previous systems
Codey Voltage Safety Check NeoPixel (5V logic), OLED (3.3V or 5V), HC-SR04 (5V) vs ESP32-S3 (3.3V GPIO) Cross-references component voltage requirements with ESP32-S3 GPIO levels Specific warnings per component + recommended level shifter or workarounds You โ€” who avoid smoke on this far more expensive board
SSD1306 OLED (128ร—64) 3.3V power, I2C (SDA/SCL) Receives display commands over I2C protocol A crisp 128ร—64 pixel display showing R2 status and messages R2-D2's dome โ€” the holographic projection system
Milestones & Rollback Previous working code at Episode 4 milestone One-click restore of code + chat history Known-good state if the board migration causes issues You โ€” who can always go back

Meet the New Brain: ESP32-S3 N16R8 ๐Ÿง 

C-3PO emerges carrying a padded case like it contains the Holy Grail.

C-3PO: "The ESP32-S3 N16R8. I have computed its specifications forty-seven times. Allow me to translate from technical to comprehensible:"

Feature ESP32-S3 N16R8 Arduino UNO R3
Processor Dual-core Xtensa LX7 @ 240 MHz Single-core ATmega328P @ 16 MHz
Flash storage 16 MB 32 KB
PSRAM 8 MB 0
GPIO pins 45 14 digital
Logic voltage 3.3V 5V
Wi-Fi Yes (802.11b/g/n) No
Bluetooth Yes (BLE 5.0 + Classic) No
USB Native USB-CDC (two ports!) USB via CH340/FTDI chip
PWM LEDC โ€” 8 channels, 14-bit resolution 6 PWM pins, 8-bit
DAC 2ร— 8-bit DAC outputs None

C-3PO: "Considerably more capable. However โ€” and I cannot stress this strongly enough โ€” the GPIO outputs are 3.3V, not 5V. Several of our existing components expect a 5V signal. This is a matter of the gravest concern and I intend to address each one individually."

R2-D2 beeps impatiently.

C-3PO: "Artoo, voltage compatibility is NOT a detail. It is the difference between a functional droid and a very expensive doorstop."

The 3.3V Migration: C-3PO's Component Review โšก

Darth Vader's voice rumbles through the ventilation system.

VADER: "Your lack of a level shifter... disturbs me."

C-3PO whirls around, then remembers where he is.

C-3PO: "Quite. Let us review each component's voltage situation with the ESP32-S3:"

Component Voltage Compatibility Table

Component VCC Needed Signal Level Needed ESP32-S3 GPIO (3.3V) Action Required
SSD1306 OLED 3.3V or 5V 3.3V I2C โœ… Compatible None โ€” OLED runs perfectly on 3.3V
Piezo Buzzer 3.3Vโ€“5V 3.3V PWM โœ… Compatible None โ€” works fine at 3.3V
NeoPixel WS2812B 5V 5V data signal โš ๏ธ Marginal Add 74AHCT125 level shifter OR use 470ฮฉ + 3V3-to-5V shifter
HC-SR04 5V 5V ECHO output โš ๏ธ Risky The ECHO pin outputs 5V โ€” use voltage divider on ECHO
PIR HC-SR501 5V 5V output โš ๏ธ Risky Use voltage divider (10k + 20k) on output pin

C-3PO: "Codey will generate the level shifter and voltage divider circuits in the wiring diagram. This is precisely the scenario for which Codey's voltage safety checks were designed."

Codey, upon seeing the ESP32-S3 selected, automatically adds voltage warnings for each incompatible component in the project.

Selecting the New Board in Codey ๐Ÿ”„

Han Solo demonstrates with the casual confidence of someone who has hot-swapped ship components mid-jump.

HAN: "Simple. In your Codey project, click the board selector at the top. Change it from Arduino UNO R3 to ESP32-S3 N16R8. Done. Codey figures out the rest."

  1. Click the board name dropdown at the top of the Codey interface
  2. Select ESP32-S3 N16R8
  3. Codey immediately shows:
โš ๏ธ  Board changed: Arduino UNO R3 โ†’ ESP32-S3 N16R8

This board uses 3.3V GPIO logic.
I've detected components in your project that may be affected:

  โ€ข NeoPixel WS2812B (pin 6): Needs level shifter โ€” see updated wiring diagram
  โ€ข HC-SR04 (pins 9/10): ECHO pin outputs 5V โ€” needs voltage divider
  โ€ข PIR HC-SR501 (pin 2): Output is 5V โ€” needs voltage divider

  Recommended: Add 74AHCT125 (quad level shifter) for WS2812B data line.
  Piezo buzzer (pin 8): โœ“ Compatible โ€” no change needed.

Shall I update the code and wiring diagram for the ESP32-S3?

Enter fullscreen mode Exit fullscreen mode

R2-D2 beeps enthusiastically: "YES."

HAN: "See? It flags everything. No surprises."

Before Moving On: Rolling Back If Needed ๐Ÿšฉ

Obi-Wan raises a steady hand.

OBI-WAN: "Before this migration, let us invoke the wisdom of Milestones. Our Episode 4 code runs perfectly on the Arduino UNO. If the ESP32-S3 migration encounters difficulty, we must be able to return to that known-good state."

In Codey, click Milestones โ†’ find "R2-D2 Sensor Eye โ€” Episode 4 Complete" โ†’ click Restore.

Both the code AND the chat history are restored to exactly how they were after Episode 4.

Now make a new milestone before starting the migration:

Milestone: "Pre-ESP32 Migration Checkpoint"

Enter fullscreen mode Exit fullscreen mode

OBI-WAN: "The Force gives you wisdom to try. The Milestone gives you the courage to try boldly."

R2-D2 beeps something along the lines of "can we please just look at the OLED already."

Prompting Codey for the ESP32-S3 Migration + OLED ๐Ÿ’ฌ

In Plan mode first:

We're upgrading R2-D2's brain from Arduino UNO R3 to ESP32-S3 N16R8.

Existing systems to migrate:
  - Piezo buzzer on pin 8 โ†’ keep same pin, use LEDC channel instead of tone()
  - NeoPixel ring (12 LEDs) on pin 6 โ†’ keep pin, add note about 74AHCT125
  - HC-SR04 on pins 9/10 โ†’ keep pins, add voltage divider on ECHO
  - PIR sensor on pin 2 โ†’ keep pin, add voltage divider on output

New addition:
  - SSD1306 OLED 128x64 display via I2C
  - ESP32-S3 I2C default: SDA=GPIO8, SCL=GPIO9
  - Show these screens:
    1. Startup: "R2-D2 ONLINE" with a spinning animation
    2. Idle: distance reading + "SAFE" or "ALERT"
    3. Motion: "MOTION DETECTED" with exclamation marks
    4. Very close: "TOO CLOSE" with a blinking border

Show me the plan before writing any code.

Enter fullscreen mode Exit fullscreen mode

Codey Plan Mode Response

R2-D2 ESP32-S3 Migration + Holographic Projector โ€” Plan

FILES:
  r2d2-main.ino     โ€” setup() and loop(), board init
  animations.h      โ€” NeoPixel dome animations (migrated to ESP32)
  sensors.h         โ€” HC-SR04 + PIR (voltage divider notes)
  display.h         โ€” SSD1306 OLED functions (new)
  sounds.h          โ€” LEDC-based tone functions (replaces tone() API)

KEY CHANGES:
  1. tone() โ†’ ledc functions (ESP32 uses LEDC peripheral for PWM)
     ledcSetup(0, 2637, 8) + ledcWrite(0, 128) replaces tone(pin, freq)

  2. I2C on ESP32-S3: Wire.begin(8, 9) for SDA=GPIO8, SCL=GPIO9
     (Adafruit_SSD1306 uses Wire automatically)

  3. NeoPixel: Same FastLED/NeoPixel API โ€” ESP32-S3 natively supports
     RMT peripheral for WS2812B. Add 74AHCT125 recommendation in wiring.

  4. HC-SR04 ECHO: Add voltage divider (10kฮฉ + 20kฮฉ) to reduce 5Vโ†’3.3V
     TRIG output from ESP32-S3 (3.3V) is sufficient to trigger HC-SR04.

  5. PIR output: Add voltage divider (10kฮฉ + 20kฮฉ)

  DISPLAY STATES:
    โ€ข BOOT  โ€” "R2-D2 ONLINE", spinner, 2 seconds
    โ€ข IDLE  โ€” Distance + status, updates every 500ms
    โ€ข SCAN  โ€” "MOTION DETECTED !!", large text
    โ€ข ALERT โ€” "TOO CLOSE" with animated blinking border

Proceed?

Enter fullscreen mode Exit fullscreen mode

Click Proceed. Codey writes all five files.

Generated display.h

// display.h โ€” R2-D2 Holographic Projector
// SSD1306 OLED 128x64 via I2C
// ESP32-S3: SDA=GPIO8, SCL=GPIO9

#pragma once
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH  128
#define SCREEN_HEIGHT  64
#define OLED_ADDR     0x3C   // Default I2C address for SSD1306

// OLED_RESET = -1 means share the Arduino reset pin (or no reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

bool displayReady = false;

// โ”€โ”€ Boot animation โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const char* spinFrames[] = {"|", "/", "-", "\\"};
int spinIdx = 0;
unsigned long lastSpinMs = 0;
unsigned long bootStartMs = 0;
bool bootDone = false;

void initDisplay() {
  // ESP32-S3 I2C: SDA=GPIO8, SCL=GPIO9
  Wire.begin(8, 9);

  if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
    Serial.println("SSD1306 not found โ€” check wiring!");
    return;
  }

  displayReady = true;
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  bootStartMs = millis();
  Serial.println("OLED projector online!");
}

void showBootScreen() {
  if (!displayReady || bootDone) return;

  unsigned long now = millis();

  if (now - lastSpinMs > 150) {
    lastSpinMs = now;
    spinIdx = (spinIdx + 1) % 4;

    display.clearDisplay();

    // Title โ€” large text centred
    display.setTextSize(2);
    display.setCursor(4, 8);
    display.println("R2-D2");
    display.setCursor(4, 28);
    display.println("ONLINE");

    // Spinner bottom right
    display.setTextSize(2);
    display.setCursor(112, 48);
    display.print(spinFrames[spinIdx]);

    display.display();
  }

  if (now - bootStartMs > 2500) {
    bootDone = true;
  }
}

// โ”€โ”€ Idle screen: distance + status โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
unsigned long lastIdleRefreshMs = 0;

void showIdleScreen(float distance) {
  if (!displayReady) return;

  unsigned long now = millis();
  if (now - lastIdleRefreshMs < 500) return;
  lastIdleRefreshMs = now;

  display.clearDisplay();

  // Distance reading
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("DISTANCE:");

  display.setTextSize(2);
  display.setCursor(0, 12);
  if (distance < 500.0f) {
    display.print((int)distance);
    display.print(" cm");
  } else {
    display.print("--- cm");
  }

  // Status label
  display.setTextSize(1);
  display.setCursor(0, 48);
  if (distance < 15.0f) {
    display.print("!! TOO CLOSE !!");
  } else if (distance < 30.0f) {
    display.print("CAUTION");
  } else {
    display.print("SAFE");
  }

  display.display();
}

// โ”€โ”€ Motion detected screen โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
void showMotionScreen() {
  if (!displayReady) return;

  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0, 8);
  display.println("MOTION");
  display.setCursor(0, 28);
  display.println("DETECTED");
  display.setTextSize(3);
  display.setCursor(96, 28);
  display.print("!!");
  display.display();
}

// โ”€โ”€ Alert: blinking border + TOO CLOSE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
bool borderVisible = true;
unsigned long lastBorderFlipMs = 0;

void showAlertScreen() {
  if (!displayReady) return;

  unsigned long now = millis();
  if (now - lastBorderFlipMs > 300) {
    lastBorderFlipMs = now;
    borderVisible = !borderVisible;
  }

  display.clearDisplay();

  if (borderVisible) {
    display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
    display.drawRect(2, 2, 124, 60, SSD1306_WHITE);
  }

  display.setTextSize(2);
  display.setCursor(8, 16);
  display.println("TOO");
  display.setCursor(8, 36);
  display.println("CLOSE!");
  display.display();
}

Enter fullscreen mode Exit fullscreen mode

Generated sounds.h (ESP32 LEDC version)

// sounds.h โ€” R2-D2 Sound System (ESP32-S3 LEDC)
// Replaces Arduino tone() with ESP32 LEDC peripheral

#pragma once

#define BUZZER_PIN    8    // GPIO8 on ESP32-S3
#define LEDC_CHANNEL  0
#define LEDC_TIMER    8    // 8-bit resolution

bool ledcReady = false;

void initSounds() {
  // Configure LEDC channel for buzzer
  ledcSetup(LEDC_CHANNEL, 1000, LEDC_TIMER);
  ledcAttachPin(BUZZER_PIN, LEDC_CHANNEL);
  ledcWrite(LEDC_CHANNEL, 0); // silent
  ledcReady = true;
}

void playTone(int frequency) {
  if (!ledcReady || frequency <= 0) {
    ledcWrite(LEDC_CHANNEL, 0);
    return;
  }
  ledcWriteTone(LEDC_CHANNEL, frequency);
  ledcWrite(LEDC_CHANNEL, 128); // 50% duty cycle
}

void stopTone() {
  ledcWrite(LEDC_CHANNEL, 0);
}

Enter fullscreen mode Exit fullscreen mode

Generated r2d2-main.ino (ESP32-S3 version)

// r2d2-main.ino โ€” R2-D2 ESP32-S3 N16R8
// Unifying all systems: sounds, dome lights, sensors, display

#include <Adafruit_NeoPixel.h>
#include "sounds.h"
#include "animations.h"
#include "sensors.h"
#include "display.h"

void setup() {
  Serial.begin(115200);
  Serial.println("R2-D2 ESP32-S3 boot sequence...");

  initSounds();
  initAnimations();   // NeoPixel dome
  initSensors();      // HC-SR04 + PIR
  initDisplay();      // SSD1306 OLED

  Serial.println("All systems nominal. R2-D2 is ONLINE.");
}

void loop() {
  // Boot animation runs first
  if (!bootDone) {
    showBootScreen();
    return;
  }

  // Read sensors
  float dist    = readDistance();
  bool  motion  = checkMotion();

  // Update display based on state
  if (dist < 15.0f) {
    showAlertScreen();
  } else if (motion) {
    showMotionScreen();
  } else {
    showIdleScreen(dist);
  }

  // Update dome animations (non-blocking)
  updateAnimationsSensors(dist, motion);
}

Enter fullscreen mode Exit fullscreen mode

The Wiring Diagram โ€” ESP32-S3 Edition ๐Ÿงญ

C-3PO straightens to his full height, relieved.

C-3PO: "Codey has drawn the wiring diagram. I have checked it. It includes the voltage dividers. It includes the level shifter recommendation. It is correct. I am, for the first time this episode, not worried."

R2-D2 Holographic System โ€” ESP32-S3 N16R8 Wiring
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

[ESP32-S3 N16R8]

  POWER RAIL (3.3V):
    3V3  โ”€โ”€โ”€โ”ฌโ”€โ”€ OLED VCC (3.3V input)
            โ””โ”€โ”€ (100ยตF cap +)
    GND  โ”€โ”€โ”€โ”ฌโ”€โ”€ OLED GND
            โ””โ”€โ”€ (100ยตF cap โˆ’)

  POWER RAIL (5V via USB):
    VIN  โ”€โ”€โ”€โ”ฌโ”€โ”€ NeoPixel Ring: 5V
            โ”œโ”€โ”€ HC-SR04: VCC
            โ””โ”€โ”€ PIR HC-SR501: VCC
    GND  โ”€โ”€โ”€โ”ฌโ”€โ”€ NeoPixel Ring: GND
            โ”œโ”€โ”€ HC-SR04: GND
            โ””โ”€โ”€ PIR HC-SR501: GND

  I2C BUS (3.3V โ€” OLED compatible):
    GPIO8 (SDA) โ”€โ”€โ”€โ”€ OLED SDA
    GPIO9 (SCL) โ”€โ”€โ”€โ”€ OLED SCL

  SIGNALS with PROTECTION:
    GPIO6  โ”€โ”€โ”€โ”€ [74AHCT125 level shifter] โ”€โ”€โ”€โ”€ NeoPixel DIN (5V)
    GPIO8  โ”€โ”€โ”€โ”€ (100ฮฉ) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Piezo Buzzer +
    GPIO9  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ HC-SR04 TRIG
    GPIO10 โ”€โ”€โ”€โ”€ [10kฮฉ / 20kฮฉ divider] โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ HC-SR04 ECHO
    GPIO2  โ”€โ”€โ”€โ”€ [10kฮฉ / 20kฮฉ divider] โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ PIR OUT

Voltage Dividers for 5V โ†’ 3.3V:
  GPIO_pin โ†โ”€โ”€ (junction) โ”€โ”€โ”€ 20kฮฉ โ”€โ”€โ”€ GND
                   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 10kฮฉ โ”€โ”€โ”€ 5V signal in

Connection Table:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ From                 โ”‚ To                                โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ESP32-S3 3V3         โ”‚ OLED VCC                          โ”‚
โ”‚ ESP32-S3 GND         โ”‚ OLED GND                          โ”‚
โ”‚ ESP32-S3 GPIO8 (SDA) โ”‚ OLED SDA                          โ”‚
โ”‚ ESP32-S3 GPIO9 (SCL) โ”‚ OLED SCL                          โ”‚
โ”‚ ESP32-S3 VIN (5V)    โ”‚ NeoPixel 5V, HC-SR04 VCC, PIR VCCโ”‚
โ”‚ ESP32-S3 GPIO6       โ”‚ Level shifter โ†’ NeoPixel DIN      โ”‚
โ”‚ ESP32-S3 GPIO8       โ”‚ 100ฮฉ โ†’ Piezo Buzzer +             โ”‚
โ”‚ ESP32-S3 GPIO9       โ”‚ HC-SR04 TRIG                      โ”‚
โ”‚ HC-SR04 ECHO (5V)    โ”‚ Voltage divider โ†’ ESP32 GPIO10    โ”‚
โ”‚ PIR OUT (5V)         โ”‚ Voltage divider โ†’ ESP32 GPIO2     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โšก Critical Notes:
  - OLED: 3.3V compatible โ€” no level shifting needed
  - NeoPixel: 5V logic required โ€” 74AHCT125 MANDATORY
  - HC-SR04 ECHO: 5V output โ€” voltage divider protects ESP32-S3
  - ESP32-S3 has two USB ports โ€” Codey auto-detects the correct one

Enter fullscreen mode Exit fullscreen mode

LUKE: "Download the PDF. Print two copies."

Compile and Upload to ESP32-S3 ๐Ÿš€

The ESP32-S3 N16R8 has two USB ports. Codey knows which one to use:

โš™๏ธ  Board: ESP32-S3 N16R8

Note: This board has two USB connectors:
  โ€ข USB (UART) โ€” for serial communication / upload via UART bridge
  โ€ข USB-OTG (native USB-CDC) โ€” direct USB communication

Codey will attempt to detect the correct port automatically.
If upload fails, try the other USB connector.

Enter fullscreen mode Exit fullscreen mode

Click Compile:

โœ“ Compilation successful
  Board:   ESP32-S3 N16R8
  Sketch:  r2d2-main.ino + 4 headers
  Binary:  412,288 bytes (5.9% of 16MB Flash)
  RAM:     Used 28,492 bytes (8.7% of 327KB)
  PSRAM:   8MB available for future expansion

Enter fullscreen mode Exit fullscreen mode

Click Upload โ†’ Select the correct USB port โ†’ Flash completes.

The OLED lights up: "R2-D2" and "ONLINE" with a spinning cursor.

R2-D2 beeps.

Then the idle screen appears: "DISTANCE: 87 cm โ€” SAFE."

Luke waves his hand in front of the HC-SR04. The screen immediately switches to "TOO CLOSE!" with a blinking border.

LUKE: "It works. He sees me. He's telling me I'm too close."

R2-D2 beeps something that clearly means "yes, please back up."

Save the Milestone ๐Ÿšฉ

Milestone: "R2-D2 Holographic Projector โ€” Episode 5 Complete"

Enter fullscreen mode Exit fullscreen mode

Four systems running. ESP32-S3 humming. The OLED projecting. The dome glowing. The sensors watching.

What's Next: The Motion Systems Activate โš™๏ธ

Han Solo slaps the workbench.

HAN: "Okay. He blinks, he beeps, he shows you a screen. But you know what R2-D2 actually does that nobody else can? He moves. He rolls. His dome spins. He navigates. Episode 6 โ€” we give this droid wheels and a rotating dome. Servo for the dome, DC motors for the base. The wiring diagram is going to get interesting."

R2-D2 beeps the equivalent of "I have been waiting for this my entire existence."

๐Ÿ”— Resources

๐Ÿค– 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.

Top comments (0)