
My roommate Paul and I initially wanted to get a Ring Doorbell Camera. However, we had some concerns once we researched some options:
- We didn't want to pay for a subscription
- Most companies had poor track records with data privacy
- No way to repair even minor damage
So we decided to tackle the challenge of designing our own local, repairable, and inexpensive doorbell camera. Conveniently, GoatHacks was just around the corner, and the 40-hour timeframe seemed to give us the perfect opportunity to build it.
We assembled the dream team: Paul, Liam, Rose, and me. Paul handled hardware, Liam handled software, and Rose and I bounced between the two.
The Plan
Here's what we set out to build:
- Video and two-way audio streaming
- Connection to server over local Wi-Fi
- ESP32 idles in deep sleep, activating with event detection:
- PIR sensor triggers ESP32 to wake up
- Button press also triggers ESP32 to wake up
- Event data saved to local SD card
- On-chip ML model determines if movement warrants an event trigger
- Event trigger sends a notification to mobile device
- Replaceable LiPo battery with custom external charger
We anticipated needing to purchase our own hardware, but still greatly underestimated how challenging it would be to source components mid-hackathon, even as basic as screws, transistors, or capacitors.
Soldering, Sensors, and a Dead Camera
Since I had little prior experience with either hardware or embedded programming, I felt eager to try my hand at both.
I decided to solo the LiPo battery charger, using a XIAO ESP32-C3 as a pass-through charger while monitoring the power level of the LiPo. I learned the hard way why soldering wires directly to the SMT power pads is risky, and accidentally tore off one of the pads while soldering a wire for a JST connection. Luckily, I was able to order a replacement to ship same-day. Once that arrived, I was much gentler assembling it.
Working on the main board, the XIAO ESP32-S3 Sense, the issues I encountered felt much more dire:
Defunct SD Port: We tried different SD cards, having Claude churn on it, and just about everything we could think of until finally giving in and reading the documentation, which gave us the simple fix of shorting the
J3jumper pads to enable the SD port. By the time we realized shortingJ3also disabled three other GPIO pins, we were nearing the deadline, and ultimately decided having a working speaker was more important than SD for our demo.Fried Camera: Right after I got one-way audio working and synced it with Liam's video streaming, our camera seemed to have died. It felt incredibly hot and stopped responding to serial, so we were worried it had fried. We tried resetting the devices, re-uploading, unplugging, and re-seating the port connection of the camera. Amazon same-day was no longer an option. A stranger even offered to lend us his broken Ring doorbell so we could jerry-rig its camera onto our board. After all that, Liam and I finally realized the issue stemmed simply from conflicting configs, as he was using Arduino IDE while I was using PlatformIO. We aren't sure what specifically caused this, but reverting to Liam's working Arduino build, then migrating to PlatformIO on his machine fixed it for both of us.
MVP and Demos
The chaos of the hackathon pressure meant our git repository was a disaster, and we learned soon enough just how overambitious we were. By the time the deadline neared, we reduced our ambitions to an MVP we could demo:
- Video streaming over HTTP
- One-way audio from doorbell to client
- Button triggering a welcoming "ding-dong" played over speaker
- LiPo battery charger
Stripping our project down to this MVP paid off heavily, as our demos went flawlessly. In the end, our project won Best Hardware and we won way too many JBLs.
With all the difficulties my team and I encountered throughout our project, I felt that hardware and embedded mentorship would have immensely helped us were it available. Eventually, I convinced myself to join the GoatHacks team to plan the event to be even better in following years. That's what I'm doing now!