The Age of Ridiculous Invention
- Rich Washburn
- 5 days ago
- 8 min read

I build a lot of things—some professional, some ridiculous, some that start out as one and become the other. But lately, there's been a throughline I can’t ignore: We’ve entered a new era of invention.
One where you can go from “What if...” to a working prototype in under an hour. One where AI writes the code, hardware costs almost nothing, and the only thing standing between you and a product is whether you decide to build it.
Case in Point: Night Vision for My Meta Quest 3
The project started because I was working in bed. I had my Meta Quest 3 on, remote desktop loaded up, everything was great—until I turned off the lights. Suddenly the tracking was garbage. The headset couldn’t see anything, and I couldn’t click, move, or navigate without randomly floating off into the void.
Now, the obvious fix was to just leave the lights on, but…where’s the fun in that?
I asked ChatGPT what was happening. It explained that the Quest’s cameras rely on visible light, but also respond well to infrared—especially around 850nm. I did some quick research (also via ChatGPT), found a cheap IR photography light online for under $20, and picked it up.
Sure enough: pitch-black room, flawless tracking. Problem solved… but with one small annoyance: I had to get up to turn it on.
So I Made It Smart — In Under an Hour

I cracked open the case, wired in a XIAO ESP32-C3, and turned the IR floodlight into a fully controllable Wi-Fi smart device.
Through a simple web interface, I can now:
Toggle the IR emitter on and off
Set timers (e.g., turn off after 90 minutes)
Trigger a soft nightlight LED when the timer ends
Adjust brightness on a 6-color LED cluster (Red, Green, Blue, White, Yellow, UV)
Automate everything via REST endpoints (great for macros and routines)

