SCPI Command Reference

SCPI Parameter Syntax

Hexadecimal #HFF
Octal #Q77
Binary #B11
String “text”, ‘text’ String parameters must be enclosed in single or double quotes. Always quote any free-form string — filenames, paths, SSIDs, passwords, IP addresses, hostnames. Example: SYSTem:COMMunicate:LAN:SSID "test me", SYSTem:WIFI:IPERF:TCPClient "192.168.1.133",5001,10, SYSTem:STORage:SD:GET "data.csv". Unquoted strings only work for plain SCPI keywords (uppercase letters and digits, no dots, no special characters) such as ON/OFF/AUTO. A bare dotted-decimal IP like 192.168.1.133 is parsed as a malformed number and rejected with -101 "Invalid character" — quote it.

Quiescence Rule — No Queries During a Benchmarked Test

Send no SCPI commands while a streaming or iperf2 test is running. Every
query preempts the data path you’re measuring (USB SCPI = priority 7; TCP
SCPI runs on the WifiTask itself), so polling skews the result.

The firmware preserves end-of-test stats in IDLE: IPERF:STATs? returns
gCtx.last_stats (frozen by FinalizeStats); STR:STATS? survives across
StopStreamData until the next StartStreamData or STATS:CLEar.

Pattern: start → time.sleep(duration + margin) → single STATS query.

For progress visibility on long runs, use an out-of-band signal (Saleae,
PC-side iperf2.log) — never poll the device under test.

List of SCPI Commands

IEEE 488.2 Standard Commands

SCPI Command Description Example Firmware Callback
*IDN? Get device identification: manufacturer, model, serial, firmware version *IDN? SCPI_CoreIdnQ
*CLS Clear status registers and error queue *CLS SCPI_CoreCls
*ESE Set event status enable register *ESE 255 SCPI_CoreEse
*ESE? Get event status enable register *ESE? SCPI_CoreEseQ
*ESR? Get event status register (clears on read). Bit 5 = command error, bit 0 = OPC *ESR? SCPI_CoreEsrQ
*OPC Set operation complete bit in ESR when all pending operations finish *OPC SCPI_CoreOpc
*OPC? Query operation complete (returns 1 when all operations done) *OPC? SCPI_CoreOpcQ
*SRE Set service request enable register *SRE 255 SCPI_CoreSre
*SRE? Get service request enable register *SRE? SCPI_CoreSreQ
*STB? Get status byte register. Bit 2 = error queue not empty, bit 7 = operation status *STB? SCPI_CoreStbQ
*TST? Run self-test (returns 0 = pass) *TST? SCPI_CoreTstQ
*WAI Wait for all pending operations to complete *WAI SCPI_CoreWai

Error and Status Commands

SCPI Command Description Example Firmware Callback
SYSTem:ERRor? Pop oldest error from SCPI error queue (FIFO, 17 slots). Returns error code and description. Returns 0,"No error" when queue is empty. SYSTem:ERRor? SCPI_SystemErrorNextQ
SYSTem:ERRor:NEXT? Alias for SYSTem:ERRor? SYSTem:ERRor:NEXT? SCPI_SystemErrorNextQ
SYSTem:ERRor:COUNt? Get number of errors in the SCPI error queue (non-destructive) SYSTem:ERRor:COUNt? SCPI_SystemErrorCountQ
SYSTem:VERSion? Get SCPI standard version (returns “1999.0”) SYSTem:VERSion? SCPI_SystemVersionQ
STATus:QUEStionable? Get questionable event register (clears on read) STATus:QUEStionable? SCPI_QuesEventQ
STATus:QUEStionable:EVENt? Get questionable event register (clears on read) STATus:QUEStionable:EVENt? SCPI_QuesEventQ
STATus:QUEStionable:CONDition? Get questionable condition register (real-time, does not clear on read) STATus:QUEStionable:CONDition? SCPI_QuesConditionQ
STATus:QUEStionable:ENABle Set questionable status enable mask STATus:QUEStionable:ENABle 255 SCPI_StatusQuestionableEnable
STATus:QUEStionable:ENABle? Get questionable status enable mask STATus:QUEStionable:ENABle? SCPI_StatusQuestionableEnableQ
STATus:OPERation? Get operation event register (clears on read). Shorthand for STATus:OPERation:EVENt? per SCPI standard. Returns 0 until firmware sets condition bits. STATus:OPERation? SCPI_StatusOperationEventQ
STATus:OPERation:EVENt? Get operation event register (clears on read) STATus:OPERation:EVENt? SCPI_StatusOperationEventQ
STATus:OPERation:CONDition? Get operation condition register (real-time, does not clear on read) STATus:OPERation:CONDition? SCPI_StatusOperationConditionQ
STATus:OPERation:ENABle Set operation status enable mask (controls which bits propagate to *STB?) STATus:OPERation:ENABle 255 SCPI_StatusOperationEnable
STATus:OPERation:ENABle? Get operation status enable mask STATus:OPERation:ENABle? SCPI_StatusOperationEnableQ
STATus:PRESet Reset all status enable registers to default values STATus:PRESet SCPI_StatusPreset

OPERation Condition Register Bits

The firmware sets these bits in the OPER condition register to reflect real-time device state:

Bit Value Name Description
4 16 Measuring Streaming/measuring is active
10 1024 SD Logging SD card logging is active

Bits are set on STR:START and cleared on STR:STOP.

QUEStionable Condition Register Bits

The firmware sets these bits in the QUES condition register to reflect streaming health:

Bit Value Name Description
4 16 Data Loss Windowed sample loss >= threshold (default 5%, configurable via SYST:STR:LOSS:THREshold)
8 256 USB Overflow USB circular buffer overflow detected
9 512 WiFi Overflow WiFi circular buffer overflow detected
10 1024 SD Overflow SD write failure detected
11 2048 Encoder Fail Encoder returned 0 bytes with data available

QUES bits are set in real-time during streaming and cleared when streaming stops. The QUES CONDition register reflects current health; the QUES EVENt register latches transitions (clears on read).

System Commands

