Skip to content

Data acquisition workflow

This page covers what ADCL WinSoft does when you press Start DAQ during a run, where the data ends up, and how to feed it into downstream post-processing.

What happens when you press Start DAQ

  1. The application starts a DaqWorker background thread (code/adcl_winsoft/src/adcl_winsoft/daq/worker.py).
  2. The worker opens a continuous NI-DAQmx task across all configured channels at the configured sample rate (default 5 Hz).
  3. Each tick, the worker reads one sample per channel, applies the per-channel slope/offset, applies the PGB matrix where applicable, derives the secondary signals (velocity, Reynolds), and writes:
    • one row to the open CSV;
    • one snapshot into AppState.last_daq for the UI;
    • one entry into each channel's rolling buffer (capped at 4096 samples, FIFO).
  4. The UI's 4 Hz refresh timer picks up AppState.last_daq and updates the visible panels.

There are two paths from the worker into the UI — Qt signals and direct shared-state writes. The direct path is the backup that keeps the application responsive if signal delivery stalls. This is the "belt and suspenders" pattern in app.py.

CSV layout

E:\Wind_tunnel\ADCLWinSoft\Data\YYYY-MM-DD\DDMMYY HHMMSS.fff<tag>.csv

Columns (typical):

Column Unit Source
t seconds since session start DAQ worker timestamp
i_pressure_static mA NI-9203, raw
i_pressure_model mA NI-9203, raw
v_pitch_angle V NI-9215, raw
mv_pgb_normal mV/V NI-9237, raw
mv_pgb_axial mV/V NI-9237, raw
mv_pgb_moment mV/V NI-9237, raw
p_static_pa Pa calibrated
p_model_pa Pa calibrated
pitch_deg degrees calibrated
pgb_n_N, pgb_a_N, pgb_m_Nm N, N·m matrix-calibrated
velocity_mps m/s Bernoulli on static-ring ΔP
re dimensionless from velocity, model length, viscosity

Exact column set depends on the channel map (daq/channel_map.py).

The filename format DDMMYY HHMMSS.fff<tag>.csv is inherited from AeroWare so existing post-processing scripts work unchanged.

Conventions for tagging runs

The optional <tag> in the filename is taken from the Acquisition panel's tag field. Use it to mark the run in a way the filename system can index — examples: _baseline, _naca0012_alpha_05, _smoke_only. Avoid spaces; use underscores. Avoid characters that the Windows filesystem rejects (: * ? < > | / \).

How much data per session

At 5 Hz with ~14 columns of doubles plus a timestamp, a CSV row is ~150 bytes. A one-hour session is roughly 2.6 MB. A full day of measurements is well under a gigabyte. Free space on E:\ is not a routine concern but check before starting if you are using a fresh drive.

Downstream post-processing

Post-processing is not in this repository — it lives with the individual experiments. The contract from ADCL WinSoft to downstream is the CSV format above and the matrix calibration on disk at E:\Wind_tunnel\AeroWare\Configs\N_C1_inv*.csv. If a downstream script reads the CSV and produces, say, force-vs-AoA plots, it can be invoked independently from MATLAB, Python, or a Jupyter notebook.

Validating against AeroWare

While ADCL WinSoft is still being validated, the workflow for a fresh calibration session is:

  1. Run AeroWare's DAQ pipeline (motor stopped) for a known reference condition.
  2. Save the AeroWare CSV.
  3. Run ADCL WinSoft's DAQ pipeline against the same physical state.
  4. Compare the engineering-unit columns. They should match to within transducer noise.

If they do not, the discrepancy is either in the channel map, the per-channel calibration, or the matrix application. Walk through daq/channel_map.py, daq/calibration.py, and the matrix file in that order.