And here's the twist: ChatGPT wrote 95% of the firmware. From HTTP server logic to pinouts and state management—it handled everything. I asked, it wrote, I built.
This Isn’t Just a Hobby — This Is the Future of Product Development
This isn’t the first time I’ve done this. It won’t be the last.
I’ve used the XIAO ESP32-C3 to build:
Beacon — a Wi-Fi microsite broadcaster with captive portal delivery, now a patented product used in events, real estate, and marketing.
Macro Keyboards — custom productivity tools that execute GPT prompts, paste templates, and trigger automations.
IoT Coffee Monitor — because yes, I wanted my live mug temperature displayed on my site (and it’s awesome).
Some of these are tools I use daily. Others I’ve sold. One I’m in the process of selling entirely—IP, design, patents, everything.
They all started the same way:
A tiny idea + a XIAO ESP32-C3 + a few minutes in ChatGPT = a real thing.
Everyone Should Be Learning This Right Now
If you’re not already playing with microcontrollers, sensors, and AI-assisted firmware, you are missing the opportunity of the decade.
Here’s why:
You can build faster than you can buy. Seriously. This entire IR light project took just over an hour. I could have spent that time scrolling Amazon, but instead I now have a custom solution that does exactly what I want.
You don’t need to know how to code. Just know how to ask. Describe the behavior you want, and AI will walk you through the rest.
There are businesses hiding inside every weird idea. The tools, the cost, the barriers—none of those are problems anymore. The only remaining constraint is creativity.
We're at a point where anyone—student, creator, business owner, freelancer—can build real-world hardware and software solutions with minimal cost and no formal training.
This isn’t hype. It’s happening right now.I'm living it. So are many of my clients.
Final Thoughts
We’re wildly enabled right now.
If you can imagine a solution to some small friction in your life or workflow—no matter how silly—it’s almost guaranteed you can build it with $30 in parts, an ESP32, and an AI assistant.
The distance from idea to outcome has collapsed.
The only question is: what are you waiting for?
Firmware:
[env:seeed_xiao_esp32c3]
platform = espressif32
board = seeed_xiao_esp32c3
framework = arduino
monitor_speed = 115200
lib_deps =
tzapu/WiFiManager @ ^2.0.17-beta
// IR Emitter and LED Controller
// Version 2.0: Added Nightlight-after-timer and full RESTful API endpoints.
#include <WiFi.h>
#include <WebServer.h>
#include <WiFiManager.h>
#include <WiFiClientSecure.h>
// =============================================================================
// PIN CONFIGURATION
// =============================================================================
#define YELLOW_LED_PIN 2 // D0
#define UV_LED_PIN 3 // D1
#define WHITE_LED_PIN 4 // D2
#define RED_LED_PIN 5 // D3
#define GREEN_LED_PIN 6 // D4
#define BLUE_LED_PIN 7 // D5
#define IR_EMITTER_PIN 10 // D10 (Load)
// =============================================================================
// GLOBAL VARIABLES
// =============================================================================
WebServer webServer(80);
WiFiManager wm;
// --- Device State Variables ---
bool irState = false;
int ledStates[6] = {0, 0, 0, 0, 0, 0}; // Yellow, UV, White, Red, Green, Blue
// --- Timer Variables ---
unsigned long irTimerStart = 0;
unsigned long irTimerDuration = 0; // in milliseconds
bool timerActive = false;
// --- Nightlight Variables ---
int nightlightLedIndex = -1; // -1 means disabled. 0-5 corresponds to the LED array.
int nightlightLedValue = 128; // Default brightness for the nightlight.
// --- Pushover Configuration ---
#define PUSHOVER_USER_KEY_LEN 31
#define PUSHOVER_APP_TOKEN_LEN 31
char pushoverUserKey[PUSHOVER_USER_KEY_LEN] = "";
char pushoverAppToken[PUSHOVER_APP_TOKEN_LEN] = "";
WiFiManagerParameter g_param_pushover_user_key("pushover_user", "Pushover User Key", pushoverUserKey, PUSHOVER_USER_KEY_LEN - 1);
WiFiManagerParameter g_param_pushover_app_token("pushover_token", "Pushover App Token", pushoverAppToken, PUSHOVER_APP_TOKEN_LEN - 1);
// =============================================================================
// FORWARD DECLARATIONS
// =============================================================================
void sendPushoverCustomMessage(String pushoverTitle, String pushoverMessage);
String urlEncode(String str);
void setLedPin(int index, int value);
void handleState();
// =============================================================================
// HTML & JAVASCRIPT WEB INTERFACE
// =============================================================================
String generateHTML() {
String html = R"(<!DOCTYPE html><html lang='en'><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1.0, user-scalable=no'>
<title>IR & LED Controller</title><style>
:root{--bg-color:#1a1a1a;--card-color:#2c2c2c;--primary-color:#007bff;--text-color:#f0f0f0;--slider-track:#444;}
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;background-color:var(--bg-color);color:var(--text-color);margin:0;padding:15px;-webkit-tap-highlight-color:transparent;}
.container{max-width:500px;margin:0 auto;} h1{text-align:center;color:var(--primary-color);}
.card{background-color:var(--card-color);border-radius:12px;padding:20px;margin-bottom:20px;box-shadow:0 4px 10px rgba(0,0,0,0.2);}
.control-group{display:flex;justify-content:space-between;align-items:center;margin-bottom:15px;} .control-group label{font-size:1.1em;}
.toggle-switch{position:relative;display:inline-block;width:60px;height:34px;} .toggle-switch input{opacity:0;width:0;height:0;}
.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s;border-radius:34px;}
.slider:before{position:absolute;content:'';height:26px;width:26px;left:4px;bottom:4px;background-color:white;transition:.4s;border-radius:50%;}
input:checked+.slider{background-color:var(--primary-color);} input:checked+.slider:before{transform:translateX(26px);}
.led-control .slider-container{flex-grow:1;margin-left:20px;}
input[type='range']{-webkit-appearance:none;width:100%;height:8px;border-radius:5px;background:var(--slider-track);outline:none;}
input[type='range']::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:24px;height:24px;border-radius:50%;background:var(--primary-color);cursor:pointer;}
.timer-section{display:flex;align-items:center;gap:10px;}
.timer-section input{width:60px;padding:8px;border-radius:5px;border:1px solid #555;background-color:#333;color:var(--text-color);font-size:1em;}
.timer-section button{padding:8px 15px;border-radius:5px;border:none;background-color:var(--primary-color);color:white;font-size:1em;cursor:pointer;}
#timerStatus{margin-top:10px;font-style:italic;color:#aaa;}
select{width:100%;padding:10px;border-radius:5px;border:1px solid #555;background-color:#333;color:var(--text-color);font-size:1em;}
</style></head><body><div class='container'><h1>VR Environment Controller</h1>
<div class='card'><h2>IR Emitter</h2><div class='control-group'><label for='irToggle'>Status</label><label class='toggle-switch'><input type='checkbox' id='irToggle' onchange='toggleIR()' )" + String(irState ? "checked" : "") + R"(><span class='slider'></span></label></div><hr>
<div class='control-group'><label>On-Timer (minutes)</label><div class='timer-section'><input type='number' id='timerInput' min='1' placeholder='mins'><button onclick='setTimer()'>Start Timer</button></div></div>
<div id='timerStatus'>Timer is inactive.</div></div>
<div class='card'><h2>Nightlight After Timer</h2><div class='control-group'><label for='nightlightSelect'>LED</label><select id='nightlightSelect' onchange='setNightlight()'>
<option value='-1'>Disabled</option>)";
const char* ledNames[] = {"Yellow", "UV", "White", "Red", "Green", "Blue"};
for(int i=0; i<6; i++){ html += "<option value='" + String(i) + "'" + (nightlightLedIndex == i ? " selected" : "") + ">" + ledNames[i] + "</option>"; }
html += R"(</select></div><div class='control-group led-control'><label>Brightness</label><div class='slider-container'><input type='range' min='0' max='255' value=')" + String(nightlightLedValue) + R"(' id='nightlightValue' oninput='setNightlight()'></div></div></div>
<div class='card'><h2>Manual LED Control</h2>)";
for (int i = 0; i < 6; i++) { html += "<div class='control-group led-control'><label>" + String(ledNames[i]) + "</label><div class='slider-container'><input type='range' min='0' max='255' value='" + String(ledStates[i]) + "' class='led-slider' id='led" + String(i) + "' oninput='updateLED(" + String(i) + ", this.value)'></div></div>"; }
html += R"(</div></div><script>
let debounceTimeout;
function sendCommand(url){fetch(url).then(response=>response.json()).then(updateUI).catch(err=>console.error('Error:',err));}
function toggleIR(){sendCommand('/control?action=toggleIR');}
function setTimer(){let mins=document.getElementById('timerInput').value;if(mins&&mins>0){sendCommand('/control?action=setTimer&minutes='+mins);}}
function updateLED(index,value){clearTimeout(debounceTimeout);debounceTimeout=setTimeout(()=>{sendCommand('/control?action=setLED&index='+index+'&value='+value);}, 100);}
function setNightlight(){let idx=document.getElementById('nightlightSelect').value; let val=document.getElementById('nightlightValue').value; clearTimeout(debounceTimeout);debounceTimeout=setTimeout(()=>{sendCommand('/control?action=setNightlight&index='+idx+'&value='+val);}, 100);}
function updateUI(state){
document.getElementById('irToggle').checked=state.irState;
for(let i=0;i<6;i++){document.getElementById('led'+i).value=state.leds[i];}
document.getElementById('nightlightSelect').value=state.nightlightIndex;
document.getElementById('nightlightValue').value=state.nightlightValue;
if(state.timerActive){let rem=Math.ceil(state.timerRemaining/60000);document.getElementById('timerStatus').innerText='Timer active. Turning off in about '+rem+' minute(s).';}
else{document.getElementById('timerStatus').innerText='Timer is inactive.';}
}
setInterval(()=>{fetch('/state').then(response=>response.json()).then(updateUI).catch(err=>console.error('Error:',err));}, 2000);
</script></body></html>)";
return html;
}
// =========================================================================
// WEB SERVER HANDLERS
// =========================================================================
void handleRoot() {
webServer.send(200, "text/html", generateHTML());
}
void handleState() {
String json = "{";
json += "\"irState\":" + String(irState ? "true" : "false") + ",";
json += "\"leds\":[" + String(ledStates[0]) + "," + String(ledStates[1]) + "," + String(ledStates[2]) + "," + String(ledStates[3]) + "," + String(ledStates[4]) + "," + String(ledStates[5]) + "],";
json += "\"timerActive\":" + String(timerActive ? "true" : "false") + ",";
json += "\"timerRemaining\":" + String(timerActive ? (irTimerDuration - (millis() - irTimerStart)) : 0) + ",";
json += "\"nightlightIndex\":" + String(nightlightLedIndex) + ",";
json += "\"nightlightValue\":" + String(nightlightLedValue);
json += "}";
webServer.send(200, "application/json", json);
}
void handleControl() {
if (webServer.hasArg("action")) {
String action = webServer.arg("action");
if (action == "toggleIR") {
irState = !irState;
digitalWrite(IR_EMITTER_PIN, irState);
if (!irState) timerActive = false;
sendPushoverCustomMessage("IR Emitter Control", String("IR Emitter was turned ") + (irState ? "ON" : "OFF"));
} else if (action == "setTimer" && webServer.hasArg("minutes")) {
irState = true;
digitalWrite(IR_EMITTER_PIN, irState);
timerActive = true;
irTimerDuration = webServer.arg("minutes").toInt() * 60000;
irTimerStart = millis();
sendPushoverCustomMessage("IR Emitter Control", "IR Emitter timer set for " + webServer.arg("minutes") + " minutes.");
} else if (action == "setLED" && webServer.hasArg("index") && webServer.hasArg("value")) {
int index = webServer.arg("index").toInt();
int value = webServer.arg("value").toInt();
setLedPin(index, value);
} else if (action == "setNightlight" && webServer.hasArg("index") && webServer.hasArg("value")) {
nightlightLedIndex = webServer.arg("index").toInt();
nightlightLedValue = webServer.arg("value").toInt();
}
}
handleState(); // Send back the new state
}
// =========================================================================
// API HANDLERS
// =========================================================================
void handleApiSetLed() {
if (webServer.hasArg("index") && webServer.hasArg("value")) {
setLedPin(webServer.arg("index").toInt(), webServer.arg("value").toInt());
handleState();
} else {
webServer.send(400, "application/json", "{\"error\":\"missing index or value\"}");
}
}
void handleApiSetTimer() {
if (webServer.hasArg("minutes")) {
irState = true;
digitalWrite(IR_EMITTER_PIN, irState);
timerActive = true;
irTimerDuration = webServer.arg("minutes").toInt() * 60000;
irTimerStart = millis();
handleState();
} else {
webServer.send(400, "application/json", "{\"error\":\"missing minutes\"}");
}
}
void handleApiIr() {
if (webServer.hasArg("state")) {
String state = webServer.arg("state");
if (state == "on") irState = true;
else if (state == "off") irState = false;
digitalWrite(IR_EMITTER_PIN, irState);
if (!irState) timerActive = false;
handleState();
} else {
webServer.send(400, "application/json", "{\"error\":\"missing state=on/off\"}");
}
}
// =========================================================================
// SETUP
// =========================================================================
void setup() {
Serial.begin(115200);
pinMode(IR_EMITTER_PIN, OUTPUT); digitalWrite(IR_EMITTER_PIN, LOW);
pinMode(YELLOW_LED_PIN, OUTPUT); analogWrite(YELLOW_LED_PIN, 0);
pinMode(UV_LED_PIN, OUTPUT); analogWrite(UV_LED_PIN, 0);
pinMode(WHITE_LED_PIN, OUTPUT); analogWrite(WHITE_LED_PIN, 0);
pinMode(RED_LED_PIN, OUTPUT); analogWrite(RED_LED_PIN, 0);
pinMode(GREEN_LED_PIN, OUTPUT); analogWrite(GREEN_LED_PIN, 0);
pinMode(BLUE_LED_PIN, OUTPUT); analogWrite(BLUE_LED_PIN, 0);
wm.addParameter(&g_param_pushover_user_key);
wm.addParameter(&g_param_pushover_app_token);
if (!wm.autoConnect("IR-Controller-Setup", "password")) { ESP.restart(); }
Serial.println("\nConnected to WiFi!");
Serial.print("IP Address: "); Serial.println(WiFi.localIP());
strncpy(pushoverUserKey, g_param_pushover_user_key.getValue(), PUSHOVER_USER_KEY_LEN - 1);
strncpy(pushoverAppToken, g_param_pushover_app_token.getValue(), PUSHOVER_APP_TOKEN_LEN - 1);
// --- Web UI Routes ---
webServer.on("/", HTTP_GET, handleRoot);
webServer.on("/control", HTTP_GET, handleControl);
webServer.on("/state", HTTP_GET, handleState);
// --- API Routes ---
webServer.on("/api/ir", HTTP_GET, handleApiIr);
webServer.on("/api/timer", HTTP_GET, handleApiSetTimer);
webServer.on("/api/led", HTTP_GET, handleApiSetLed);
webServer.on("/api/state", HTTP_GET, handleState); // Alias for /state
webServer.onNotFound([]() { webServer.send(404, "text/plain", "Not Found"); });
webServer.begin();
sendPushoverCustomMessage("IR Controller Online!", "Device is online at IP: " + WiFi.localIP().toString());
}
// =========================================================================
// MAIN LOOP
// =========================================================================
void loop() {
webServer.handleClient();
if (timerActive && (millis() - irTimerStart >= irTimerDuration)) {
irState = false;
digitalWrite(IR_EMITTER_PIN, LOW);
timerActive = false;
sendPushoverCustomMessage("IR Emitter Control", "IR Emitter timer finished and turned OFF.");
// --- Nightlight Logic ---
if (nightlightLedIndex >= 0 && nightlightLedIndex < 6) {
setLedPin(nightlightLedIndex, nightlightLedValue);
const char* ledNames[] = {"Yellow", "UV", "White", "Red", "Green", "Blue"};
sendPushoverCustomMessage("Nightlight Activated", String(ledNames[nightlightLedIndex]) + " nightlight is ON.");
}
}
}
// =========================================================================
// HELPER & PUSHOVER FUNCTIONS
// =========================================================================
void setLedPin(int index, int value) {
if (index >= 0 && index < 6) {
ledStates[index] = value;
int pin;
switch(index) {
case 0: pin = YELLOW_LED_PIN; break;
case 1: pin = UV_LED_PIN; break;
case 2: pin = WHITE_LED_PIN; break;
case 3: pin = RED_LED_PIN; break;
case 4: pin = GREEN_LED_PIN; break;
case 5: pin = BLUE_LED_PIN; break;
default: return;
}
analogWrite(pin, value);
}
}
void sendPushoverCustomMessage(String pushoverTitle, String pushoverMessage) {
if (strlen(pushoverUserKey) == 0 || strlen(pushoverAppToken) == 0) { Serial.println("Pushover: Keys not configured."); return; }
if (WiFi.status() != WL_CONNECTED) { Serial.println("Pushover: WiFi not connected."); return; }
WiFiClientSecure client;
client.setInsecure();
if (!client.connect("api.pushover.net", 443)) { Serial.println("Pushover: Connection failed!"); return; }
String postData = "token=" + String(pushoverAppToken) + "&user=" + String(pushoverUserKey) + "&title=" + urlEncode(pushoverTitle) + "&message=" + urlEncode(pushoverMessage);
client.println("POST /1/messages.json HTTP/1.1");
client.println("Host: api.pushover.net");
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: "); client.println(postData.length());
client.println();
client.print(postData);
unsigned long timeout = millis();
while (client.available() == 0) { if (millis() - timeout > 5000) { client.stop(); return; } }
while(client.available()){ if (client.readStringUntil('\r').startsWith("HTTP/1.1 200 OK")) { Serial.println("Pushover: Message sent."); } }
client.stop();
}
String urlEncode(String str) {
String encodedString=""; char c; char code0; char code1;
for (unsigned int i =0; i < str.length(); i++){
c = str.charAt(i);
if (c == ' '){ encodedString+= '+'; }
else if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { encodedString+=c; }
else {
code1=(c & 0xf)+'0'; if ((c & 0xf) > 9) code1=(c & 0xf) - 10 + 'A';
c=(c>>4)&0xf; code0=c+'0'; if (c > 9) code0=c - 10 + 'A';
encodedString+='%'; encodedString+=code0; encodedString+=code1;
}
}
return encodedString;
}
#ESP32C3, #AIBuilder, #MakersGonnaMake, #IoTProjects, #HardwareHacking, #OpenSourceInnovation, #DIYTech, #SmartDevices, #CreativeEngineering, #FutureIsBuilt
Comments