Build journal · ESP32-S3 · 3D printed

Reward Rocket

A tabletop rocket that releases one sealed reward capsule when my kid earns it. Getting there took ten chapters of things going wrong.

The video has the highlights. This is the long version: the dead ends, the measurements that broke my assumptions, and the fixes that finally made it buildable.

Get the files

Build one yourself

Every part here is what I actually used.

Get the print files on Printables →Parts listAssembly guidePrint settingsCode (GitHub)

Free · STL/3MF · CC BY-NC-SA 4.0

Prototype notice: Reward Rocket is a prototype and has not been extensively tested. Build and use it at your own risk. Scoped build and software checks do not mean physical validation.

How we worked

The design process behind it

I built Reward Rocket with the AI Make process, the same step-by-step method every AI Make project follows. See how the process works.

The build story

One button, one capsule, one very small customer

Potty training runs on rewards. I wanted the reward to feel like an event: I approve it from my phone, my kid presses a big real button, and one sealed capsule comes out of the rocket on the table.

That’s the whole pitch. Making it real took a browser mockup, a stack of Fusion parts, a print farm, a hood that took roughly 18 hours to print, and more firmware than I expected.

I worked with AI assistants the whole way. They modeled parts in parallel while I handled other work, built and checked the firmware, and read through the code to find bugs. I measured the real parts, printed, assembled, tested, and made the calls. Where an assistant’s guess met a caliper, the caliper won. That happens a lot below.

Spoiler: it works. It passed a 15-delivery test.

01

The spec I wrote before touching CAD

Before any CAD, the rocket got a yardstick: a product design specification, the written list of what it must do. A parent approves one reward at a time over the home network. A real button for the kid. One closed capsule at a time, dispensed from the acrylic tube; the finished rocket’s tube holds 10 capsules. Reuse the ESP32-S3 board and 5 V stepper I already owned. Fit in six inches.

The spec also pinned down the tube dimensions, a 40 g limit on what a capsule carries, printer and material preferences, looks, cost and effort targets, safety and recovery limits, and how each requirement would eventually be checked.

PDS requirements card (v1.3)
The design specification card
02

A rocket that only existed in a browser tab

The first rocket was a GLB, a compact 3D model file you can spin around in a web browser. Rocket, tube, capsule path, mechanism, all moving. We could argue about layout and motion in minutes instead of modeling every screw first. I still have the clips of it going from rough to polished.

It looked great. It also lied, the way every pretty mockup lies. A browser model doesn’t care that you can’t reach a screw, that a connector has nowhere to go, that two walls pass through each other, or that a part will print badly the way it’s oriented. It even carried an idea I’d later kill: two Hall sensors.

So the GLB became a picture and a layout guide, never something to print. The layout ideas worth keeping were rebuilt as dimensioned Fusion parts, with mounting and manufacturing detail added only where evidence backed it up.

The lesson I took away: print cheap size-check coupons for the critical spaces before detailed design. I did use coupons eventually. Too late.

Browser concept evolution
Browser concept evolution
03

The board fit on paper. It did not fit in the rocket.

The electronics started as reference photos and catalog descriptions: the ESP32 breakout board, the Hall sensor board, the stepper driver. All of it had to fit in a small body and stay reachable for service.

Then I tried to install the real board. Some of the early board details, especially the breakout pins, were wrong. Worse, the actual pin headers crashed into the base and floor. There was no way to get the board in.

That one taught me something. A board can line up perfectly with its screw holes and still be impossible to install, because the connectors and the bends in the wires need real volume behind it.

So I measured. Board facing outward, which worked. Header projection: 8 mm. Connectors plus wire bends: roughly 18–20 mm from the board surface. That number later shaped the removable pod on the hood. And I powered everything from the breakout’s labeled 5 V/GND bus.

The service pod and hood seam
The service pod and hood seam
04

Two sensors went in, one came out

The early concept had two Hall sensors, little magnetic switches: one to find home, one to mark the delivery spot. That’s an extra board, extra mounts, extra wires, extra code.

