Cal Hacks 13.0 · October 2026

The box measures.
Pill explains.

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.

Hobby partsUNO Q, 2 sensors, 3 LEDs
1 tabletper test, destroyed
3 answersnever a guess
Two modesclinic and personal
The Pill station on a table: a purple 3D-printed cylinder with a clear cup of water inside, the purple LED box on its side with white, blue and red LEDs wired in, a photoresistor holder on the left wall, and an Arduino UNO Q with jumper wires in front
the station as built · lid off · the drawing is the same chamber, from the CAD

Film · Saturday night

The pitch, 87 seconds

Filmed at the Palace of Fine Arts, Saturday night. The station says Unable to verify: the bottle said aspirin, the tablet inside wasn't, and there was no matching reference.
01Meet the station.

Fig 1 · The station

Every part, pulled apart.

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

Built Saturday, at the table.

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.

Top view of the station with the lid off and the blue LED on: a clear plastic cup of water inside the purple printed cylinder, blue light at the near wall where the LED box is attached, jumper wires running to the LED legs and to the Arduino UNO Q on the left
Blue LED on, lid off. Light from the LED box (bottom) crosses the clear cup of water in the printed well.
Close-up of the purple LED box on the side of the chamber: a white, a blue and a red 5 mm LED in a row with jumper wires on their legs, two empty holes above and below the blue LED, and a thin slot on top
The LED box. White, blue and red 5 mm LEDs, two spare holes, the diffuser slot on top.
The station with its flat purple lid on, a small hole in the lid, the LED box facing the camera, a photoresistor holder on the left wall with two wires, and a breadboard with resistors and jumper wires in front
Lid on. A flat printed lid with one small hole; a photoresistor holder on the left wall.
Side view: the photoresistor holder at 90° to the beam facing the camera, its two leads coming out through the fin, the LED box on the right, and the Arduino UNO Q on a USB-C cable in front
The 90° holder. The side sensor's leads come out through the fin; the UNO Q streams over USB-C.
Top view with the lid off and the LEDs off: the clear plastic cup of water sitting inside the purple printed well, the LED box below it and the UNO Q at the left edge
LEDs off. The clear plastic cup sits in the well; one whole tablet goes in per test.
The whole station on a table: the purple chamber with its lid, the LED box with its three LEDs, the Arduino UNO Q, a breadboard covered in jumper wires, and a spare purple cup shim ring at the back
Everything. Chamber, LED box, UNO Q, breadboard with the dividers, a spare cup shim ring at the back.

Blueprints

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.

02Why it has to exist.

The problem

One in ten.

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.

1 in 10

medical products in low- and middle-income countries estimated substandard or falsified

WHO, 2017

116,000

extra malaria deaths a year in sub-Saharan Africa, modelled, from substandard and falsified antimalarials (range 64,000–158,000)

LSHTM model, cited by WHO, 2017

>300

children's deaths linked to contaminated cough syrups in three countries, 2022–23, most under five

WHO, Jan 2023

$30.5B

spent each year on substandard and falsified medical products, by WHO's estimate

WHO fact sheet, 2024

7,152pharmaceutical crime incidents logged in 2025 (falsified medicines, diversion and theft), the most on recordPSI
3.7 milliontrademark-infringing pharmaceutical items seized at the US border in fiscal 2024US CBP
1.3 millionMedication errors injure approximately 1.3 million people a year in the United States, according to the World Health Organization (2017). Errors, not falsified medicines: a second way the tablet in hand can go wrong.WHO, 2017
44,000–98,000A 1999 Institute of Medicine report estimated that medical errors in U.S. hospitals cause between 44,000 and 98,000 deaths a year. All medical errors, not drugs alone.IOM, To Err Is Human, 1999
20 daysfrom report to public alert for Uzbekistan's contaminated syrups; about 8 months for falsified Ozempic. Then the alert still has to reach the clinic.WHO alerts
€25.85per sample for the cheapest field screening kit in one 13-country network; a lab result takes 7–10 business daysGPHF Minilab study, 2022

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

03What it is made of.

How Pill works

It dissolves.

Fig 0.1

Chamber

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

The LED box

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

Two photoresistor holders

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

Next: a thermistor

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

Next: a stirrer

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

Arduino UNO Q and breadboard

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

Pill Gate, the station app

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

Sensor → curve → verdict → decision

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

04What one run looks like.

Fig 2 · One run

One tablet, start to answer.

before → 60 s quick
2–10 min full

Before

Good tablets make the reference.

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

Photograph the 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

Dark, then blank.

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

Drop one tablet. Stir by hand.

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

The curve is matched. Pill answers.

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.

05Follow one tablet.

Fig 2b · The run, scene by scene

