01 · Pay
Escrow → supplier, in USDC on Base.
The delivery’s money waits in escrow. If the tablet passed the screen, a pharmacist taps release and the agent’s CDP wallet signs the transfer to the supplier. No tap, no transfer.
Cal Hacks 13.0 · October 2026
A tablet cannot lie about dissolving.
A dissolution check the size of a coffee mug, from hobby parts: a 3D-printed chamber, three LEDs, two light sensors and an Arduino UNO Q. Drop one tablet in a clear cup of water, close the lid, and 60 s later (quick run; 2–10 min for a full one) it says Passed the screen, Needs lab testing or Unable to verify. In a clinic, that answer decides whether the supplier gets paid.
Film · Saturday night
Fig 1 · The station
scroll to explode
01 · Lid
A flat printed lid with a skirt and a plug that keep room light out, and one small hole. Opening it marks the moment the tablet went in.
02 · Chamber
A purple 3D-printed cylinder, 84 mm across and 84 mm tall, with a 78 mm well the cup drops into. Hand-stirred today; a stirrer motor is next.
03 · Cup
A clear plastic cup of water and one whole tablet. One of three printed shim rings keeps it centred on the beam.
04 · LED box
A printed box on the side of the chamber holds white, blue and red 5 mm LEDs. They shine through a diffuser plate into the cup, one at a time.
05 · Two photoresistors
One in a holder straight across from the LED box (how much light gets through), one at 90° (how much scatters: the cloudiness a white tablet makes).
06 · Brains
An Arduino UNO Q and a breadboard with the divider resistors. A dark reading every second, then one per colour, one CSV line to the laptop. The firmware decides nothing.
Fig 1.1 · The real thing
The drawing above is this station. A purple 3D-printed chamber, a clear cup of water, three LEDs, two photoresistors, an Arduino UNO Q, a breadboard and a laptop. Stirred by hand with a stick.






Drawn before the build. The build uses three of the five LED holes (white, blue, red) and the plain lid; the green LED and the stirrer motor are not fitted. Open any one full size.
The problem
WHO estimates that 1 in 10 medical products in low- and middle-income countries is substandard or falsified. A model cited by WHO puts the cost at about 116,000 extra malaria deaths a year in sub-Saharan Africa from substandard and falsified antimalarials alone. The instrument that catches this in a lab costs $20,000 to $100,000 and sits far from the clinics that need it.
medical products in low- and middle-income countries estimated substandard or falsified
extra malaria deaths a year in sub-Saharan Africa, modelled, from substandard and falsified antimalarials (range 64,000–158,000)
children's deaths linked to contaminated cough syrups in three countries, 2022–23, most under five
spent each year on substandard and falsified medical products, by WHO's estimate
Why a lookup is not enough
Lot numbers can be copied. Dissolution cannot.
In December 2025 the FDA found falsified Ozempic inside the legitimate US supply chain, labelled with a lot number that was also a real one. A recall lookup alone passes that product. A measurement of the tablet itself is the only check that does not trust the label. FDA, Dec 2025
How Pill works
Fig 0.1
A 3D-printed cylinder with the clear cup of water in its well. The beam crosses the cup from the LED box to the far wall; the side sensor sits at 90°.
Ø 84 × 84 mm · well Ø 78 mm · beam 28 mm above the well floor · lid Ø 90 mm, one 3.6 mm hole · three shim rings, bores 58 / 64 / 70 mm
Fig 0.2
White, blue and red 5 mm LEDs push into holes in the box's outer wall and shine through a diffuser plate that slides into a slot on top. Lit in turn once a second; red is the colour reference.
D5–D8 · active-low through one 330 Ω resistor to 5 V · LOW means on
Fig 0.3
Each photoresistor pushes into a pocket from inside the well; its leads leave through the holder. One holder faces the LED box, one sits at 90° to the beam.
CdS photoresistor · 10 kΩ divider from 3V3 · A0 across the cup · A1 at 90°
Fig 0.4 · Next
Not on the station yet. The lid's small hole is there for it: a bead on two leads, dipped in the water. Today the water temperature is typed in for each run.
what’s next · temperature on every reading instead of once per run
Fig 0.5 · Next
Not on the station yet. The CAD has a lid with a motor tower, a rod and a four-blade paddle that turns below the beam. Today the cup is stirred by hand with a wooden stick.
what’s next · the same stir every run, without the hand
Fig 0.6
The board reads both photoresistors through 10 kΩ dividers on the breadboard and streams one CSV line a second. The firmware decides nothing.
3.3 V · 12-bit ADC · dark reading before every sweep · 115200 baud
Fig 0.7
The station face, on the laptop the UNO Q plugs into. It builds the curves, spots the moment the tablet went in from the lid opening, matches the run against a reference profile and gives one of three answers.
Python · FastAPI · SQLite · 14 tests · says REPLAY (not live) when it replays a CSV
Fig 0.8 · Data path
The UNO Q measures. The software owns the maths, the rules and the payment policy. Claude writes the plain-English "why" and the log line; it never sets a verdict or moves money.
CSV line/s · absorbance = log(blank/now) · reference match · 7 rules · policy.md · escrow simulated until a CDP key
Fig 2 · One run
Before
Three or more runs of a known-good tablet on this same station make a reference profile: how fast it dissolves and how far the signal moves, colour (blue minus red) for yellow tablets, cloudiness on the side sensor for white ones. Without a profile the answer is Unable to verify, by design. The station’s first profile is not recorded yet.
Bottle
Drug, strength, lot and maker come off the label. The lot is checked against openFDA enforcement reports; the answer is shown as no record for this lot, recall, or lookup unavailable. Never "clear".
Clean water · 10 s
Every second, every LED goes off for a dark reading that cancels room light. Clean water in the cup has to read steady for 10 s. If the lid is open or the blank is noisy, the run does not start.
Tablet in
Opening the lid marks the moment the tablet went in; open longer than 25 s and the run says Unable to verify. The inline sensor watches how much light gets through; the 90° sensor watches how much scatters sideways as the water clouds.
60 s · or 2–10 min
Quick mode: the first 60 s are compared with the reference curve at 5 s checkpoints. Full mode runs until the curve flattens, then checks time-to-80 % and the final level against the spread of good runs. One of three answers, with the reason.
Fig 2b · The run, scene by scene
Scroll, and follow one whole tablet from a bottle label to a payment. Six moments, drawn as an illustration of a passing run: the station’s first reference profile is not recorded yet, so today’s real runs end in Unable to verify.
one tablet · one curve · one answer
Fig 2c · Pill Gate, the station app
The station on the table runs Pill Gate: a guided check that walks one tablet from clean water to an answer in five phases, with the time each one takes on the rail.