It needed one. The firmware now seeks the sensor’s edge as a magnet passes and uses that as its datum, the fixed reference point everything is measured from. From there it applies a signed, saved offset that I set by hand to reach the delivery spot. I watched the sensor catch the magnet and stop the way it was configured. Then I lined the top up at the delivery position and tightened the grub screw.

The datum gives a known start. The offset handles however the parts actually line up. No second sensor, and no pretending that counting motor steps alone can find the spot. In my debrief, the two sensors were on my list of unnecessary redundancy.

05

A button too short to press its own switch

Version one of the button was a stack: switch, a flexible and fairly weak support, plunger, bezel. The switch fit fine on its own. Assembled from underneath, it was a fight.

And then the plunger didn’t reach. The button was too short to press its own switch reliably. Some of the small supported features printed badly too.

The fix was a rethink. The switch now lives in a removable cartridge that slides in from below, held by a compact keeper on a sturdier, continuous support, with a bezel that screws on and a longer plunger. I measured the switch actuator sitting 9.8 mm below the bezel mounting surface, and at my request the AI extended the plunger tip to exactly that. Its flange gives 3 mm of captured play, 1.5 mm each way, and the switch itself sets where a press stops. Pegs and sockets keep the bezel halves aligned while the seam glue cures. The base and its heat-set inserts didn’t change at all.

Dry test: it worked like a charm. The printed plunger came out well, and the button works. Best part: the switch can now be swapped without scrapping the base.

Button cartridge, keeper, plunger and bezel (CAD re-render)
Button cartridge, keeper, plunger and bezel (CAD re-render)
06

The 18-hour hood

Having a print farm means you can print a lot of parts at once. It doesn’t mean you’re printing them well.

My early print plates were often half empty, and the AI oriented some parts so they needed a forest of support. The early hood was roughly an 18-hour print; a later redesigned and reoriented version was about 3 hours. The early one was also miserable to clean up. On one printer, a part had support under faces that should have sat flat on the build plate, and a thin section near a cone rim delaminated, its layers peeling apart.

Looking closer, support wasn’t following the surfaces that mattered. Tiny tips got no support while big flat areas were buried in it. The surface finish showed it. And print plates kept going out with unused space. I asked more than once for compatible parts to share a print plate, and pointed out that in Orca, same-material parts can each have their own infill, so one print plate doesn’t force one infill on everything.

The turnaround: the AI reoriented parts for solid bed contact and less support, and made print plate arrangement a deliberate step instead of an afterthought. The rules I settled on: orient for the least support, never put support on mating faces unless there’s truly no alternative, and no brims unless a part has actually failed to stick. That’s what this project taught me.

And the same lesson as chapter 2, again: size-check prints before detailed models, especially for bought boards and anything that moves.

Inverted hood with the local screw-block changes
Inverted hood with the local screw-block changes
Nose underside section showing the fixed ribs (CAD re-render)
Nose underside section showing the fixed ribs (CAD re-render)
07

Wires I couldn’t reach

The first wiring plan put connectors on a floor I couldn’t reach once the rocket was assembled. The Hall sensor board’s screws and nuts were awkward too, and I ruled out nuts on the sensor side because they could pull out and crowd the sensor.

Heat-set inserts, threaded brass sleeves melted into the plastic, replaced the nuts. The button wiring got simpler once I was actually building it. I soldered the two button wires directly to the B3F-5050 switch pins and routed them to the ESP32 instead of using the terminals in the model.

The final map: button to GPIO17 and ground. Hall sensor signal to GPIO15 at 3.3 V. The ULN2003 driver’s IN1–IN4 to GPIO4 through GPIO7. Motor power from the breakout’s 5 V and shared GND bus.

Fewer connectors and reachable screws made the real assembly simpler. The wiring diagram shows this setup as I built it.

The breakout headers projecting toward the floor
The breakout headers projecting toward the floor
08

Making room without making it ugly

Remember the 18–20 mm the connectors needed? The original hood didn’t have it. Pin headers, connector bodies and wire bends simply didn’t fit.