One tablet, one minute.

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

    06What the judges see.

    Fig 2c · Pill Gate, the station app

    At the table.

    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.

    1. PreparechecksClean water in the cup, lid closed, LED reaching the sensor.
    2. Clean water10 sThe reading has to stay steady for 10 s before a tablet goes in.
    3. Tablet in≈ 10 sOpen the lid, drop the tablet, close it. The lid opening is the tablet-in mark; open past 25 s, the run says Unable to verify.
    4. Dissolving60 sQuick mode: 60 s after the tablet goes in. Full mode stops when the curve flattens, 2–10 min.
    5. ResultautoMatched against the reference profile; one of three answers.
    Pill Gate, Measure step: the phase rail at Prepare, with Quick 60 s and Full 2:00–10:00 modes and the instruction to fill the cup with clean water and close the lid
    01Measure: the phase rail and the clean-water check
    Pill Gate, end of the guided flow: the screening result card with time to 80 percent, final level and run length
    02The guided flow lands on the result card
    Pill Gate result: Unable to verify, because no reference profile was matched; the delivery stays at the gate until the test is repeated
    03Result: Unable to verify, and the delivery stays at the gate

    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

    • Passed the screenPASS
    • Needs lab testingNEEDS LAB
    • Unable to verifyUNABLE TO VERIFY

    The station says it in words; the clinic app writes the same three answers as PASS / NEEDS LAB / UNABLE TO VERIFY.

    07What it says back.

    Fig 3 · The clinic app

    Three answers.
    Never a guess.

    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.

    • P1PASS (Passed the screen): the run sits inside the spread of good tablets on this station.
    • N1NEEDS LAB (Needs lab testing): outside it, slower, weaker, cloudier or clearer than the good ones.
    • U1UNABLE TO VERIFY: no reference for this product, a fault, the lid open too long, or a noisy blank.

    Three outcomes, three screens

    the clinic app, replaying simulated curves

    PASSThe run matched the reference. Release is proposed; a pharmacist taps.
    NEEDS LABThe run fell outside the reference. The payment stays in escrow and a lab referral is drafted.
    Recall on the lotThe label’s lot is on the openFDA recall list. Held, whatever the curve says.

    Fig 4 · The first real run

    One aspirin, one station.

    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

    PieceStatus
    Station hardwareReal: Arduino UNO Q, two photoresistors, blue, white and red LEDs, one CSV line a second. One real aspirin run recorded.
    Station appReal: 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 profileNot recorded yet. Until it is, the station answers Unable to verify.
    Label reading, clinic appReal: Gemini, live.
    Clinic app curvesReplays of simulated curves, labelled REPLAY.
    x402 /verifyA real 402, signature checked by the facilitator; the paid 200 is pending a CDP key.
    USDC escrowSimulated: nothing moves until a CDP key is in.
    Nessie mirrorBuilt, not run.

    Fig 4b · Both apps, screen by screen

    The screens.

    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.

    1. Pill Gate welcome screen with Clinic, Personal and Check modes

      Welcome. Pick clinic, personal or a quick check.

    2. Pill Gate home screen

      Home. The station’s state and the next step.

    3. Pill Gate bottle step

      Bottle. Claude reads drug, strength, NDC, lot, expiry and maker.

    4. Pill Gate measure step with the phase rail

      Measure. The phase rail: clean water 10 s, tablet in, 60 s quick run.

    5. Pill Gate result screen saying Unable to verify

      Result. One of three answers; here Unable to verify, with the reason.

    6. Pill Gate ask screen

      Ask. Questions answered only from the report and its numbered sources.

    7. Pill Gate history screen

      History. Every scan, with its run file and its answer.

    8. Pill Gate reference profiles screen

      Profiles. Reference profiles, built from three or more good runs.

    08Where the answer holds the money.

    Clinic mode

    The verdict holds the payment.

    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

    • P1Release needs PASS, no recall record for the lot, amount within the spend cap, and the pharmacist's tap.
    • P2NEEDS LAB: hold, and draft the lab referral with the curve attached.
    • P3UNABLE TO VERIFY: escalate to a person; no money moves.
    • P4A recall hit on the lot: hold, whatever the curve says.
    • P5Amount above the cap: escalate.
    • P6Recall lookup unreachable: hold until a lookup succeeds or a person overrides.

    the three sandbox accounts

    Clinicpays into escrow when a delivery is logged
    Pill escrowholds until the verdict and the tap
    Supplierreceives on release; refund on hold

    A day in a clinic

    Six deliveries: logged, tested, then released or held.

    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

    09How the money moves.
    Coinbase · x402 · payment agents

    Payments

    The verdict is the invoice.

    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

    How the money moves, and who decides.

    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.

    One rail, simulated todayUSDC on Base Sepolia through a CDP agent wallet; nothing moves until the CDP key is in. A Capital One Nessie sandbox mirror is built for the fiat story and runs only if its key lands. One log line per decision.
    What the agent can doPropose, draft a referral, buy a verdict under $1. It cannot release: release is a human tap, every time, and the model can only downgrade a decision.
    What the agent cannot doHold more than one delivery's value, pay anyone not on the delivery, or move anything on Needs lab testing or Unable to verify. The caps live in policy.md, in plain text.

    Pricing · proposed

    Twenty dollars a station.

    Personal
    $0
    • Phone-only: label read, recall check, dose log
    • No verdicts without a station
    • Photos deleted after the fields are read
    Clinic
    $20per station per month
    • Verdicts, reference profiles, calibration tracking
    • Escrow and release on Base (simulated until a CDP key)
    • Decision log with the rule and clause on every line
    • Station hardware at parts cost: hobby parts
    Verify API
    5¢per verdict, x402
    • Send a curve, get one of the three answers with its rule id
    • No account; the request pays for itself
    • Same seven rules, same rule id on the answer
    Coinbase Developer Platform · x402 · Base

    What Coinbase is for here.

    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

    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.

    02 · Buy

    A verdict from another station, for a few cents.

    With x402 the agent pays per request for a verdict from someone else’s station: no account, no invoice, capped under $1.

    03 · Earn

    Every station sells /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

    402Payment Required

    GET /verify answers with the price: 5¢ in USDC on Base Sepolia.

    signbuyer’s wallet

    The buyer’s CDP wallet signs a USDC authorization (EIP-3009). Nothing moves yet.

    settlefacilitator

    The facilitator checks the signature and settles the transfer on Base.

    200OK

    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.”

    10At home, one bottle at a time.

    Personal mode

    One tablet per bottle.

    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

    • 01Reads the label: drug, strength, lot, maker, expiry. Fields stay editable; the photo is deleted after extraction.
    • 02Checks the lot against openFDA recalls, live or from a dated cache, and says which.
    • 03Keeps one verdict per bottle, from the one tablet you tested, with its two numbers and rule id.
    • 04Logs a dose with one tap. Recall alerts arrive later if the lot is added to the list.

    what it never does

    • —Tell you to stop a medicine, or tell you a tablet is fine to take.
    • —Re-test from the list. Measuring a dose destroys a tablet and needs the station.
    • —Send your photos anywhere. Only the five label fields leave the phone.
    11What it will not claim.

    Fig 5 · What “Passed the screen” does not mean

    Pill screens tablets. A lab has the last word.

    “Passed the screen” means

    This one tablet, on this station, dissolved like the good tablets in its reference profile. No red flags found.

    “Passed the screen” does not mean

    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

    RuleFires whenVerdict
    U1No reference for this drug on this stationUNABLE TO VERIFY
    U2Any fault: lid open, sensor saturated, LED deadUNABLE TO VERIFY
    U3Under 30 s of data, or the reading never settledUNABLE TO VERIFY
    N1Plateau below the reference bandNEEDS LAB
    N2Plateau in band but the 90° channel did not rise with itNEEDS LAB
    N3Plateau above the reference bandNEEDS LAB
    P1Plateau in band and the 90° channel rose with itPASS

    Six questions we expect at the table

    Ask us the hard ones.

    "Why aspirin?"

    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.

    "Would this catch a real antimalarial?"

    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.

    "How do we know the demo isn't rigged?"

    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.

    "Who lets software hold money?"

    Nobody. The policy proposes; a pharmacist taps. The model can only downgrade a decision to "escalate", never release.

    "Why not just scan the barcode?"

    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.

    "What does it cost, really?"

    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

    Built in one weekend, by hand.

    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

    • AIClaude (station) and Gemini (clinic app) read the bottle label into editable fields; Claude writes the two-sentence "why" under a verdict and drafts the decision-log line. Every model sentence passes a word filter.
    • NOTThe verdict, the seven rules, the pass band, and every money movement are deterministic code. The model can only downgrade to "escalate".

    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

    • 01An Arduino UNO Q: 3.3 V, 12-bit ADC, one CSV line a second
    • 02Two CdS photoresistors in 10 kΩ dividers: one in line with the beam, one at 90°
    • 03Blue, white and red 5 mm LEDs, lit in turn
    • 04A clear plastic cup in a purple 3D-printed chamber with a flat lid (one small hole), an LED box and two photoresistor holders
    • 05A wooden stick to stir, and a laptop running Pill Gate

    Hobby parts, no lab equipment. Next: a stirrer and a thermistor, so stirring and temperature stop depending on the hand.