SCPI Command Description Example Firmware Callback
SYSTem:REboot Reboots the device immediately. Returns “System reset initiated” before restarting SYSTem:REboot SCPI_Reset
help Display available SCPI commands help SCPI_Help
SYSTem:SYSInfoPB? Returns protobuf message with board information – actual message fields are listed below this section SYSTem:SYSInfoPB? SCPI_SysInfoGet
SYSTem:INFo? Get human-readable system information including detailed power state names (STANDBY, POWERED_UP, etc.), battery voltage, charge state, network config, and system status SYSTem:INFo? SCPI_SystemInfo
SYSTem:LOG? Get system log entries (dumps all, clears buffer). Also resets one-shot suppression flags so ISR one-shot log sites can fire again. Independent from SCPI error queue. 64 entries x 128 bytes, circular buffer. SYSTem:LOG? SCPI_SysLogGet
SYSTem:LOG:CLEar Clear log buffer without reading. Also resets one-shot suppression flags. SYSTem:LOG:CLEar SCPI_SysLogClear
SYSTem:LOG:TEST Add test messages to log buffer (for verification) SYSTem:LOG:TEST SCPI_SysLogTest
SYSTem:LOG:LEVel Set runtime log level for a module. Module names: POWER, WIFI, SD, USB, SCPI, ADC, DAC, STREAM, ENCODER, GENERAL. Levels: 0=NONE, 1=ERROR, 2=INFO, 3=DEBUG. Each module is clamped to its compile-time ceiling (all modules: DEBUG). Runtime-only, resets on reboot. SYST:LOG:LEV STREAM,2 SCPI_SysLogLevelSet
SYSTem:LOG:LEVel? Query runtime log level. With module name returns integer level; without parameter dumps all modules with levels and ceilings. SYST:LOG:LEV? STREAM / SYST:LOG:LEV? SCPI_SysLogLevelGet
SYSTem:LOG:LEVel:ALL Set all modules to the same runtime log level. Each module still clamped to its compile-time ceiling. SYST:LOG:LEV:ALL 3 SCPI_SysLogLevelAllSet
SYSTem:LOG:CMDHistory? Get recent SCPI command history SYSTem:LOG:CMDHistory? SCPI_SysLogCmdHistory
SYSTem:ECHO Set echo for use with terminal/human readable. Default = 1. SYSTem:ECHO -1 turns off all echoed characters. SYSTem:ECHO 0 turns off echo but leaves DAQiFi> prompt. SYSTem:ECHO 1 turns on echo. SCPI_SetEcho
SYSTem:FORceBoot Force device to enter bootloader mode for firmware updates SYSTem:FORceBoot SCPI_ForceBootloader
SYSTem:SERialNUMber? Get device serial number in SCPI hex format (#H prefix followed by 16 hex digits) SYSTem:SERialNUMber? SCPI_GetSerialNumber
SYSTem:USB:TRANSparent:MODE Set USB transparent mode for WiFi radio firmware updates (0=SCPI mode, 1=transparent mode) SYSTem:USB:TRANSparent:MODE 0 SCPI_UsbSetTransparentMode
SYSTem:COMMunication:TCPIP:CONTROL? (not implemented) SCPI_NotImplemented

Power Commands

SCPI Command Description Example Firmware Callback
SYSTem:POWer:SOURce? Get external power source type (0=none, 1=unknown, 2=1A charger, 3=2A charger, 4=USB 100mA, 5=USB 500mA) SYSTem:POWer:SOURce? SCPI_PowerSourceGet
SYSTem:BAT:LEVel? Get battery charge level percentage (0-100). Returns -1 when device is in STANDBY mode (battery monitoring inactive) SYSTem:BAT:LEVel? SCPI_BatteryLevelGet
SYSTem:POWer:STATe? Get power state. Returns binary values:
0 = STANDBY (device in low-power mode)
  – On USB power: MCU remains on, 3.3V rail enabled
  – On battery power: MCU powers off to save battery
1 = POWERED (device fully operational)
  – Maps to internal states POWERED_UP or POWERED_UP_EXT_DOWN
  – All systems operational, ADC readings valid

Device automatically manages 3.3V rail to prevent power loss on USB disconnect
SYSTem:POWer:STATe? SCPI_GetPowerState
SYSTem:POWer:STATe Set power state:
0 = STANDBY (low-power mode)
1 = POWERED (fully operational)
SYSTem:POWer:STATe 1 SCPI_SetPowerState
SYSTem:POWer:OTG? Get OTG boost mode status (0=off, 1=on) SYSTem:POWer:OTG? SCPI_GetOTGMode
SYSTem:POWer:OTG Set OTG boost mode:
0 = Disable OTG
1 = Enable battery boost operation

Notes:
• OTG provides 5V output from battery
• Cannot be enabled while USB is connected
• Disable when no longer needed to save battery
SYSTem:POWer:OTG 1 SCPI_SetOTGMode
SYSTem:FORce5V5POWer:STATe Force enable/disable external 5V supply (overrides automatic control) SYSTem:FORce5V5POWer:STATe 1 SCPI_Force5v5PowerStateSet
SYSTem:POWer:AUTO:EXTernal Set auto-external power behavior SYSTem:POWer:AUTO:EXTernal 1 SCPI_SetAutoExtPower
SYSTem:POWer:AUTO:EXTernal? Query auto-external power setting SYSTem:POWer:AUTO:EXTernal? SCPI_GetAutoExtPower

BQ24297 Battery Charger Diagnostics

SCPI Command Description Example Firmware Callback
SYSTem:POWer:BQ:REGisters? Dump all BQ24297 registers (REG00-REG0A hex values) SYSTem:POWer:BQ:REGisters? SCPI_BQ24297Registers
SYSTem:POWer:BQ:ILIM Set IINLIM directly (0=100mA, 2=500mA, 6=2A, 7=3A) SYSTem:POWer:BQ:ILIM 2 SCPI_BQ24297SetILIM
SYSTem:POWer:BQ:DPDM Force D+/D- re-detection. WARNING: Disrupts USB connection — requires cable replug to recover. Diagnostic only. SYSTem:POWer:BQ:DPDM SCPI_BQ24297ForceDPDM
SYSTem:POWer:BQ:FAULT:CLEar Clear latched BQ24297 fault flags SYSTem:POWer:BQ:FAULT:CLEar SCPI_BQ24297FaultClear
SYSTem:POWer:BQ:DIAGnostics? Comprehensive diagnostics: battery state, registers, GPIO, IINLIM state machine, power state, VBUS level. Note: reads REG09 which clears latched fault flags. SYSTem:POWer:BQ:DIAGnostics? SCPI_BQ24297Diagnostics

DIO Commands

SCPI Command Description Example Firmware Callback
DIO:PORt:DIRection Sets Digital Port Direction. First parameter is the DIO number. Second parameter is for Direction, ‘0’ for input and ‘1’ for output. DIO:PORt:DIRection 0,1 SCPI_GPIODirectionSet
DIO:PORt:DIRection? Gets Digital Port Direction. Parameter passed is the DIO number whose Direction needs to be checked. DIO:PORt:DIRection? 0 SCPI_GPIODirectionGet
DIO:PORt:STATe Sets Digital Port State. First parameter is the DIO number. Second parameter is for State, ‘0’ for LOW State and ‘1’ for HIGH State. DIO:PORt:STATe 0,1 SCPI_GPIOStateSet
DIO:PORt:STATe? Gets Digital Port State. Parameter passed is the DIO number whose State needs to be checked. DIO:PORt:STATe? 0 SCPI_GPIOStateGet
DIO:PORt:ENAble Enables Digital Port. This command should be used everytime a new DIO needs to be used, before using commands like DIO:PORt:DIRection, and DIO:PORt:STATe. The parameter passed should be ‘1’ to Enable the DIO port. DIO:PORt:ENAble 1 SCPI_GPIOEnableSet
DIO:PORt:ENAble? Gets Digital Port Enabled State. DIO:PORt:ENAble? SCPI_GPIOEnableGet

DIO Debug Probe Commands

Lightweight framework for toggling or pulsing DIO pins from anywhere in the streaming pipeline to enable logic-analyzer timing analysis. While a probe is assigned to a DIO channel, that channel is owned exclusively — normal DIO:PORt:STATe / DIO:PORt:DIRection / PWM commands on an owned channel are rejected with -200 Execution error. Clearing a probe restores the user-configured state automatically.

Two probe classes:

  • Standard probes 0–9 mapped 1:1 to DIO_0..DIO_9, permanently wired to streaming pipeline stages, controlled at runtime via these SCPI commands.
  • Ad-hoc probes 10–15 mapped 1:1 to DIO_10..DIO_15, compile-time only (set bits in DIO_PROBE_ENABLE_MASK in BoardConfig.h).

Standard probe map — hardcoded call sites:

Probe Stage
0 Streaming timer ISR entry
1 ADC EOS ISR entry
2 Deferred task wake
3 Deferred task: alloc + channel loop + queue push
4 Deferred task: ADC + DIO trigger
5 ADC EOS task wake
6 ADC EOS task: result read loop
7 Encoder task wake
8 Encoder: encode call
9 Encoder: output write

Modes:

  • OFF — inert, no toggles
  • TOGGLE — flip pin on each call (use for event rate / cadence capture)
  • PULSE — drive HIGH on PulseStart, LOW on PulseEnd (use for duration capture)
SCPI Command Description Example Firmware Callback
SYSTem:DIOProbe:ASSign Assign a standard probe (0–9) to a mode (OFF / TOGGLE / PULSE). Channel = probe id. Rejects if PWM is active on the target channel. SYSTem:DIOProbe:ASSign 0,TOGGLE SCPI_DioProbeAssign
SYSTem:DIOProbe:ASSign? Query a probe’s current mode. Works for standard (0–9) and ad-hoc (10–15) probes. Returns OFF, TOGGLE, or PULSE. SYSTem:DIOProbe:ASSign? 0 SCPI_DioProbeAssignGet
SYSTem:DIOProbe:CLEar Release a standard probe, return the channel to normal DIO control. SYSTem:DIOProbe:CLEar 0 SCPI_DioProbeClear
SYSTem:DIOProbe:CLEar:ALL Release all 10 standard probes (ad-hoc probes are not affected). SYSTem:DIOProbe:CLEar:ALL SCPI_DioProbeClearAll
SYSTem:DIOProbe:PIPELine Set all 10 standard probes to the given mode in one call. Convenience for capturing the full pipeline. SYSTem:DIOProbe:PIPELine TOGGLE SCPI_DioProbePipeline
SYSTem:DIOProbe:LIST? Dump all 16 slots (10 standard + 6 ad-hoc) with channel, mode, and compile-time flag. SYSTem:DIOProbe:LIST? SCPI_DioProbeList

Caps-only abbreviations: DIOProbe abbreviates to DIOP (not DIOPR). ASSignASS, CLEarCLE, PIPELinePIPEL. E.g. SYST:DIOP:ASS 0,TOGGLE.

See docs/PIPELINE_TIMING.md in the firmware repo for captured timing measurements and per-stage CPU-budget tables.

PWM Commands

SCPI Command Description Example Firmware Callback
PWM:CHannel:FREQuency Sets the Frequency of a PWM channel (0,3,4,5,6,7) in Hz PWM:CHannel:FREQuency 0,10000 SCPI_PWMChannelFrequencySet
PWM:CHannel:FREQuency? Gets the PWM frequencty in Hz. Parameter passed is the PWM channel number. PWM:CHannel:FREQuency? 0 SCPI_PWMChannelFrequencyGet
PWM:CHannel:DUTY Sets the duty cycle of a PWM channel in percentage PWM:CHannel:DUTY 0,50 SCPI_PWMChannelDUTYSet
PWM:CHannel:DUTY? Gets the duty cycle of a PWM channel in percentage. Parameter passed is the PWM channel number. PWM:CHannel:DUTY? 0 SCPI_PWMChannelDUTYGet
PWM:CHannel:ENable Enable PWM in a particular channel. This command should be used everytime a new PWM channel needs to be used, before using commands like PWM:CHannel:FREQuency, and PWM:CHannel:DUTY. PWM:CHannel:ENable 0,1 (Enable PWM in channel 0)
PWM:CHannel:ENable 0,0 (Disable PWM in channel 0)
SCPI_PWMChannelEnableSet
PWM:CHannel:ENable? Check if PWM is enabled in a channel. Parameter passed is the PWM channel number that needs to be checked. PWM:CHannel:ENable? 0 SCPI_PWMChannelEnableGet

WiFi Commands

Note: Commands marked Requires WiFi powered return SCPI_ERROR_EXECUTION_ERROR when WiFi is disabled (STANDBY mode). Configuration SET commands and queries for settings (SSID?, NETType?, SECurity?) work in any power state. In STA mode with DHCP, ADDRess?, MASK?, and GATEway? return DHCP-assigned values; use the CONFigure: variants to read user-configured values.

SCPI Command Description Example Firmware Callback
SYSTem:COMMunicate:LAN:ENAbled? Get WiFi enabled status (0=disabled, 1=enabled) SYSTem:COMMunicate:LAN:ENAbled? SCPI_LANEnabledGet
SYSTem:COMMunicate:LAN:ENAbled Enable or disable WiFi (0=disable, 1=enable) SYSTem:COMMunicate:LAN:ENAbled 1 SCPI_LANEnabledSet
SYSTem:COMMunicate:LAN:NETType? Get network type: 1 = NETWORK_TYPE_INFRASTRUCTURE
4 = NETWORK_TYPE_SOFT_AP
SYSTem:COMMunicate:LAN:NETType? SCPI_LANNetTypeGet
SYSTem:COMMunicate:LAN:NETType Set network type: 1 = Infrastructure (connect to router)
4 = Soft AP (device creates access point)
SYSTem:COMMunicate:LAN:NETType 1 SCPI_LANNetTypeSet
SYSTem:COMMunicate:LAN:ADDRess? Get actual IP address (DHCP-assigned in STA mode). Requires WiFi powered. SYSTem:COMMunicate:LAN:ADDRess? SCPI_LANAddrGet
SYSTem:COMMunicate:LAN:ADDRess Set device IP address SYSTem:COMMunicate:LAN:ADDRess “192.168.1.100” SCPI_LANAddrSet
SYSTem:COMMunicate:LAN:CONFigure:ADDRess? Get configured (pre-DHCP) IP address SYSTem:COMMunicate:LAN:CONF:ADDR? SCPI_LANConfAddrGet
SYSTem:COMMunicate:LAN:MASK? Get actual subnet mask (DHCP-assigned in STA mode). Requires WiFi powered. SYSTem:COMMunicate:LAN:MASK? SCPI_LANMaskGet
SYSTem:COMMunicate:LAN:MASK Set subnet mask SYSTem:COMMunicate:LAN:MASK “255.255.255.0” SCPI_LANMaskSet
SYSTem:COMMunicate:LAN:CONFigure:MASK? Get configured (pre-DHCP) subnet mask SYSTem:COMMunicate:LAN:CONF:MASK? SCPI_LANConfMaskGet
SYSTem:COMMunicate:LAN:GATEway? Get actual gateway IP (DHCP-assigned in STA mode). Requires WiFi powered. SYSTem:COMMunicate:LAN:GATEway? SCPI_LANGatewayGet
SYSTem:COMMunicate:LAN:GATEway Set gateway IP address SYSTem:COMMunicate:LAN:GATEway “192.168.1.1” SCPI_LANGatewaySet
SYSTem:COMMunicate:LAN:CONFigure:GATEway? Get configured (pre-DHCP) gateway IP SYSTem:COMMunicate:LAN:CONF:GATE? SCPI_LANConfGatewayGet
SYSTem:COMMunicate:LAN:IPV6? Get IPv6 support status (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:IPV6 Set IPv6 support (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:DNS1? Get primary DNS server (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:DNS1 Set primary DNS server (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:DNS2? Get secondary DNS server (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:DNS2 Set secondary DNS server (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:MAC? Get device MAC address. Requires WiFi powered. SYSTem:COMMunicate:LAN:MAC? SCPI_LANMacGet
SYSTem:COMMunicate:LAN:MAC Set custom MAC address (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:CONnected? Check if WiFi is connected (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:HOST? Get device hostname (returns runtime hostname with MAC suffix, e.g. “DAQiFi-95A7”) SYSTem:COMMunicate:LAN:HOST? SCPI_LANHostnameGet
SYSTem:COMMunicate:LAN:HOST Set device hostname (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:SSID? Get WiFi SSID SYSTem:COMMunicate:LAN:SSID? SCPI_LANSsidGet
SYSTem:COMMunicate:LAN:SSID Set WiFi SSID to connect to SYSTem:COMMunicate:LAN:SSID “MyNetwork” SCPI_LANSsidSet
SYSTem:COMMunicate:LAN:SSIDSTR? Get WiFi signal strength (RSSI %). Requires WiFi powered. SYSTem:COMMunicate:LAN:SSIDSTR? SCPI_LANSsidStrengthGet
SYSTem:COMMunicate:LAN:AvSSIDScan Scan for available WiFi networks (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:AvSSID? Get list of available WiFi networks from scan (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:SECurity? Get security type: 0 = OPEN, 3 = WPA_AUTO_WITH_PASS_PHRASE
(Other options deprecated or not implemented)
SYSTem:COMMunicate:LAN:SECurity? SCPI_LANSecurityGet
SYSTem:COMMunicate:LAN:SECurity Set security type: 0 = OPEN, 3 = WPA/WPA2 SYSTem:COMMunicate:LAN:SECurity 3 SCPI_LANSecuritySet
SYSTem:COMMunicate:LAN:PASs Set WiFi password/passphrase (requires non-open security mode) SYSTem:COMMunicate:LAN:PASs MyPassword123 SCPI_LANPasskeySet
SYSTem:COMMunicate:LAN:PASSCHECK? Check if given password matches stored password (returns 1 if match, 0 if not) SYSTem:COMMunicate:LAN:PASSCHECK? MyPassword123 SCPI_LANPasskeyGet
SYSTem:COMMunicate:LAN:DISPlay Display network settings (not implemented) SCPI_NotImplemented
SYSTem:COMMunicate:LAN:APPLY Apply WiFi settings to device (required for network changes to take effect). After APPLY the WiFi module re-initializes, associates with the AP (STA mode) or starts the AP (AP mode), and brings the TCP server back up. Allow up to 20 s for the TCP server on port 9760 to accept connections; SYST:COMM:LAN:ADDR? may return the DHCP-assigned IP before TCP is actually listening. APPLY is a soft restart — see WiFi Command Notes for hardware reset (HRESet). SYSTem:COMMunicate:LAN:APPLY SCPI_LANSettingsApply
SYSTem:COMMunicate:LAN:HRESet Hardware-reset the WINC1500 chip via the GPIO reset path (DEINIT → CHIP_EN/RESET_N toggle → INIT). Use to recover a wedged outbound TCP stack (#383): symptoms are ICMP ping still works but TCP connect() from the MCU times out. Returns immediately; full recovery (chip reset + STA reassoc + DHCP) takes ~20-25 s. Poll LAN:ADDR? until non-192.168.1.1 to confirm DHCP completed. SYSTem:COMMunicate:LAN:HRESet SCPI_LANHardReset
SYSTem:COMMunicate:LAN:LOAD Load WiFi settings from NVM SYSTem:COMMunicate:LAN:LOAD SCPI_LANSettingsLoad
SYSTem:COMMunicate:LAN:SAVE Save current WiFi settings to NVM (allow settings to persist after power-off) SYSTem:COMMunicate:LAN:SAVE SCPI_LANSettingsSave
SYSTem:COMMunicate:LAN:FACRESET Load factory default WiFi settings (SSID=”DAQiFi”, Open security, etc.) SYSTem:COMMunicate:LAN:FACRESET SCPI_LANSettingsFactoryLoad
SYSTem:COMMunicate:LAN:GETChipInfo? Get WiFi module chip information as JSON: ChipId, firmware version, and build date SYSTem:COMMunicate:LAN:GETChipInfo? SCPI_LANGetChipInfo
SYSTem:COMMUnicate:LAN:FWUpdate Sets the serial interface to transparent mode for WiFi radio WiFi module firmware updates, bypassing the SCPI interface.

Command Sequence to enter WINC FW update mode:
1. SYSTem:POWer:STATe 1
2. SYSTem:COMMUnicate:LAN:FWUpdate
3. SYSTem:COMMUnicate:LAN:APPLY

Now, flash using the MCHP winc_flash_tool.cmd

Command Sequence to exit WINC FW update mode:
1. SYSTem:USB:TRANSparent:MODE 0
2. SYSTem:COMMunicate:LAN:ENabled 1
3. SYSTem:COMMUnicate:LAN:APPLY

Note: This uses the same transparent mode functionality as SYSTem:USB:TRANSparent:MODE

WiFi Command Notes

  • The device creates an open WiFi access point by default with SSID “DAQiFi”
  • WiFi must be enabled (ENAbled 1) and applied (APPLY) for changes to take effect
  • Settings must be saved (SAVE) to persist across power cycles
  • The device must be in POWERED_UP state (power state 1) for WiFi to operate
  • Post-APPLY timing: the WiFi module takes time to re-initialize, associate/start, obtain DHCP, and reopen the TCP server on port 9760. Allow up to ~20 s before attempting a client TCP connection — pinging may succeed earlier than TCP accepts, and ADDR? may report the DHCP IP before the TCP server is actually listening. A handy readiness pattern: after APPLY, poll ADDR? until it returns a non-default IP, then attempt connect(ip, 9760) with a short retry loop.
  • APPLY is a soft restart, NOT a hardware reset. Internally APPLY triggers WIFI_MANAGER_EVENT_REINIT which the state machine handles by BSSDisconnect + reconnect with new settings — it explicitly avoids WDRV_WINC_Deinitialize (Microchip driver bug: leaves the chip in permanent reset; see wifi_manager.c:867). APPLY does not toggle the WINC’s CHIP_EN / RESET_N GPIOs.
  • WINC hardware reset path: use SYST:COMM:LAN:HRESet. Internally fires WIFI_MANAGER_EVENT_DEINITWDRV_WINC_CloseWDRV_WINC_Deinitializewifi_manager_FixWincResetState() (asserts CHIP_EN, deasserts RESET_N on the WINC GPIO pins) → 2 s settle → WIFI_MANAGER_EVENT_INIT to bring the chip back up cleanly. Validated 2026-04-28: recovers a wedged outbound TCP stack within ~25 s. Symptoms requiring this: ICMP ping still works but TCP connect() from MCU times out indefinitely. Returns immediately; poll LAN:ADDR? until non-192.168.1.1 to confirm DHCP completed.
  • *RST now also resets the WINC. From the v3.4.6+ firmware, the *RST handler fires wifi_manager_Deinit() before RCON_SoftwareReset, so the WINC chip GPIO reset and the PIC32 soft reset happen together — the user gets the expected “everything fresh” state. Earlier firmware left the WINC running with stale state across *RST.
  • Recovery hierarchy (least to most invasive):
    1. SYST:WIFI:IPERF:STOP — clears iperf2 module’s gCtx; rarely sufficient
    2. LAN:APPLY — soft restart; refreshes association but leaves WINC chip state untouched (does not recover wedge)
    3. SYST:POWer:STATe 01 — cycles 10V rail; doesn’t drive WINC reset GPIOs (does not recover wedge)
    4. SYST:COMM:LAN:HRESet — drives DEINIT → GPIO reset → INIT; recovers wedged TCP stack ✓ validated
    5. *RST — full PIC32 reset; on v3.4.6+ also drives WINC reset GPIO via the bundled wifi_manager_Deinit
    6. Physical power cycle — last resort. Required only if even the GPIO reset doesn’t recover (rare; see #384 for ongoing investigation).
  • Manual ENA 0 / APPLY / ENA 1 / APPLY recipe is NOT reliable. Earlier wiki revisions described this as the recovery path. Empirical testing (2026-04-28) showed it sometimes works and sometimes doesn’t, depending on what state the WiFi state machine is in. Use LAN:HRESet instead.

Automatic SSID/Hostname MAC Suffix

When the SSID or hostname is the bare default “DAQiFi”, the firmware automatically appends the last 4 hex digits of the device’s MAC address to make each device distinguishable on the network (e.g. “DAQiFi-95A7”). This applies to:

  • AP SSID: The broadcast network name visible to WiFi clients
  • DHCP hostname: The device name reported to routers and network discovery tools (DHCP Option 12)

The suffix is applied on every WiFi init and reinit (including after APPLY), so factory resets and default values always get the suffix. User-customized values (anything other than bare “DAQiFi”) are preserved without modification. The HOST? and SSID? queries return the suffixed values.

iperf2 Commands

Quiescence rule applies. Query IPERF:STATs? once after the run; firmware returns last_stats in IDLE.

SCPI Command Description Example Firmware Callback
SYSTem:WIFI:IPERF:TCPServer Start iperf2 TCP server. Requires WiFi associated. SYSTem:WIFI:IPERF:TCPServer 5002 SCPI_Iperf2_TcpServer
SYSTem:WIFI:IPERF:UDPServer Start iperf2 UDP server. SYSTem:WIFI:IPERF:UDPServer 5002 SCPI_Iperf2_UdpServer
SYSTem:WIFI:IPERF:TCPClient TCP client <ip>,[port=5001],[dur_s=10]. IP must be quoted. SYSTem:WIFI:IPERF:TCPClient “192.168.1.133”,5002,12 SCPI_Iperf2_TcpClient
SYSTem:WIFI:IPERF:UDPClient UDP client (also reports loss). SYSTem:WIFI:IPERF:UDPClient “192.168.1.133”,5002,10 SCPI_Iperf2_UdpClient
SYSTem:WIFI:IPERF:TXBLast TX-blast TCP server <port>,<dur_s>. Pure raw-byte blasting from a static buffer — no iperf2 protocol overhead. PC connects with any TCP byte-counter (nc, iperf -c if you ignore the protocol noise, or a custom socket reader). Useful for separating “iperf2 protocol cost” from “WINC SPI staging ceiling.” Duration is measured from peer accept, not bind. SYSTem:WIFI:IPERF:TXBLast 5003,60 SCPI_Iperf2_TxBlast
SYSTem:WIFI:IPERF:STOP Finalize stats and return to IDLE. SYSTem:WIFI:IPERF:STOP SCPI_Iperf2_Stop
SYSTem:WIFI:IPERF:STATs? End-of-test snapshot (in IDLE) or live counters (during run — don’t poll). SYSTem:WIFI:IPERF:STATs? SCPI_Iperf2_Stats
SYSTem:WIFI:IPERF:DIAGnostics? Diagnostic dump for #399 investigations: current mode, listen/data socket fds, pending_tx, abort_pending, bytes_confirmed, last_send_rc, send_err_count, WINC state, plus a free-socket probe when idle. SYSTem:WIFI:IPERF:DIAGnostics? SCPI_Iperf2_Diag
SYSTem:WIFI:IPERF:AUTOReset Toggle auto-HRESet on session end (0=off, 1=on, default 1). When on, runs wifi_manager_HardReset after every iperf2 session — costs ~12 s WiFi reassociation but gives clean WINC state per session (#399 workaround). Set to 0 for back-to-back fast trials where reassoc overhead dominates measurement. SYSTem:WIFI:IPERF:AUTOReset 0 SCPI_Iperf2_SetAutoReset
SYSTem:WIFI:IPERF:AUTOReset? Query auto-HRESet state. SYSTem:WIFI:IPERF:AUTOReset? SCPI_Iperf2_GetAutoReset
SYSTem:WIFI:IPERF:MAXPending Dormant debug knob, default 0 (use compile-time IPERF2_MAX_PENDING_TX = 4). Set 0..4 to throttle the WINC HIF queue depth at runtime (N=3 ≈ 75% rate, N=2 ≈ 50%). Tested 2026-04-30 / 2026-05-01 against #399 sustained-rate decay — did not improve stability or throughput. Kept available for future investigations. SYSTem:WIFI:IPERF:MAXPending 2 SCPI_Iperf2_SetMaxPending
SYSTem:WIFI:IPERF:MAXPending? Query effective MAXPending (returns the override if set, else the compile-time default). SYSTem:WIFI:IPERF:MAXPending? SCPI_Iperf2_GetMaxPending

IPERF:STATs? Response Fields

Field Description
Mode 0=IDLE, 1=TCP svr, 2=TCP cli, 3=UDP svr, 4=UDP cli, 5=TX-blast (always 0 in IDLE)
Active / Completed 1/0 in-test; 0/1 after completion
Bytes uint64, transferred bytes (preserved in IDLE)
DurationMs actual elapsed at end-of-test (preserved in IDLE)
KBps Bytes × 1000 / DurationMs / 1024
UdpTotalPkt / UdpLostPkt / UdpOutOfOrder UDP only

IPERF:DIAGnostics? Response Fields

Field Description
Mode Same encoding as STATs? Mode
DataSock / ListenSock Current socket fds (-1 if not allocated)
PendingTx TX in flight, bounded by IPERF2_MAX_PENDING_TX (default 4) or MAXPending override
AbortPending 1 if a deferred abort was scheduled in callback context (cleared by Iperf2_Tasks)
BytesConfirmed Cumulative bytes the WINC SOCKET_MSG_SEND callback has acknowledged this session
LastSendRc / SendErrCount Sticky tracking of m2m_send failures (reset on Iperf2_Initialize, not by ResetContext)
WincState wifi_manager state machine value (see WIFI_STATE enum)
FreeTcpSockets / FreeUdpSockets Probed at IDLE only — opens then closes a throwaway socket of each type to verify WINC pool isn’t exhausted (#399 hypothesis check)

Mode 5 — TX-blast notes

  • Server-mode: device binds and listens on the requested port, PC connects. Duration starts at accept, not bind, so the user has time to start the PC reader after sending the SCPI.
  • Throughput is the upper bound for any iperf2 mode — protocol overhead is zero (raw 1400-byte payloads from a static buffer). PC and device byte counts agree to ≤2% (E: 2026-05-02 5×60s battery).
  • Stats schema is the same as iperf2 modes — Bytes, DurationMs, KBps populate at session end via FinalizeStats.

ADC Commands

SCPI Command Description Example Firmware Callback
MEASure:VOLTage:DC? Measure DC voltage on specified channel MEASure:VOLTage:DC? 0 SCPI_ADCVoltageGet
ENAble:VOLTage:DC Enable/disable ADC channels for voltage measurement Enable Ch0: ENAble:VOLTage:DC 0,1
Enable Ch1: ENAble:VOLTage:DC 1,1
Enable all: ENAble:VOLTage:DC 65535
SCPI_ADCChanEnableSet
ENAble:VOLTage:DC? Get channel enable status ENAble:VOLTage:DC? 0 SCPI_ADCChanEnableGet
SOURce:VOLTage:LEVel Set output voltage level (not implemented) SOURce:VOLTage:LEVel 5.0 SCPI_NotImplemented
CONFigure:ADC:SINGleend Set channel to single-ended (1) or differential (0) mode (if device supports it) CONFigure:ADC:SINGleend 0,1 SCPI_ADCChanSingleEndSet
CONFigure:ADC:SINGleend? Get channel single-ended/differential setting CONFigure:ADC:SINGleend? 0 SCPI_ADCChanSingleEndGet
CONFigure:ADC:RANGe Set ADC channel voltage range (if device supports it) CONFigure:ADC:RANGe 0,10 SCPI_ADCChanRangeSet
CONFigure:ADC:RANGe? Get ADC channel voltage range CONFigure:ADC:RANGe? 0 SCPI_ADCChanRangeGet
CONFigure:ADC:CHANnel Enable/disable ADC channel (alias for ENAble:VOLTage:DC for backwards compatibility) CONFigure:ADC:CHANnel 0,1 SCPI_ADCChanEnableSet
CONFigure:ADC:CHANnel? Get channel enable status (alias for ENAble:VOLTage:DC? for backwards compatibility) CONFigure:ADC:CHANnel? 0 SCPI_ADCChanEnableGet
CONFigure:ADC:chanCALM Sets the m (slope) calibration value on a single channel CONFigure:ADC:chanCALM 0 1.0023 SCPI_ADCChanCalmSet
CONFigure:ADC:chanCALB Sets the b (intercept) calibration value on a single channel CONFigure:ADC:chanCALB 0 0.0012 SCPI_ADCChanCalbSet
CONFigure:ADC:chanCALM? Gets the m (slope) calibration value for a channel CONFigure:ADC:chanCALM? 0 SCPI_ADCChanCalmGet
CONFigure:ADC:chanCALB? Gets the b (intercept) calibration value for a channel CONFigure:ADC:chanCALB? 0 SCPI_ADCChanCalbGet
CONFigure:ADC:SAVEcal Saves current user calibration values for all channels to NVM CONFigure:ADC:SAVEcal SCPI_ADCCalSave
CONFigure:ADC:SAVEFcal Saves current calibration as factory values (use with caution) CONFigure:ADC:SAVEFcal SCPI_ADCCalFSave
CONFigure:ADC:LOADcal Loads user calibration values from NVM CONFigure:ADC:LOADcal SCPI_ADCCalLoad
CONFigure:ADC:LOADFcal Loads factory calibration values from NVM CONFigure:ADC:LOADFcal SCPI_ADCCalFLoad
CONFigure:ADC:USECal Select factory (0) or user (1) calibration values CONFigure:ADC:USECal 1 SCPI_ADCUseCalSet
CONFigure:ADC:USECal? Get calibration mode: factory (0) or user (1) CONFigure:ADC:USECal? SCPI_ADCUseCalGet

Capabilities Discovery

SCPI Command Description Example Firmware Callback
CONFigure:CAPabilities:JSON? Returns a single-line JSON document describing every device capability — identity, channel topology, ADC ranges, streaming limits, transports, power, storage, triggers. Intended for client tools that need to discover what the device can do at connect time. ~5 KB on NQ1. See Capabilities JSON Schema for the full field reference. CONFigure:CAPabilities:JSON? SCPI_CapabilitiesJsonGet

DAC Commands (NQ3 Only)

SCPI Command Description Example Firmware Callback
SOURce:VOLTage:LEVel Set DAC channel voltage. Two params: channel,voltage. Or one param: set all channels. SOURce:VOLTage:LEVel 0,5.0 SCPI_DACVoltageSet
SOURce:VOLTage:LEVel? Query DAC channel voltage. Optional param: channel number. Omit for all channels. SOURce:VOLTage:LEVel? 0 SCPI_DACVoltageGet
CONFigure:DAC:UPDATE Update all DAC outputs (apply pending voltage changes) CONFigure:DAC:UPDATE SCPI_DACUpdate
CONFigure:DAC:chanCALM Set DAC channel calibration slope CONFigure:DAC:chanCALM 0,1.0 SCPI_DACChanCalmSet
CONFigure:DAC:chanCALM? Get DAC channel calibration slope CONFigure:DAC:chanCALM? 0 SCPI_DACChanCalmGet
CONFigure:DAC:chanCALB Set DAC channel calibration offset CONFigure:DAC:chanCALB 0,0.0 SCPI_DACChanCalbSet
CONFigure:DAC:chanCALB? Get DAC channel calibration offset CONFigure:DAC:chanCALB? 0 SCPI_DACChanCalbGet
CONFigure:DAC:USECal Select factory (0) or user (1) DAC calibration CONFigure:DAC:USECal 1 SCPI_DACUseCalSet
CONFigure:DAC:USECal? Get DAC calibration mode CONFigure:DAC:USECal? SCPI_DACUseCalGet
CONFigure:DAC:SAVEcal Save user DAC calibration to NVM CONFigure:DAC:SAVEcal SCPI_DACCalSave
CONFigure:DAC:LOADcal Load user DAC calibration from NVM CONFigure:DAC:LOADcal SCPI_DACCalLoad
CONFigure:DAC:SAVEFcal Save factory DAC calibration to NVM CONFigure:DAC:SAVEFcal SCPI_DACCalFSave
CONFigure:DAC:LOADFcal Load factory DAC calibration from NVM CONFigure:DAC:LOADFcal SCPI_DACCalFLoad

Voltage Output Precision

SCPI Command Description Example Firmware Callback
CONFigure:VOLTage:PRECision Set voltage output precision. 0 = integer millivolts, 1-10 = volts with N decimal places. CONF:VOLT:PREC 4 SCPI_SetDataPrecision
CONFigure:VOLTage:PRECision? Get current voltage output precision CONF:VOLT:PREC? SCPI_GetDataPrecision
CONFigure:VOLTage:SAVE Save current precision to NVM (persists across reboots) CONF:VOLT:SAVE SCPI_SaveDataPrecision
CONFigure:VOLTage:LOAD Load precision from NVM CONF:VOLT:LOAD SCPI_LoadDataPrecision

Precision Values:

Value Unit Format Example Notes
0 millivolts (integer) 1221 Backwards compatible, fastest output path
1-3 volts 1.2, 1.22, 1.221 Low precision
4 volts 1.2207 Default (NQ1) — 0.1mV resolution, preserves 12-bit ADC
5-6 volts 1.22070, 1.220703 Default 6 (NQ3) — 18-bit ADC (AD7609)
7-10 volts 1.2207031 Default 7 (NQ2) — 24-bit ADC (AD7173)

Board-Specific Defaults:

Board ADC Resolution Default Precision
NQ1 MC12bADC 12-bit 4
NQ3 AD7609 18-bit 6
NQ2 AD7173 24-bit 7

Notes:

  • Applied systemwide: CSV streaming, JSON streaming, and SCPI voltage queries (MEAS:VOLT:DC?, SOUR:VOLT:LEV?)
  • Protobuf streaming is unaffected
  • Can be changed while streaming is active; takes effect on the next encoded sample
  • Use CONF:DATA:SAVE to persist across reboots; otherwise resets to board default

SPI Commands

SCPI Command Description Example Firmware Callback
OUTPut:SPI:WRIte Write data to SPI bus (not implemented) OUTPut:SPI:WRIte 0xFF,0x00 SCPI_NotImplemented

Streaming Commands

SCPI Command Description Example Firmware Callback
SYSTem:STReam:START Start streaming enabled channels at specified frequency SYSTem:STReam:START 100 SCPI_StartStreaming
SYSTem:STReam:STOP Stop data streaming SYSTem:STReam:STOP SCPI_StopStreaming
SYSTem:STReam:DATA? Check if streaming is active (0=stopped, 1=streaming) SYSTem:STReam:DATA? SCPI_IsStreaming
SYSTem:STReam:FORmat
<format>,<TestData_Len>
Argument 1: <format>
  • 0 = Protobuf
  • 1 = JSON
  • 2 = TestData

Argument 2 (optional):<TestData_Len>
  • Specifies the length of TestData.
  • This field is applicable only when <format> is set to 2 (TestData).
  • By default the <TestData_Len> = 0 (dynamic length which varies during run-time). The length of the TestData will be equal to the number of bytes written to the buffer upon calling Nanopb_Encode().
Additional notes: TestData format is useful to run communication tests. In this mode, the program will first encode the stream data using Nanopb_Encode(), then fill up the write buffer with dummy data until it reaches the length specified by <TestData_Len>. The packet structure for TestData is demonstrated below:

Byte [0] – The first byte is always a ‘#’, which indicates a header byte.

Byte [1] – Byte [4] – 32-bit tick in 1 millisecond resolution.

Byte [5] – Byte [6] – 16-bit cycle counter, increments every packet. Useful for packet loss detection.

Byte [7] – Byte [TestData_Len-5] – padded with Dummy Data.

Byte [TestData_Len-4] – Byte[TestData_Len-3] – 16-bit checksum using simple additive summation.

Byte [TestData_Len-2] – Byte[TestData_Len-1] – 2 bytes delimiter ‘\r\n’
SYSTem:STReam:FORmat 2,1000
Sets the stream format to TestData with fixed length at 1000 bytes (maximum length).
SCPI_SetStreamFormat
SYSTem:STReam:FORmat? Get current stream format (0=Protobuf, 1=JSON, 2=CSV) SYSTem:STReam:FORmat? SCPI_GetStreamFormat
SYSTem:STReam:INTerface Set streaming output interface:
• 0 = USB
• 1 = WiFi
• 2 = SD card
• 3 = All (legacy mode)
Auto-detects source interface if not explicitly set.
SYSTem:STReam:INTerface 2 SCPI_SetStreamInterface
SYSTem:STReam:INTerface? Get current streaming interface SYSTem:STReam:INTerface? SCPI_GetStreamInterface
SYSTem:STReam:STATS? Get streaming loss/throughput statistics (see response fields below). Query after StopStreamData for trustworthy benchmark numbers — see Quiescence Rule. Counters survive across the stop until the next StartStreamData (auto-clears) or explicit STATS:CLEar. SYSTem:STReam:STATS? SCPI_GetStreamStats
SYSTem:STReam:STATS:CLEar Clear all streaming statistics counters SYSTem:STReam:STATS:CLEar SCPI_ClearStreamStats
SYSTem:STReam:LOSS:THREshold Set sample-loss percentage threshold that triggers QUES data-loss bit (range 1-100, default 5) SYSTem:STReam:LOSS:THREshold 10 SCPI_SetLossThreshold
SYSTem:STReam:LOSS:THREshold? Get current loss threshold percentage SYSTem:STReam:LOSS:THREshold? SCPI_GetLossThreshold
SYSTem:STReam:LOSS:WINDow Set flow window size override (0 = auto, 20-10000 = explicit). Auto = clamp(freq×2, 20, 10000). Takes effect at next streaming start. SYSTem:STReam:LOSS:WINDow 500 SCPI_SetFlowWindow
SYSTem:STReam:LOSS:WINDow? Get current flow window size override (0 = auto) SYSTem:STReam:LOSS:WINDow? SCPI_GetFlowWindow
SYSTem:STReam:TEST:PATtern Set test pattern mode: 0=off (real ADC), 1=counter, 2=midscale, 3=fullscale, 4=walking, 5=triangle, 6=sine SYSTem:STReam:TEST:PATtern 1 SCPI_SetTestPattern
SYSTem:STReam:TEST:PATtern? Query current test pattern (0=disabled) SYSTem:STReam:TEST:PATtern? SCPI_GetTestPattern

Streaming Statistics Response Fields

SYSTem:STReam:STATS? returns the following key=value pairs:

Field Type Description
TotalSamplesStreamed uint64 Samples successfully queued from ISR to encoder
TotalBytesStreamed uint64 Total bytes encoded and offered to output buffers
QueueDroppedSamples uint32 Samples lost when the 700-sample queue is full
UsbDroppedBytes uint32 Bytes lost due to USB circular buffer full (16KB)
WifiDroppedBytes uint32 Bytes lost due to WiFi circular buffer full (5.6KB)
SdDroppedBytes uint32 Bytes lost due to SD write timeout or partial write
SdWriteCalls uint32 Total disk_write() invocations
SdWriteSectors uint32 Total sectors written to SD card
SdBytesWritten uint64 Total bytes confirmed written to SD card
SdWriteErrors uint32 disk_write() failures (covers CRC rejects, timeouts, all FatFS-level errors)
SdWriteMaxLatencyMs uint32 Worst-case single write latency in milliseconds
SdWriteAlignedCopies uint32 Writes requiring cacheable→aligned buffer copy (performance penalty indicator)
WifiTcpBytesSent uint64 Bytes accepted by WiFi radio send() (WiFi streaming only). Safe for multi-day sessions.
WifiTcpBytesConfirmed uint64 Bytes confirmed delivered by WiFi radio callback. If less than WifiTcpBytesSent, data was lost inside the radio module.
WifiTcpSendErrors uint32 WiFi send callback errors (negative sentBytes — real failures)
WifiTcpPartialSends uint32 Partial sends (callback confirmed fewer bytes than requested — normal TCP segmentation, indicates link pressure)
EncoderFailures uint32 Encode attempts that returned 0 bytes with data available
TimerISRCalls uint64 Actual streaming timer ISR entry count this session (#265). Distinguishes “timer firing at requested rate” from downstream bottlenecks. Invariant: TimerISRCalls == TotalSamplesStreamed + QueueDroppedSamples. Compare against freq × duration to detect rate-limiting at the PIC32MZ ~90 kHz hardware ceiling.
SampleLossPercent uint32 QueueDroppedSamples / (TotalSamples + Dropped) * 100
ByteLossPercent uint32 (USB + WiFi + SD dropped) / TotalBytesStreamed * 100 (can exceed 100% with multiple active outputs)
WindowLossPercent uint32 Sliding-window sample loss percentage (0-100), updated every N samples. Window size = clamp(freq×2, 20, 10000) or explicit override via SYST:STR:LOSS:WINDow. Threshold for QUES bit 4 configurable via SYST:STR:LOSS:THREshold (default 5%).

Session lifecycle: Stats are cleared automatically when a new streaming session starts (STR:START). They are preserved after STR:STOP so the user can query them. A LOG_E summary is automatically written at session end if any data was lost (retrieve via SYSTem:LOG?).

Thread safety: 64-bit counters use critical sections for atomic updates on 32-bit PIC32MZ. STATS? returns an atomic snapshot of all fields. TimerISRCalls lives in a separate volatile global written only by the timer ISR (priority 1, no concurrent writers); the snapshot read is taken inside the same critical section, which blocks the timer ISR for coherent 64-bit access.

Diagnostic logic for TimerISRCalls:

  • TimerISRCalls < freq × duration → timer is rate-limited (PIC32MZ ~90 kHz hardware ceiling for the streaming ISR + Harmony dispatch)
  • TimerISRCalls == TotalSamples + QueueDropped → every ISR is fully accounted for between the ISR and the deferred task
  • QueueDroppedSamples > 0 → sample pool exhausted (encoder/output too slow for the rate the timer is firing)
  • UsbDroppedBytes / SdDroppedBytes > 0 → encoder is fine but transport can’t keep up

Per-interface coverage: WiFi has full pipeline tracking (BytesSent/BytesConfirmed/SendErrors/PartialSends) because the radio transport is non-deterministic. USB and SD only track buffer overflow drops — their transports are deterministic (USB CDC is protocol-ACKed, SD writes are synchronous), so “sent == confirmed” by definition.

Test Pattern Streaming Mode

Test pattern mode replaces real ADC values with synthetic data for deterministic regression testing and benchmarking. The real ISR timing is preserved — patterns only override the ADC value field.

SCPI Commands:

SYSTem:STReam:TEST:PATtern <pattern>   # Set pattern (0=off, 1-6)
SYSTem:STReam:TEST:PATtern?            # Query current pattern

Pattern Types:

Pattern Name Value Generated Use Case
0 Off Real ADC data Normal operation
1 Counter (sampleCount + channelId) % (adcMax+1) Integrity verification — PC can predict exact values
2 Midscale adcMax / 2 Consistent encoding size across CSV/JSON/ProtoBuf
3 Fullscale adcMax Worst-case ProtoBuf variable-length encoding
4 Walking (sampleCount * (channelId+1)) % (adcMax+1) Multi-channel visual verification
5 Triangle Ramps 0→adcMax→0, period=2*(adcMax+1) Realistic waveform, staggered per channel
6 Sine 256-sample sine wave, scaled to [0, adcMax] Realistic signal testing, 45° phase offset per channel
  • adcMax = max raw ADC code = Resolution – 1 (4095 for MC12bADC 12-bit, 262143 for AD7609 18-bit)
  • Pattern is runtime-only (not persisted to NVM, resets on reboot)
  • Sample counter resets at each STR:START for deterministic sessions
  • All encoding formats and output interfaces work normally with test patterns

Streaming Throughput Benchmarking

SCPI Command Description Example Firmware Callback
SYSTem:STReam:BENCHmark <0|1> Enable (1) or disable (0) benchmark mode. Bypasses frequency cap for throughput testing. Lowers ISR task priority for fair scheduling. SYST:STR:BENCH 1 SCPI_SetBenchmarkMode
SYSTem:STReam:BENCHmark? Query benchmark mode (0=normal, 1=uncapped) SYST:STR:BENCH? SCPI_GetBenchmarkMode
SYSTem:STReam:THRoughput <freq>,<duration_sec> Self-contained benchmark: enables benchmark mode + test pattern 2, streams for duration, stops, returns all stats. Blocks SCPI during execution. SYST:STR:THR 5000,10 SCPI_RunThroughputBench

Benchmark Mode Usage:

  1. Enable test patterns: SYST:STR:TEST:PATtern 2
  2. Enable benchmark mode: SYST:STR:BENCHmark 1
  3. Start streaming at desired rate: SYST:STR:START 11000
  4. Wait, then stop: SYST:STR:STOP
  5. Check results: SYST:STR:STATS?
  6. Restore: SYST:STR:BENCHmark 0

Measured Zero-Loss Throughput Ceilings (NQ1, test patterns):

Interface Format Channels Max Rate KB/s
USB CSV 1 13 kHz 210
USB CSV 16 3 kHz 766
USB PB 1 5 kHz 62
USB PB 16 3 kHz 136
SD CSV 1 5 kHz 84
SD CSV 16 1 kHz 272
SD PB 1 5 kHz 61
SD PB 16 1 kHz 46
WiFi PB 16 1 kHz 49
WiFi CSV 16 1 kHz 206

Dynamic Memory Management Commands

Buffer sizes and sample pool depth are configurable at runtime to optimize RAM usage for specific streaming scenarios. All settings take effect at the next STR:START. Settings are runtime-only (not persisted to NVM, reset on reboot to safe defaults). All setters reject changes while streaming is active.

SCPI Command Description Range Default Firmware Callback
SYSTem:MEMory:SD:BUFfer <bytes> Set SD circular buffer size 4096-65536, multiple of 512 32768 SCPI_SetMemSdBuf
SYSTem:MEMory:SD:BUFfer? Query SD circular buffer size SCPI_GetMemSdBuf
SYSTem:MEMory:WIFI:BUFfer <bytes> Set WiFi circular buffer size 1400-65536 14000 SCPI_SetMemWifiBuf
SYSTem:MEMory:WIFI:BUFfer? Query WiFi circular buffer size SCPI_GetMemWifiBuf
SYSTem:MEMory:USB:BUFfer <bytes> Set USB circular buffer size 4096-65536 16384 SCPI_SetMemUsbBuf
SYSTem:MEMory:USB:BUFfer? Query USB circular buffer size SCPI_GetMemUsbBuf
SYSTem:MEMory:SAMPle:POOL <count> Set sample pool depth (0=auto) 0 or 100-2000 500 (auto) SCPI_SetMemSamplePool
SYSTem:MEMory:SAMPle:POOL? Query sample pool depth SCPI_GetMemSamplePool
SYSTem:MEMory:FREE? Query full memory diagnostics SCPI_GetMemFree
SYSTem:MEMory:AUTO Auto-balance buffers for active interfaces SCPI_MemAutoBalance
SYSTem:MEMory:STACk? Query all task stack high-water marks SCPI_GetStackStats

Memory Diagnostics Response Fields

SYSTem:MEMory:FREE? returns a comma-separated key:value response:

Field Type Description
HeapTotal uint32 Total FreeRTOS heap size (75000 bytes)
HeapFree uint32 Currently free heap bytes
HeapUsed uint32 Currently used heap bytes
HeapMinEverFree uint32 Lowest heap free since boot (high-water mark)
CoherentPoolTotal uint32 Total DMA-safe coherent pool size (126976 bytes)
CoherentPoolFree uint32 Free coherent pool bytes
SdCircularSize uint32 Current SD circular buffer partition size (streaming pool)
SamplePoolCount uint32 Current sample pool depth (number of samples)
SamplePoolBytes uint32 Sample pool data memory (count x 208 bytes)
SampleNextFreeBytes uint32 Free-list array memory (count x 2 bytes)
SampleQueueBytes uint32 FreeRTOS queue overhead (estimated)

Auto-Balance Algorithm

SYSTem:MEMory:AUTO queries the active streaming interface (SYSTem:STReam:INTerface) and SD enable state, then allocates default buffer sizes only for enabled interfaces. Remaining streaming pool space goes to the sample pool (clamped 100-2000). Also re-partitions the 124KB coherent pool among all three DMA consumers (SD write, USB write, WiFi SPI staging) — inactive interfaces get minimums, active interfaces split remaining space (SD 50%, USB 30%, WiFi 20%; single-active gets everything). Returns the allocation as "USB:<n>,WiFi:<n>,SD:<n>,Encoder:<n>,Pool:<n>,UsbDma:<n>,WifiDma:<n>,SdDma:<n>".

SD Logging Commands

SCPI Command Description Example Firmware Callback
SYSTem:STORage:SD:ENAble Enable (1) or disable (0) SD card. WiFi+SD streaming blocked (SPI bus conflict). Cannot disable while SD is busy. SYSTem:STORage:SD:ENAble 1 SCPI_StorageSDEnableSet
SYSTem:STORage:SD:ENAble? Query SD card enable status (0=disabled, 1=enabled) SYSTem:STORage:SD:ENAble? SCPI_StorageSDEnableGet
SYSTem:STORage:SD:FILE Set filename for SD card logging. File is opened in overwrite mode (not append). SYSTem:STORage:SD:FILE “data.csv” SCPI_StorageSDLoggingSet
SYSTem:STORage:SD:LISt? List all files on SD card. Returns chunked output to handle large directories. Optional parameter: directory path. SYSTem:STORage:SD:LIST?
SYSTem:STORage:SD:LIST? “DAQiFi”
SCPI_StorageSDListDir
SYSTem:STORage:SD:GET Retrieve file contents from SD card. Parameter: filename in quotes. SYSTem:STORage:SD:GET “data.csv” SCPI_StorageSDGetData
SYSTem:STORage:SD:DELete Delete a file from SD card. Parameter: filename in quotes. SYSTem:STORage:SD:DEL “old.csv” SCPI_StorageSDDelete
SYSTem:STORage:SD:FORmat Format SD card (erase all files). WARNING: Destructive! Non-blocking — returns immediately. Poll FORmat? for progress. SYSTem:STORage:SD:FOR SCPI_StorageSDFormat
SYSTem:STORage:SD:FORmat? Query format status and progress. Returns: <status>,<percent>. Status: 0=idle, 1=in progress, 2=completed OK, -1=failed. Percent: 0-100. Terminal states (2, -1) clear to idle on read. Example: 1,45 = formatting at 45%. SYSTem:STORage:SD:FOR? SCPI_StorageSDFormatQuery
SYSTem:STORage:SD:BENCHmark Run write speed benchmark. Parameter: size in KB (1-1024), optional pattern (0=zeros, 1=sequential, 2=random). Waits for file open before timing, waits for full pipeline flush before stopping timer. Measures actual I/O throughput (no artificial delays). SYSTem:STORage:SD:BENCH 1024
SYSTem:STORage:SD:BENCH 512,1
SCPI_StorageSDBenchmark
SYSTem:STORage:SD:BENCHmark? Query benchmark results. Returns CSV: bytes_written,time_ms,speed_bps SYSTem:STORage:SD:BENCH? SCPI_StorageSDBenchmarkQuery
SYSTem:STORage:SD:MAXSize Set maximum file size in bytes before auto-split. Prevents FAT32 4GB limit issues. Range: 1000 bytes to 4GB, or 0 for filesystem maximum. Default: 3.9GB (FAT32-safe). Setting 0 uses safe 3.9GB limit. Files split sequentially: data.csv → data-0001.csv, data-0002.csv, etc. SYSTem:STORage:SD:MAXSize 2000000000
SYSTem:STORage:SD:MAXSize 0
SCPI_StorageSDMaxSizeSet
SYSTem:STORage:SD:MAXSize? Query current maximum file size setting. Returns bytes. SYSTem:STORage:SD:MAXSize? SCPI_StorageSDMaxSizeGet
SYSTem:STORage:SD:SPACe? Query SD card free and total space. Returns two values: free bytes, total bytes. Routes through SD card manager state machine (works even when SD is disabled). SYSTem:STORage:SD:SPACe? SCPI_StorageSDSpaceGet
SYSTem:STORage:SD:ABORt Abort an in-progress SD file transfer (GET). Closes the file cleanly. No-op if no transfer is active. SYST:STOR:SD:ABOR SCPI_StorageSDAbort
SYSTem:STORage:SD:INFO? Query SD card identification (CID register). Returns comma-separated fields: MID (manufacturer ID), OID (OEM string), PNM (product name), PRV (product revision M.N), PSN (serial number), MDT (manufacturing date YYYY/MM). Returns SCPI error if no card present or CID unavailable. SYST:STOR:SD:INFO? SCPI_StorageSDInfo

SD Card INFO Response Example:

3,"SD",SR256,8.4,2818572288,2023/6

Fields: MID=3 (SanDisk), OID=”SD”, Product=”SR256″, Revision=8.4, Serial=2818572288, Date=2023/June

SD Card Logging Example:

SYSTem:POWer:STATe 1
SYSTem:STORage:SD:ENAble 1
SYSTem:STORage:SD:FILE "test.csv"
SYSTem:STReam:INTerface 2      // Set output to SD card
SYSTem:STReam:FORmat 2          // CSV format
CONFigure:ADC:CHANnel 0,1
SYSTem:STReam:START 100
// Data logs to SD card
SYSTem:STReam:STOP
SYSTem:STORage:SD:LISt?         // File appears in listing
SYSTem:STORage:SD:GET "test.csv"
SYSTem:STORage:SD:DELete "test.csv"

FreeRTOS Commands

SCPI Command Description Example Firmware Callback
SYSTem:OS:Stats? Get FreeRTOS task runtime statistics showing CPU usage per task SYSTem:OS:Stats? SCPI_GetOSStats

Common Usage Examples

Basic Power Control

# Power up the device
SYSTem:POWer:STATe 1

# Check power state
SYSTem:POWer:STATe?

# Get system info
SYSTem:INFo?

# Power down
SYSTem:POWer:STATe 0

WiFi Configuration

# Configure WiFi to connect to a network
SYSTem:COMMunicate:LAN:SSID "MyNetwork"
SYSTem:COMMunicate:LAN:SECurity 3
SYSTem:COMMunicate:LAN:PASs "MyPassword123"
SYSTem:COMMunicate:LAN:NETType 1
SYSTem:COMMunicate:LAN:APPLY

# Save settings to NVM
SYSTem:COMMunicate:LAN:SAVE

# Configure as Access Point
SYSTem:COMMunicate:LAN:NETType 4
SYSTem:COMMunicate:LAN:SSID "DAQiFi-AP"
SYSTem:COMMunicate:LAN:SECurity 0
SYSTem:COMMunicate:LAN:APPLY

ADC Data Acquisition

# Enable channel 0 for 10V range
ENAble:VOLTage:DC 0,1
CONFigure:ADC:RANGe 0,10

# Read single voltage
MEASure:VOLTage:DC? 0

# Start streaming at 100Hz
SYSTem:STReam:START 100

# Stop streaming
SYSTem:STReam:STOP

Digital I/O Control

# Enable DIO port
DIO:PORt:ENAble 1

# Set as output
DIO:PORt:DIRection 0,1

# Set high
DIO:PORt:STATe 0,1

# Read state
DIO:PORt:STATe? 0

PWM Output

# Enable PWM channel 0
PWM:CHannel:ENable 0,1

# Set 1kHz frequency
PWM:CHannel:FREQuency 0,1000

# Set 50% duty cycle
PWM:CHannel:DUTY 0,50

SD Card Logging

# Power up
SYSTem:POWer:STATe 1

# Enable SD card and set filename
SYSTem:STORage:SD:ENAble 1
SYSTem:STORage:SD:FILE "data.csv"

# Set streaming to SD interface and CSV format
SYSTem:STReam:INTerface 2
SYSTem:STReam:FORmat 2

# Enable ADC channel(s)
CONFigure:ADC:CHANnel 0,1

# Start logging at 100 Hz
SYSTem:STReam:START 100

# Stop and retrieve data
SYSTem:STReam:STOP
SYSTem:STORage:SD:LISt?
SYSTem:STORage:SD:GET "data.csv"

Note: WiFi does not need to be disabled for SD logging. However, WiFi streaming (SYSTem:STReam:INTerface 1 or 3) cannot be used simultaneously with SD logging due to shared SPI bus. WiFi firmware update is also blocked while SD is busy.


Source of truth: daqifi/daqifi-nyquist-firmware wiki → 01-SCPI-Interface · Edit on GitHub · this page is auto-synced; edit upstream to update.