I could have inflated the whole hood. That would have solved the space problem and given me a fat, bulky rocket that was harder to service.

Instead, the hood split in two. A removable blue service pod now sits on the white hood. It carries the extra bulge, is held by two center screws, and comes off without touching the base. The seam was rebuilt to follow the hood’s taper instead of leaving a visible gap. I set the electronics clearance target at about 20 mm from the board, and chose to power the board through its 5 V header rather than a permanent USB cable. The redesigned hood printed far faster than the support-heavy original, too (see chapter 6).

Flush pod-to-hood joint
Flush pod-to-hood joint
Blue integral fincan with ribs and tube stop (CAD re-render)
Blue integral fincan with ribs and tube stop (CAD re-render)
09

The rocket that delivered in silence

Firmware bring-up started small: short, counted jogs, small commanded moves of the motor. The first jog was so short the driver LEDs just blinked. Was the motor even moving? I questioned the test length, and a continuous jog settled it. The motor turned. The Hall sensor test became a proper seek-and-stop tool: turn until the sensor finds home, then stop. No more guessing step counts.

From there the controller grew into a parent page on my home LAN. One obvious button sends a reward. A separate settings area handles jogging, teaching positions, status, and Arduino IDE OTA (over-the-air) firmware updates. Positioning uses the Hall sensor as the home datum plus that persistent signed dropoff correction. The AI refined startup and recovery behavior after my real-world testing.

Then the surprise. A phone audio test page worked fine on its own. But the first combined version could release a capsule in total silence unless I refreshed the page. Reading the code turned up a lifecycle error: each reward cycle ID was consumed before audio start was ready.

Firmware 358 fixed that, and in my testing it behaved as expected. 358 is the accepted baseline. A later two-client and restart concern led to firmware 359. Its source, controller tests, ESP32-S3 build and package checks all passed. 359 is the compiled candidate.

10

Fifteen deliveries later

If you want to build one, start with the 3D animated assembly guide. It’s made from the saved CAD models and their positions: 38 steps, 95 models and the full parts list. It’s a map of the built prototype.

The parts list covers every bought component with supplier and reference links. The motor sits on two M3×8 screws with ten 0.5 mm M3 washers, five under each ear, lifting each ear 2.5 mm. The guide also covers the B3F-5050 button, the single Hall module and the removable pod.

My debrief was mixed. I lost time waiting on long checks whose results still needed rework. I called out support-heavy printing, underfilled print plates, too many controls in the interface, the two Hall sensors, wrong board details, surfaces that didn’t meet cleanly, and tasks abandoned before they were finished. My biggest process fix: print size-check coupons before modeling any real-world part you haven’t measured.

And the rocket? It feels good, and it passed a 15-delivery test.

So here’s the scoreboard. Wins: a 15-delivery pass, a button that works, a Hall-indexed controller, and a complete set of build documents. It got more buildable with every round.

CAD view of the assembled rocket
CAD view of the assembled rocket
Electronics

Wiring as built

SignalConnection
ULN2003 IN1–IN4GPIO4–GPIO7
Hall sensor (active-low)GPIO15, 3.3 V
B3F-5050 buttonGPIO17 + GND, direct solder
Driver powerShared 5 V / GND breakout bus
Power inPanel USB-C, 5 V 2 A supply

The button wires are soldered straight to the switch pins and routed to GPIO17 and GND. The 28BYJ-48 motor sits on two M3×8 socket-head screws, with five 0.5 mm M3 washers under each ear. That 2.5 mm lift sets how the gears mesh.

For printing, we used tested 0.20 mm profiles and as little support as possible, with none on surfaces that mate with other parts. We skipped brims unless a part needed help sticking, and put compatible parts on the same plate.

Bill of materials

Parts I used

Every part here is what I actually used in this build: all 26 lines of the purchased parts list. The printed parts are in the print files: 39 printed pieces in all, including ten of each capsule half. The acrylic tube is used uncut and holds 10 capsules.

