
Reviving a Raspberry Pi with AI

I almost threw the Raspberry Pi away.
It was sitting under a knot of micro-USB cables that were already going in the trash: a Raspberry Pi 1 Model B+ from 2014, with a piece of masking tape on the case that still said localhost:4080 from some earlier experiment. Single-core ARMv6. 512MB of RAM. 100Mb Ethernet. Four USB 2.0 ports. No built-in WiFi.
Next to it were a "Wi-Pi" WiFi dongle, two old USB webcams, and a bare laptop webcam module I had pulled out of a dead Toshiba years ago. That last one was the bit I could never quite throw out, because it looked like the kind of thing that should become useful one day.
The goal was modest: turn the pile into a camera server I could reach while away from home. Not a real security system. Not high-resolution video. Just enough remote visibility to check whether my plants were still alive.
Why it stayed in the drawer
I had built an earlier version of this project once. Same Pi, one webcam, Ethernet, local network only. I called it surveillance with a straight face. It worked for about a week, the SD card died, and I never bothered to reflash it.
The project was fun. Restarting it was not.
Old hardware projects have a tax. Find the right OS image for an ARMv6 board. Check whether the WiFi dongle still has kernel support. Remember how headless SSH setup works, remember all the quirks and defaults of the OS. Read forum threads where every answer is almost for your board, except the person answering owns a completely different Pi.
That is usually where I give up. Not because the work is impossible, but because the interesting part keeps moving one detour farther away.
This time I wanted to test a smaller claim about AI than the usual fireworks show: could an agent-assisted workflow hold enough context to keep me moving through the boring parts?
I experimented with Antigravity as the workbench, not just as a chat window. The folder was where I kept the shared project state: notes, command output, config snippets, photos, and whatever hardware details I had confirmed. The chat was where I tested Gemini against that context. The terminal was how it actually talked to the Pi, mostly through SSH once networking was alive.
That distinction mattered. I was not asking Gemini to be an oracle. I was using Antigravity to keep the project state visible while Gemini helped me decide what to try next.
It did not make the Pi newer and faster. It made the next step easier to find.
The first decision was boring on purpose
The OS choice mattered because a Pi 1 B+ is an ARMv6 board with very little memory. A desktop image would have been a waste, and a random modern install path can quietly assume hardware newer than this.
The conservative answer was a 32-bit Raspberry Pi OS Lite image based on the legacy or oldstable track available in Raspberry Pi Imager at the time. In the image list, that showed up as raspios_oldstable_lite_armhf. The exact label may change as Debian releases move, but the reasoning is the part that matters: 32-bit Lite, no desktop, and no needless services fighting for RAM.
That was not a difficult answer. It was just the first answer I did not have to rediscover across ten tabs.
Gemini handled the SD-card prep from Antigravity: flash the microSD card, add ssh and userconf.txt to the boot partition, and get it ready for a headless first boot. I plugged in the WiFi dongle, put the card in the Pi, and powered it up.
The Pi did not join WiFi.
That sounds like a contradiction with the "AI plug and play" setup, so here is the boring detail: the dongle was not dead. Once I got a shell, lsusb could see it. The failure was first-boot network configuration, not missing hardware. At that point I had no monitor on the Pi, no SSH over WiFi, and no desire to turn the living room into a cabling project.
So I made the shortest possible network: one Ethernet cable between my Mac and the Pi.
# On the Mac. `en7` was my USB Ethernet adapter; yours may differ.
sudo ifconfig en7 inet 10.10.10.1 netmask 255.255.255.0 up
# On the Pi, with a keyboard attached and no display.
# I waited for boot, typed the login blind, then gave eth0 an address.
sudo ip addr add 10.10.10.2/24 dev eth0
# Back on the Mac.
ssh [email protected]
That is not elegant. It is barely a trick. But it got me from "the Pi exists somewhere on the floor" to a shell, which was the only thing that mattered.
The laptop webcam was the part I cared about
The two normal USB webcams were boring. Plug them in, get ordinary /dev/video* devices, move on.
The Toshiba module was different. It had a small camera board, a flat ribbon cable, six unlabeled pads, and no datasheet I could find that matched the markings well enough to trust. This is also where an AI story can get stupid fast. A model guessing a pinout from photos is not evidence. If you treat it like evidence, you can fry the board, the USB port, or both.
The only reason this was even plausible is that many laptop webcam modules are USB Video Class devices internally. I was not converting a random camera ribbon into USB by vibes. I was looking for USB pads on a board that already appeared to contain the camera controller. If it had been a MIPI or LVDS camera without a USB controller, a chopped-up USB cable would not have saved it.
I sent photos of both sides of the module, typed out the chip markings I could read, and described the USB cable I was about to sacrifice. The useful answer was practical: identify ground by continuity to shield, find the likely VBUS, D+, and D- pads, check that power and ground were not shorted, avoid assuming wire colors, and keep dmesg -w open before plugging anything in.
I still had to measure. I still had to decide. The AI reduced the search space; the multimeter made the call.
I tinned the pads, soldered the cable, plugged the module into a powered USB hub, and watched the kernel report a USB Video Class device. It appeared as another /dev/video* device.
The soldering was ugly, but it worked!
MotionEye met a 2014 CPU
MotionEye is a web interface for motion, the Linux motion-detection daemon. That distinction matters, because I managed to trip over it almost immediately.
I installed MotionEye, added the first USB webcam, and got a stream. Then I added the second USB webcam and the laptop module and asked the Pi to do something it had no business doing: serve the web UI, handle three camera feeds, record video, generate thumbnails, and encode at settings that were optimistic even before you remember the 512MB of RAM.
VIDIOC_S_INPUT: Device or resource busy
ffmpeg_set_codec: Could not open codec Encoder not found
hwmon1: Undervoltage detected!
Recordings showed up as half-written .crdownload files. The web UI sat at 100% CPU. The stream worked just long enough to make me think I was close, then fell apart.
This is where the Antigravity setup helped. One error would have been easy to search. Several errors at once needed ordering.
In my case, there were four separate problems.
The standalone motion service from the OS package was running and had grabbed a camera device. MotionEye still needs the motion binary, but it should be the thing managing motion; the separate systemd service should not be competing for /dev/video0.
sudo systemctl stop motion
sudo systemctl disable motion
The video settings were too heavy. Three cameras at 640x480 and 10fps were not a realistic target for this board, especially with recording enabled. USB bandwidth was part of the squeeze too; the powered hub helped with current draw, but it did not create another USB controller.
# /etc/motioneye/camera-*.conf
width 320
height 240
framerate 3
stream_quality 50
movie_codec mkv:mpeg4
Recording failed for a simpler reason too: MotionEye was trying to use an H.264 encoder that was not available on that Pi. The app could see the cameras, but it could not save the video in the format it had picked.
That is what movie_codec mkv:mpeg4 changed. mkv is the file container, and mpeg4 is the video encoder inside it. In plain English: save the recording as an .mkv file, but use an encoder this old Pi actually has.
Thumbnail generation was another small CPU leak. I turned it off globally and restarted MotionEye.
# /etc/motioneye/motioneye.conf
generate_thumbnails false
sudo systemctl restart motioneye
The undervoltage warning was the least subtle bug in the room. I had been powering the Pi, the WiFi dongle, and the cameras like a person who wanted software to apologize for physics. A powered USB hub fixed the camera side, and a better 5V supply fixed the Pi side. No config file negotiates with voltage drop.
After those changes, the Pi could run three low-resolution feeds. Not beautifully. Reliably enough.
The WiFi name was not a joke
My home WiFi is called Martin Router King ✨. The sparkle is non-negotiable.
To be precise, I am not claiming wpa_supplicant cannot handle a Unicode SSID. It can. I am saying the first-boot config path I used did not get this dongle onto this network, and I did not want to spend the night proving whether the failure was quoting, encoding, or my own typo.
Once I had SSH over Ethernet, I configured WiFi with NetworkManager instead.
sudo nmcli dev wifi list
sudo nmcli dev wifi connect 'Martin Router King ✨' password 'your-password-here'
sudo nmcli con mod 'Martin Router King ✨' ipv4.method manual ipv4.addresses 192.168.1.80/24 ipv4.gateway 192.168.1.1 ipv4.dns 192.168.1.1
sudo nmcli con up 'Martin Router King ✨'
The connection name can differ depending on how NetworkManager creates it, so I checked it with nmcli con show before making the static IP permanent. The important outcome was simple: the old dongle worked, the Pi got a predictable LAN address, and I could remove the direct Ethernet cable.
Remote access without opening the camera to the internet
I did not expose MotionEye directly to the public internet. No router port forward. No "temporary" open port that turns permanent because I forget about it. MotionEye got an admin password, stayed on the local network, and Tailscale became the way back in.
That made the remote path boring in the right way. My phone joined the same tailnet, the Pi had a Tailscale address, and I could open MotionEye as if I were still at home. If Tailscale was down, the camera server was not reachable from outside. That was the trade I wanted.
Two weeks later I was on vacation, checking my plants from my phone.
The video quality was terrible. Proper potato-grade surveillance. I did not care. The whole thing used parts I already owned, one Saturday night, and a small piece of solder.
What AI actually changed
The model did not know secret commands. It did not make the laptop camera safe to solder. It did not make the Pi capable of more CPU than it had.
The useful part was continuity.
The folder held the project state: the board model, the ARMv6 constraint, the WiFi dongle, the weird SSID, the MotionEye config, the power supply, the USB hub, and the fact that two cameras were ordinary USB webcams while the third was a hacked laptop module. The terminal gave me the live connection to the Pi. The chat gave me a place to ask Gemini what the logs meant without re-explaining the whole setup every time.
I also used Playwright through MCP once the MotionEye web UI was reachable. That let the agent open the page, click through the interface, check whether the camera views loaded, and debug the boring browser-side failures without me manually refreshing the same tab over and over. It was not testing in the formal CI sense. It was an extra pair of eyes on the UI.
That combination kept the errors from becoming one giant failure. Gemini could separate the mess into resource contention, unsupported encoding, CPU load, and power because the surrounding context was already there.
That ordering was the difference between staying with the project and putting the Pi back in the drawer.
I am still skeptical of over-trusting AI around hardware. If a model sounds confident near a soldering iron, I want a multimeter involved, especially because there is no Git history safety net when you burn a board. But as a context holder and tireless debugging partner, it was useful in exactly the way small projects need: it made the next step cheap enough to take.
What I ended up with
The final system was not impressive on paper, which is why I like it.
Board: Raspberry Pi 1 Model B+
OS: Raspberry Pi OS Lite, 32-bit
Cameras: 2 old USB webcams, 1 Toshiba laptop webcam module wired as USB
Camera app: MotionEye controlling motion
Video target: 320x240 at 3fps per camera
Power: better 5V supply for the Pi, powered USB hub for cameras
Network: old "Wi-Pi" WiFi dongle, static LAN IP
Remote path: Tailscale, no public port forwarding
Use case: checking plants while away from home
That is the actual result. Not a polished security system. Not a clean install guide. A tiny old board on WiFi, three terrible cameras, and a way to check my plants from my phone.
AI did not make me better at hardware that Saturday. I still had to do the soldering, measuring, rebooting, power swap, and settings grind. It just kept the mess organized enough that I did not quit when the next unrelated error showed up.
For me, that is the useful version of AI. Not magic. Not autopilot. Just enough help to keep moving.
The Pi is out of the drawer now. It streams awful 320x240 video, it has a job again, and I am weirdly proud of it.