Aptaseek LLC · St. Louis, Missouri
A sample that needs an answer today goes to a lab that answers days later.
Aptastat is being developed as a handheld aptamer-based electrochemical analyzer with a single-use strip per analyte. One prototype reader exists; it is not yet handheld. The first analytes are xylazine and medetomidine, two sedatives now found in illicit fentanyl, and it is being developed for healthcare professionals, emergency medical services, public health officials and law enforcement.
All of that prototype’s hardware data are on a metered resistor. The strips do not exist yet: no aptamer to either drug was found when we searched on 1 October 2026, and no electrochemical cell has been measured on this instrument. It is for research use only. This page keeps what the reader has been measured doing apart from what it is built to do, and lists what has not been measured.
- Instrument — measured on a metered 9.84 kΩ resistor; impedance magnitude repeats to a median 0.57 %
- Assay — not measured: no electrochemical cell, monolayer or aptamer has been measured on this instrument
- Funding — NIH SBIR Fast-Track (R43/R44) application in preparation for the 5 January 2027 receipt date; not submitted, not awarded
Where the lab isn’t
The confirmatory answer in clinical and forensic toxicology is mass spectrometry, and mass spectrometry is a building, a technician and a turnaround. The fastest field answer is an immunoassay strip: one target, yes or no at one cutoff. Between them there is little that healthcare professionals, emergency medical services, public health officials or law enforcement can carry that gives a graded reading rather than a line or no line, and that needs a new strip rather than a new instrument when the supply changes.
An aptamer is a short single strand of DNA selected to bind one small molecule. It is synthesized rather than raised in an animal, and changing what a sensor detects means changing the sequence rather than rebuilding the instrument. Each new strip needs its own aptamer, and each aptamer takes months of selection with no assurance of a binder.
Aptastat is the reader. The recognition chemistry is the part that swaps.
What a strip would be, and the two ways it might be read
This section is a plan, not a result. No strip has been made, and nothing in it has been measured.
01 · The surface
04 · The impedance model
04 · The impedance picture
-
01
The strip and its surface.
Each analyte would have its own single-use strip: a printed gold working electrode carrying a thiol-anchored DNA aptamer, backfilled with mercaptohexanol. The reader has a workflow built to check that such a monolayer actually formed, by comparing a cyclic voltammogram against the bare-gold scan taken earlier on that same electrode — a monolayer that failed to form looks like bare gold, which is exactly what the comparison measures. No strip has been made, and that workflow has never been run on a monolayer.
aptastat/web/plan.py — technique “verify_sam”
-
02
The matched control. — no diagram
Each strip would be read against a scrambled copy of the same strand as its blank: the aptamer’s own bases in a different order. The reader has one measurement channel as built, and the second electrode connection the blank needs is not yet fitted.
app/config.yaml · aptastat/backends/ad5940.py
-
03
Two candidate readouts, undecided. — no diagram
Both candidates are voltammetric, on the reader’s closed potentiostatic loop. One is label-free: a ferri/ferrocyanide redox probe, read as a scramble-subtracted change in the probe’s peak current. The other is square-wave voltammetry of a strand labeled with methylene blue. Both need binding to change the strand’s conformation at the surface, which is not established for the first aptamer to be tried, and the label-free form is not reagentless. The choice has not been made. Either way, the signal would be a measured difference against the scramble, and the planned Phase I gate rests on that difference, not on a fitted parameter.
aptastat/web/plan.py — techniques “cv”, “swv”
-
04
Where impedance fits.
The reader also implements impedance spectroscopy: a small-signal AC excitation — 10 mV rms by default — swept across frequency, with the spectrum fitted to a Randles equivalent circuit. On a surface that blocks a redox probe such a fit returns a charge-transfer resistance, the diameter of the semicircle on a Nyquist plot, and that is what the two diagrams above illustrate. Impedance is behind every measured figure on this page, all of them on a resistor. It is not the planned readout, and no planned milestone rests on a fitted charge-transfer resistance.
aptastat/web/plan.py — technique “eis”, ac_amplitude_mv
What this section is careful about.
An electrochemical signal at a surface is sensitive to everything that changes that surface, not only to binding. That is why the matched scramble, the per-electrode baseline and the monolayer check are parts of the planned measurement rather than options in it. A number printed without them is not a result.
What the box actually does
- Techniques
- Four measurement techniques are implemented: impedance spectroscopy, cyclic voltammetry, square-wave voltammetry and chronoamperometry. Six guided workflows are built on them — electrode clean, monolayer verification, baseline capture, replicates, titration, time course — beside a self-test and a quality-control check. All four techniques have run on hardware, on the resistor only. The instrument builds every setup form from these declarations, so a parameter this hardware does not have cannot appear on the screen. aptastat/web/plan.py — SPECS
- Frequency
- Settable from 0.0448 Hz to 160 kHz, log-spaced, up to 4,096 points in one sweep; the sweeps reported on this page span 1 Hz to 150 kHz. The bounds are not written down: they are derived at import from the firmware’s own band table and rounded inward, so the form cannot offer a frequency the shim will refuse. aptastat/web/plan.py — _band_bounds() · aptastat/backends/eis_bands.py
- Working ceiling
- About 150 kHz. The 160 kHz figure is the top band’s DFT Nyquist; above roughly 150 kHz a metered resistor reads visibly low, and the instrument says so in the field’s own help text rather than quoting the higher number. aptastat/web/plan.py — f_start_hz help text
- Excitation
- 0.1 to 600 mV rms; 10 mV default. aptastat/web/plan.py
- Transimpedance
- Two ladders, mirrored from the firmware’s C tables rather than assumed: eight rungs, 200 Ω to 160 kΩ, on the impedance path; twenty-six rungs, 200 Ω to 512 kΩ, on the voltammetry path. A requested value off the ladder is snapped to the nearest rung, and the run records the value used, not the value asked for. aptastat/backends/rtia.py
- Front end
- Analog Devices AD5940 (EVAL-AD5940ELCZ) on a Raspberry Pi 5 over SPI0. DESIGN.md §1–2 · POWER.md §3.1
- Electrodes
- One working-electrode connection as built. Channel selection through an ADG5208 8:1 analog switch is written in software and not fitted; the backend accepts switch positions 0 through 7. app/config.yaml · aptastat/backends/ad5940.py
- Runtime
- Not measured. A power budget gives about 5.4 hours for a ~50 Wh 2S2P pack at a 7.5 W system average, on a 90 % usable / 90 % conversion basis. That is a calculation for the pack the design recommends, not a battery test. The prototype runs on an off-the-shelf four-cell battery board instead, and that board has an open charging fault. POWER.md §2.2–2.3, §4
- Software
- One Python codebase for the instrument’s 7-inch panel, the desktop application and the installable phone app, against one API.
The app on this page is the instrument’s own screen
-
It saves first. The run is on the instrument’s own card before anything is queued to go anywhere. The network is a second destination, never a dependency — a run taken where there is no signal is saved exactly as durably as one at a bench on fiber. What the queue holds is a pointer, not a payload, so a crash mid-upload cannot lose a run; and a run that cannot be uploaded is reported rather than quietly dropped.
aptastat/cloud/outbox.py
-
It opens with no signal. Install it on a phone home screen and it opens to the runs you last looked at — labeled as cached, rather than presenting month-old runs as current. Arming, starting and stopping are never cached: a stored “armed” would be a lie about custody of a physical instrument.
aptastat/web/static/sw.js
-
Colors, icons and the web manifest are generated at request time from one palette file, so the icon on somebody’s home screen cannot drift from the mark on the instrument’s own display. A test pins the two together.
aptastat/web/icons.py
One door, and the instrument holds it.
An Rct is a fit, and a fit can fail to support the number it produces. On the reader exactly one piece of code decides whether that number gets printed, and it runs on the instrument, at the moment of the measurement. Today that holds for impedance fits only; the voltammetric peak finders, which either planned readout would use, do not yet refuse, and they reported peaks on the resistor. What that code decided is stored with the run, and it is what every screen shows afterward — this app, the instrument’s own panel, the desktop application. Nothing here recomputes anything. Where the fit did not support a figure you see that it was withdrawn, rather than a browser’s guess at what it might have been.
The mirror holds the instrument’s own read-out, not the raw material for someone else’s.
aptastat/summary.py, module docstring
What it has been measured doing
Everything in this section was taken on a metered 9.84 kΩ resistor, not on a cell. Read it as a statement about the measurement core.
Sixteen repeat sweeps, 2026-09-07, on a metered resistor.
Read 9,855.7 Ω against the resistor’s metered 9,840 Ω. Eight sweeps, 2026-09-08. The ohm scale was set against this resistor and a second metered one, so this shows self-consistency, not accuracy. Across the sixteen sweeps of 2026-09-07, per-frequency mean readings lay between 2.9 % below and 1.9 % above 9,840 Ω.
At 5,336.92 Hz, in the same sixteen sweeps of 2026-09-07.
Across the eight sweeps of 2026-09-08.
app/AUDIT-2026-09.md §1 · aptastat/analysis/diagnostics.py — spectrum_spread, kk_test
On provenance: the 2026-09-08 spectra carry a full provenance
header, and it is not clean — those runs are flagged DEGRADED-POINTS,
their header leaves the electrode route undeclared, and the 0.15 V bias they
requested was not applied. The 2026-09-07 spectra carry no provenance header at
all: the recording machinery did not exist yet. Both sets were taken on the
metered resistor; where a record does not name it, the load is identified by the
bench runbook and by the readings themselves. Neither was taken on a cell. The
repeatability figures are agreement between repeats of one measurement with no
bias applied, which is what they are offered as.
And the figure that was wrong for two weeks
For two weeks this project’s stated blocker was that repeat sweeps spread about 20 %, against an assumed binding signal of about 12 %. The conclusion drawn from it — that no aptamer result would mean anything until the hardware improved — was wrong, and it cost two weeks.
The 20 % was the spread of Rct, a fitted parameter, measured on a pure resistor. A resistor has no charge-transfer arc for Rct to describe, so fitting Rs + Rct∥CPE + Warburg to a plain resistance is unidentifiable by construction, and the fit had said so all along: across the eight sweeps of 2026-09-08 the one-sigma uncertainties ran as high as 1.24 × 109 Ω. The code computed them correctly and the store persisted them. Nothing displayed them.
Recomputed on |Z|, a quantity that exists in that load, the stored sweeps spread 0.57 % on 2026-09-07 and 0.59 % on 2026-09-08. On those same sweeps the fitted Rct scatters by 164 % and 54 %; the 20 % was the figure quoted at the time.
Two things changed as a result, and both are in the instrument rather than in a document. A diagnostics module was added so dispersion is computed on a quantity that exists in the load being measured. And the standing rule is now written down: before believing a dispersion figure, check what quantity it was computed on and whether that quantity is identifiable in the load.
app/AUDIT-2026-09.md §1 · evidence/README.md — the fitted scatter, re-derived
What has not been demonstrated
This instrument has a verdict called INDETERMINATE. It means measured, cannot be judged, and it exists so that a run the analysis cannot support is never reported as one it can. It is not a shade of WARN: WARN is defined as a reading in the equivocal band and would ask the operator to treat the sample as suspect, while INDETERMINATE asks them to re-prep and re-run the electrode. It keeps its Rct, reports no concentration, and can seed neither a baseline nor a control reference. Today only impedance fitting returns it: the voltammetric peak finders do not yet, and they reported peaks on the resistor. The archived resistor runs predate the present configuration; 33 of them were stored as PASS or WARN under placeholder thresholds, which is why only raw magnitude is quoted here. The same standard applies to this page.
app/README.md — Verdicts · evidence/README.md — the stored verdicts
No binding data on this instrument.
Every figure in the section above was taken on a metered resistor. No electrochemical cell, no monolayer and no aptamer-modified electrode has been measured here. The assay is unproven on this device. A first measurement on a real electrochemical cell, and then a first binding curve, are the next things the work has to do.
app/AUDIT-2026-09.md §1
As configured today, the impedance path does not hold a commanded potential.
The front end has two analog paths. As configured today, with the excitation amplifier’s sense input on the counter electrode, the impedance path does not hold a commanded potential. In one seven-point scan on the metered resistor, Eachieved = 0.987 · Erequested − 0.438 V — an offset about one and a half times the whole requested range of 0 to +0.300 V, so every request in that scan arrived as a negative potential. That fit is a snapshot: over 42 minutes at a constant +0.300 V request the achieved potential ranged from −0.277 to +0.083 V across six readings. With a bias requested, the resistor’s reported impedance magnitude followed the achieved potential, at about −23 % per volt in a second seven-point scan, and not reproducibly. The cause is not established. It is treated as a fault to diagnose, not a constant to correct for, and diagnosing it on a real cell, against a commercial potentiostat, is planned work. Meanwhile the configuration ships with its bias at 0.0 V, and the instrument measures the standing potential rather than asserting one, badges the run UNBIASED-OFFSET, and refuses a biased sweep that fails an absolute potential check. The repeatability figures above are from sweeps with no bias applied. No planned readout rests on this path. Voltammetry runs on the other path, which closes a potentiostatic loop; that loop’s offset has not yet been measured against an independent instrument.
app/config.yaml — sweep.dc_bias_v · app/pi-ad5940-shim/README.md, lines 131 and 1544–1617 (the measurements; the cause those files propose is not established)
We found no report of the first aptamer to be tried on printed gold, and we have not made that surface.
20DF42 (Samuelian & Baum, Analysis & Sensing 2022, 2(6):e202200044) is a published DNA aptamer to benzodiazepines, not to either sedative this reader is being developed for. Its paper reports in vitro selection, dissociation constants measured in solution, and a strand-displacement fluorescence-polarization sensor in solution. We found no report of 20DF42 as a thiol monolayer on printed gold, and we have not made one. It is planned as the first test of whether this reader can read aptamer binding on a strip: the planned Phase I gate is a titration of surface-bound 20DF42 with diazepam or alprazolam, in buffer, read against its base-matched scramble.
Samuelian & Baum 2022
“Benzodiazepine” is a class, and this aptamer does not cover it.
The 20DF42 paper reports solution dissociation constants of 0.2 to 0.6 µM for diazepam, alprazolam and their metabolites, and little or no binding to lorazepam or clonazepam. We have no binding data for the designer benzodiazepines (etizolam, bromazolam, flualprazolam, clonazolam). 20DF42 is a model for testing the reader and the surface, not a planned product strip. The rule it illustrates is general: a strip labeled by drug class would falsely reassure on a sample containing a member the aptamer does not bind, so a strip would be labeled by the analyte it was calibrated against and the analogs it is documented to bind, or not labeled.
Samuelian & Baum 2022
The shipped configuration names no analytes.
The channel configuration ships with every analyte field empty, on purpose. Three example channels were removed in September 2026 because they were examples and not analytes anyone had calibrated on this instrument. An analyte name is what binds a calibration curve to a channel, and a curve that converts a measured change into a concentration for a substance nobody calibrated against is the one way this device will print a confident number it has not earned.
app/config.yaml — channels
The SBIR application is not submitted, and nothing is awarded.
An NIH SBIR Fast-Track (R43/R44) application is in preparation for the 5 January 2027 receipt date. It has not been submitted. No work described on this page was funded by it.
Safety and disclaimer
This is an early proof-of-concept, for research use only. It is not a certified medical or forensic device and is not for use in diagnostic procedures. Readouts depend on aptamer selectivity, probe chemistry and per-device calibration; treat WARN/DETECTED as screening indications, not confirmatory results, and confirm them with an orthogonal method.
app/README.md — Safety / disclaimer
Who built it, and who is planned
Ali Parvez — Electronics and PCB design. Built the reader, its firmware bridge and its software, as described on this page.
Dana A. Baum, PhD — Aptamer chemist; corresponding author of the paper that reports 20DF42. An NIH application in preparation plans her as a second principal investigator, with her laboratory doing the aptamer surface chemistry and selection under a subaward. That is planned. Nothing is agreed in writing.
On data
The cloud mirror holds specimen codes, never identities — no name, no medical record number, no date of birth. There is no self-registration; an administrator creates accounts. Results are displayed for a specimen code rather than as a clinical interpretation for a patient. Runs are stored as the instrument wrote them, byte for byte, so the desktop application reads back exactly what the device held rather than a re-serialization of it. Records are retained for ten years by default.
infra/mirror.yaml · app/DESK-AND-CLOUD.md §1
It does not drive the instrument. Setting up and starting a run happens on the instrument’s own network, by someone who can see the cell. A stop button on a page with no instrument behind it is an invitation to believe there is one.
aptastat/web/static/app.js
If you are reading this to decide something
- Program officers and funders — the preliminary data behind the figures above are available on request.
- Collaborators with an aptamer — if you have a sequence with solution-phase affinity data and want to know whether it survives as a surface, that is precisely the question this instrument was built to answer. It has not yet answered it for any sequence; the first attempt is the planned work described above.
- Healthcare professionals, emergency medical services, public health officials and law enforcement — the instrument is for research use only, and we are not ready for a field evaluation. We would like to talk to you about what one would have to prove first.