Amazon purchase links are affiliate links. As an Amazon Associate I earn from qualifying purchases. Using these links helps me make more projects like this one.

Download BOM.csv

CategoryPartQtySpecWhere I got it
ElectronicsESP32-S3 controller + expansion breakout1 assemblyExact owned board variant; breakout is separately mountedView on Amazon
Electronics28BYJ-48 stepper motor15V stepper motor with factory motor plugView on Amazon
ElectronicsULN2003 driver board1ULN2003 family; four-input boardView on Amazon
ElectronicsHome Hall sensor module1A3144/3144E family; signal to GPIO15, active-low INPUT_PULLUPView on Amazon
ElectronicsMomentary button switch1Omron B3F-5050; 12×12 mm bodyView on Amazon
PowerPanel USB-C inlet with pigtail1DWEII B0FS1F9RQ7 panel inletView on Amazon
PowerUSB power supply15V, 2A USB-A output supplyView on Amazon
PowerUSB-A to USB-C external supply cable1USB-A plug to USB-C inlet connectionView on Amazon
MechanicalOutput shaft1Stainless steel, 6 mm diameter × 100 mm longView on Amazon
MechanicalBearings2Plain 686ZZ: 6 mm bore, 13 mm OD, 5 mm wideView on Amazon
MechanicalIndex magnet13 mm diameter × 2 mm axial magnetView on Amazon
MechanicalAcrylic tube1Supplied tube used uncut; nominal 51 mm ID × 55 mm OD, 18-inch length. Holds 10 capsules.View on Amazon
FastenerSocket-head screw16ISO 4762 M2×6 mmView on Amazon
FastenerCountersunk screw7DIN 965A M2×6 mm Phillips; 90° head, max OD 4 mm, max head height 1.2 mmView on Amazon
FastenerSocket-head screw2ISO 4762 M3×8 mmView on Amazon
FastenerFlat-point grub screw3ISO 4026 M3×6 mmView on Amazon
FastenerCountersunk floor screw3ISO 10642 M3×16 mmView on Amazon
FastenerM2 heat-set insert23M2 thread × 4 mm long; nominal OD 3.2 mmView on Amazon
FastenerM3 heat-set insert8M3 thread × 4 mm long; nominal OD 4.6 mmView on Amazon
FastenerM2 washer4OD 5 mm × ID 2.2 mm × 0.3 mm thickView on Amazon
FastenerM3 washer100.5 mm thick; five beneath each motor earView on Amazon
ConsumableAssembly adhesiveAs neededARKA KRAFTPROTZ 3D DRUCK liquidView on Amazon
WiringSignal leads / jumpers7Seven female/female 2.54 mm signal leads; supplied mixed ELEGOO kitView on Amazon
WiringButton leadsExisting pairTwo direct-solder leads from the B3F-5050 normally-open contact pair: GPIO17 to one side, common GND to the other; active-low INPUT_PULLUP.View on Amazon
WiringDriver power leadsExisting pairBreakout 5V bus to ULN2003 +; shared GND bus to ULN2003 −. Driver inputs map from ESP32 GPIO4/5/6/7.View on Amazon
Printing materialELEGOO Rapid PLA+ filament bundle1 bundleBlack/white/red/blue 4 kg Rapid PLA+ bundle (4 × 1 kg spools), ASIN B0CD2GRZ2MView on Amazon

As an Amazon Associate I earn from qualifying purchases. Using these links helps me make more projects like this one.

Fastener kits

These kits contain the screws needed for this build. The insert and washer packs provide the remaining fasteners.

Assembly

38-step assembly guide

From laying out parts to servicing the blue pod: inserts, button cartridge, drive train, floor, ESP32, hood, fincan and capsules.

Open the 3D assembly guide →

Missing a part? Here’s the exact one I used.

Show your build

Built one?

I’d love to see it. Post your make or remix on Printables, or tag me on X @mtorores. Remixes are welcome under CC BY-NC-SA 4.0: non-commercial, with credit, shared alike.

Post your make on Printables

Keep going

How I designed it, and what’s next