====== Spad Electronics Board — Technical Summary ====== ===== Firmware Lineage ===== No public Spad-specific repo found. Lineage traced: * **MIDIsprout v0.21** (''github.com/electricityforprogress/MIDIsprout'') — base sensing/MIDI code, MIT licensed, no scale/menu selection. * **Sam Cusumano's "shield" firmware v026** (''github.com/electricityforprogress/BiodataSonificationBreadboardKit'') — adds button+knob menu system for live Threshold, Scale, Channel, LED Brightness selection. * **Leetronics fork** (''https://github.com/leetronics/midi-biodata'') — ports v026's menu features onto the classic MIDI Sprout board layout. * **Spad Electronics** — per third-party comparison (Gearspace forum), described as same hardware/software as the Leetronics version. ===== Sensing Circuit ===== Two leaf/skin probe electrodes wired in series with a fixed 100K resistor (R2), into a 555 timer in **astable** configuration, with a fixed .0042µF timing capacitor (C1). * Leaf resistance is the only variable in the RC network — this measures **resistance** (ionic conductance through leaf fluid), not capacitance. * Higher leaf resistance → longer 555 oscillation period. * Lower resistance (more conductive) → shorter period. * Contrast this with capacitive sensing (SFCS/touch, digital-pin capsense) which fixes R and varies C instead ===== Sampling ===== * 328p MCU interrupt fires on every **rising edge** of the 555 output (''attachInterrupt(..., RISING)'') — one timestamp per oscillation period. * 10 consecutive period values collected into an array per cycle. ===== Analysis (''analyzeSample()'') ===== Once the array fills, computed over the sample window: * ''averg'' — mean of the samples * ''delta'' — max minus min (spread across the window) * ''stdevi'' — standard deviation of the samples **Trigger condition** (does a note fire at all): ''delta > stdevi * threshold'' (threshold default 2.3) ===== Note Mapping (if triggered) ===== ^ Output ^ Driven by ^ Logic ^ | Pitch | ''averg'' (average resistance level) | ''map(averg % 127, 1, 127, noteMin=36, noteMax=96)'', then snapped to nearest note in selected scale | | Duration | ''delta'' (magnitude of swing) | ''150 + map(delta % 127, 1, 127, 100, 2500)'' ms | | Velocity | fixed | always 100, not sensor-derived | | CV ramp rate | ''delta % 127'' | sets analog control-voltage slide rate | * Higher average resistance → higher pitch (not lower). * ''%127'' folds unbounded microsecond values into MIDI's 7-bit range — a modulo wrap, not a calibrated scale. Monotonic only within each 127µs wrap-band, not globally across the full sensor range. ===== v0.21 vs v026 Diff (confirmed) ===== **Identical** (line-for-line, confirmed by direct diff): * ''sample()'' — byte-for-byte identical * ''analyzeSample()'' — identical except one substitution (below) * ''setNote()'', ''setControl()'', ''checkControl()'', ''checkNote()'', ''MIDIpanic()'', ''midiSerial()'' * ''readVcc()'', ''checkBattery()'', ''bootLightshow()'', ''mapfloat()'', ''freeRAM()'', ''rampUp()'', ''rampDown()'', ''checkLED()'' * ''scaleNote()'', ''scaleSearch()'' * Core constants: ''noteMin=36'', ''noteMax=96'', ''samplesize=10'', ''threshMin/Max = 1.61/3.71'', ''batteryLimit=3000'' **Added in v026** (UI/config layer only, sensing math untouched): * Scale selection: v0.21 uses ''scaleSelect'' (one fixed array, compile-time only). v026 uses ''scale[currScale]'' (5 arrays: Chromatic/Major/DiaMinor/Indian/Minor), runtime-selectable via menu. * Full button+knob menu system (''checkMenu()'', ''thresholdMode()'', ''scaleMode()'', ''channelMode()'', ''brightnessMode()'') — v0.21 has only empty stubs (''checkButton()'', ''knobMode()''). * Threshold: v0.21 sets continuously every loop directly from the knob. v026 only adjusts threshold inside the menu; persists after exit. * MIDI channel: fixed constant in v0.21; runtime-adjustable in v026. * LED brightness: fixed in v0.21; runtime-adjustable in v026. * ''EEPROMex.h'' included in v026 but no read/write calls found — likely unused/vestigial. **Conclusion:** v026 (and by extension Leetronics/Spad) = v0.21's sensing/analysis core, unmodified, with a menu/config layer bolted on top. ===== Alternative Two-Electrode Bioelectric Method (for contrast — NOT what Spad uses) ===== * Passive — no injected signal, no RC network, no 555. * Reads the plant's own native millivolt-scale bioelectric activity (action potentials, slow-wave potentials) via AC-coupled high-gain instrumentation amplifier (e.g. AD8232). * Electrode damage/longevity problem with penetrating electrodes → SWCNT nanofilm electrodes identified as best non-invasive option (2+ months stable, documented light-induced biopotential response).