Skip to content

Latest commit

 

History

History

firmware

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

README.md

NeuroFocus Mark 3 firmware

Modular Arduino / PlatformIO firmware for:

Board Netlist Role in firmware
Main nf-mark3-main.tel Full: ADS1220 + LEDs + button + battery
AFE nf-mark3-afe.tel OUT0 path (preset p0)
Expansion nf-mark3-expansion.tel Same SPI master code, external strip

Layout

firmware/
├── platformio.ini          # seeed_xiao_esp32s3 + native tests
├── include/nf/             # public headers (documented)
│   ├── AppConfig.h         # defaults & why they exist
│   ├── BoardPins.h         # pin ↔ netlist map
│   ├── ChannelMap.h        # OUT* → ADS1220 mux plans
│   ├── Voltage.h           # raw → V / µV / battery
│   ├── StreamFormat.h      # plotter / CSV / JSON
│   ├── CommandParser.h     # CLI parse (unit-tested)
│   ├── Ads1220Driver.h     # SPI ADC
│   ├── StreamEngine.h      # capture + print
│   ├── CommandShell.h      # serial shell
│   ├── StatusLeds.h
│   ├── UserButton.h
│   └── BatterySense.h
├── src/main.cpp            # wiring only
└── test/                   # pio test -e native
    ├── test_channel_map/
    ├── test_commands/
    ├── test_voltage/
    └── test_stream_format/

Build / flash / test

cd firmware
pio run -t upload          # flash XIAO
pio device monitor -b 115200
pio test -e native         # host unit tests (no board)

Demo (OUT0)

  1. Flash and open serial @ 115200
  2. Confirm ADS1220 OK
  3. Press b (or SW2)
  4. Open Serial Plotter — one raw count per line
  5. s to stop

Command reference

Input Action Why it exists
b / s / v Start / stop / soft-reset OpenBCI-compatible hosts
p0 OUT0 vs AVSS Default AFE / single-ended demo
p1 OUT0 vs OUT3 Differential with ref on AIN3
p2 Scan 4× SE Exercise all H8/H9 nets
p3 Scan ref-to-OUT3 Legacy multi-channel montage
p4 OUT0 vs OUT1 Tight differential pair
f0 f1 f2 f3 raw / csv / µV / json Plotter vs logging vs science
r0–r6 ADS1220 data-rate level Speed vs noise trade
g1…g128 PGA gain Only if you disable bypass
pga0 / pga1 Bypass PGA on/off AFE already gains — default bypass
bat Pack voltage LiPo safety / logging
temp ADS1220 die °C Sanity / thermal
test AVDD monitor self-test SPI bring-up
blink LED check Carrier assembly
i / status Dump config Debug without recompile
? / help This list —

SW2 toggles stream without a keyboard.

Config variables (AppConfig.h)

Symbol Default Why
kVrefVolts 3.3 REFP0≈VCC on carrier
kBypassPgaDefault true AD8422 is the gain stage
kDefaultDataRateLevel 2 ~90 SPS, plotter-friendly
kDefaultPreset OUT0_SE Reliable single-channel demo
kDefaultFormat RawLine Serial Plotter
kAfeGainDefault 1.0 Report ADC-pin µV until Rg known
kDrdyTimeoutMs 50 Never hang CLI on dead ADC
kBatRTop/Bottom 220k/220k Match R3/R4 netlist

Possibilities unlocked

  1. Bench OUT0 — continuous ADC, plotter
  2. 4-ch scan — p2/p3 + f1 CSV to a host logger
  3. Differential pair — p4 or p1
  4. Science units — f2 with real afeGain
  5. Structured log — f3 JSON lines
  6. Hands-free — SW2 start/stop
  7. Field power — bat before long capture
  8. Expansion strip — same SPI, external board
  9. Self-test — test after assembly
  10. Rate/gain sweep — r* / g* without reflash

Hardware notes

  • Open OUT0 may sit mid/full-scale — connect AFE or a known voltage for a real wave.
  • Single-ended p0 uses AIN0–AVSS; true bipolar EEG montages prefer p1/p3.
  • Expansion has no battery net / button — those APIs no-op or float if pins unconnected.