Screens from Pill Gate, replaying a recorded run (the top bar says REPLAY (not live))
The station
An Arduino UNO Q runs at 3.3 V with a 12-bit ADC. Once a second it turns every LED off and reads both photoresistors (the dark reading, which cancels room light), then lights blue, white and red in turn and reads again: one photoresistor in line with the beam, one at 90° to it. It prints one CSV line and decides nothing. Pill Gate, on the laptop, builds the curves and matches the run against a reference profile recorded from known-good tablets on the same station.
Three answers, one product
The station says it in words; the clinic app writes the same three answers as PASS / NEEDS LAB / UNABLE TO VERIFY.
Fig 3 · The clinic app
The clinic app runs on a laptop and on your phone. Green means the run matched the reference. Warm red means it did not, and the money stays put. Grey means Pill has nothing to compare against, so it asks a person. This phone replays a simulated curve.
Three outcomes, three screens
the clinic app, replaying simulated curves
Fig 4 · The first real run
Saturday, one aspirin tablet on the UNO Q station. Aspirin is white, so it has no colour to measure: the straight-through red channel moved by only 0.035, while the side sensor’s cloudiness signal rose by 0.29 against a blank noise of 0.006. That is why each profile names the channel to watch. No reference profile is recorded yet, so the station’s answer for this run is Unable to verify.
What is real right now
| Piece | Status |
|---|---|
| Station hardware | Real: Arduino UNO Q, two photoresistors, blue, white and red LEDs, one CSV line a second. One real aspirin run recorded. |
| Station app | Real: analysis, guided run, lid detection, the guardrail; 14 tests pass. A live Claude label read and report ran on a replay of the aspirin run. |
| Reference profile | Not recorded yet. Until it is, the station answers Unable to verify. |
| Label reading, clinic app | Real: Gemini, live. |
| Clinic app curves | Replays of simulated curves, labelled REPLAY. |
| x402 /verify | A real 402, signature checked by the facilitator; the paid 200 is pending a CDP key. |
| USDC escrow | Simulated: nothing moves until a CDP key is in. |
| Nessie mirror | Built, not run. |
Fig 4b · Both apps, screen by screen
Pill Gate runs the station on a laptop; the clinic app runs the delivery, the escrow and the log on a laptop or a phone. Swipe, use the arrows, or the arrow keys.
Clinic mode
A clinic samples one tablet from each delivery. Passed the screen proposes release; Needs lab testing holds the money and drafts a lab referral; Unable to verify escalates. Every decision is logged with the lot, the time, the rule that fired and the policy clause it quotes. No money moves without a pharmacist's tap. Today every money move is simulated: USDC on Base Sepolia once a CDP key is in, with a Capital One Nessie sandbox mirror if its key lands.
policy.md · the six clauses the agent may quote
the three sandbox accounts
A day in a clinic
illustration from the app’s demo data · six of its deliveries on one day
Verdicts by lot and day
Seven days of the app’s seeded deliveries. Each cell is one lot, one tablet, one verdict. Red is kept for a recall; orange waits for a lab; grey asks a person.
illustration from the app’s demo data
Payments
Money in Pill is boring on purpose. The clinic pays a delivery into escrow when it is logged. The station tests one tablet. The policy agent reads the verdict, the recall check and the spend cap, and proposes release, hold or escalate. A pharmacist taps. Only then does USDC move from escrow to the supplier, on Base, signed by the agent's own CDP wallet. The same agent can buy a verdict from someone else's station with x402, a few cents at a time.
Fig 6 · The tree
Measure, three answers, the policy agent, then Coinbase. Under it, how an AI agent pays for a verdict over Coinbase x402. Ink arrows are built; the dashed one is not yet run.
Pricing · proposed
One job: move the money the verdict decides. USDC on Base, from wallets the agent holds but cannot spend without a person. Three uses, one rail.
01 · Pay
The delivery’s money waits in escrow. If the tablet passed the screen, a pharmacist taps release and the agent’s CDP wallet signs the transfer to the supplier. No tap, no transfer.
02 · Buy
With x402 the agent pays per request for a verdict from someone else’s station: no account, no invoice, capped under $1.
03 · Earn
/verify.Each station answers /verify over x402 at 5¢ a verdict (proposed). Send a curve, get one of the three answers and its rule id.
One x402 call, four steps
GET /verify answers with the price: 5¢ in USDC on Base Sepolia.
The buyer’s CDP wallet signs a USDC authorization (EIP-3009). Nothing moves yet.
The facilitator checks the signature and settles the transfer on Base.
The seller answers with the verdict, its rule id and a payment receipt header.
Built withCDP API Key Wallets · CDP Facilitator · @x402/express · CdpX402Client
Where it stands: a real 402 from our server, with the payment signature checked by the facilitator; the paid 200 lands when the CDP key is in. No real payment has happened.
TESTNET today: Base Sepolia, test USDC, no real money. Mainnet is one config line.
Builder feedback
“x402’s auth-capture scheme (authorize now, capture or void later) is exactly an escrow; it isn’t on the public Base Sepolia facilitator yet, so we built escrow with three wallets and a human tap.”
Personal mode
Photograph a new bottle, test one tablet from it, and Pill keeps the result in My medicines with the recall check and a one-tap dose log. It never nags, never tells you to stop a medicine, and says plainly that measuring a dose needs the station.
what it does
what it never does
Fig 5 · What “Passed the screen” does not mean
This one tablet, on this station, dissolved like the good tablets in its reference profile. No red flags found.
That the tablet is the right drug, the right dose, or free of contaminants. Pill checks how a tablet dissolves; it does not identify ingredients. Anything it cannot compare goes to a lab, by design.
the clinic app’s seven rules, in order · N2 belongs to its simulated two-channel reference design
| Rule | Fires when | Verdict |
|---|---|---|
| U1 | No reference for this drug on this station | UNABLE TO VERIFY |
| U2 | Any fault: lid open, sensor saturated, LED dead | UNABLE TO VERIFY |
| U3 | Under 30 s of data, or the reading never settled | UNABLE TO VERIFY |
| N1 | Plateau below the reference band | NEEDS LAB |
| N2 | Plateau in band but the 90° channel did not rise with it | NEEDS LAB |
| N3 | Plateau above the reference band | NEEDS LAB |
| P1 | Plateau in band and the 90° channel rose with it | PASS |
Six questions we expect at the table
It is white, so it has no colour to measure, which is why the side sensor matters: on our first run its cloudiness signal rose by 0.29 against a blank noise of 0.006, while the red channel moved by 0.035. Riboflavin was the first plan, but it absorbs blue so strongly that a whole tablet saturates the cup.
Not today, and it says so: Unable to verify, for any drug without a reference profile on this station. An honest "no reference" beats a guess.
Run ids and timestamps on every curve, the raw trace saved for every run, and a station you can open and look inside. Bring your own tablet.
Nobody. The policy proposes; a pharmacist taps. The model can only downgrade a decision to "escalate", never release.
Because lot numbers get copied. The FDA's December 2025 Ozempic case carried a real lot number. Only the tablet itself cannot lie about dissolving.
Hobby parts: an Arduino UNO Q, two photoresistors, three LEDs, a clear cup and a 3D-printed chamber. One tablet per test and 60 s for a quick run. A new lab dissolution tester typically costs $20,000–$100,000, and a lab result typically takes 7–10 business days.
The team
Every line of firmware, backend and app, the station, the first runs and this page were made during the Cal Hacks 13.0 hacking period. The method is textbook optics: a tablet changes how light crosses a cup of water; two sensors watch it happen. What is new is what the station does with the answer.
where AI is used, and where it is not
built with
Arduino UNO Q · Python · FastAPI · SQLite · anime.js · React · Node + Express · Claude · Gemini · Coinbase CDP + x402 · Capital One Nessie sandbox · openFDA · Google Calendar
Code: private for now; ask us at the table.
What the station is made of
Hobby parts, no lab equipment. Next: a stirrer and a thermistor, so stirring and temperature stop depending on the hand.