e1608: a configurable generator update rate, and the achieved rate in the Analog out panel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
0c6e69957d
commit
0d8c583bbb
12 files changed
+181
-11
No files matched your search
@@ -51,7 +51,7 @@ What feeds `Acquisition` is a `DataSource`, one of the registered *kinds*.
|
||||
never reaches the UI files.
|
||||
- The E-1608 source runs **everything inside `poll()`** on the producer thread: posted commands, the
|
||||
connect state machine (Down, Scanning, Halted), the scan read, the 500 ms status check (its not-running restart is skipped when a hardware trigger is configured), the digital
|
||||
input/counter poll and the 20 ms waveform tick. There is no second thread. A connect attempt (discovery,
|
||||
input/counter poll and the waveform tick (every `1 / gen_rate` s, 20 ms by default; one synchronous DAC write per running channel, so a slow board lowers the rate it achieves, which the Analog out panel reports). There is no second thread. A connect attempt (discovery,
|
||||
handshake, calibration read, scan start) can block `poll()` for as long as the command timeout allows each
|
||||
step; that delays only the command queue. Every exception is caught inside `poll()`: an escape would end
|
||||
the producer thread, and `drain_commands()` runs inside the same `try` for that reason.
|
||||
|
||||
@@ -118,7 +118,7 @@ is exported when the option is absent, so GTK's own choice stands.
|
||||
`--source e1608` selects the MCC E-1608 Ethernet DAQ; its settings are `--source-opt` keys, all optional
|
||||
(`address` or `mac`+`subnet`, `port` 54211, `code` 0, `timeout_ms` 2000, `scan_rate` 1000 per channel,
|
||||
`ext_clock`, `trigger` `none|rising|falling|high|low`, `auto_restart` 1, `calibrate` 1, `poll_rate` 10,
|
||||
`mode` `se|diff`, `ai0`..`ai7` `BIP10V|BIP5V|BIP2V|BIP1V` (an absent key = off, **and any `aiN` key at all
|
||||
`gen_rate` 50 (Hz, 1 to 200: the waveform generator's DAC update rate), `mode` `se|diff`, `ai0`..`ai7` `BIP10V|BIP5V|BIP2V|BIP1V` (an absent key = off, **and any `aiN` key at all
|
||||
drops the default**: only a run with no `aiN` key gets `ai0=BIP10V`, so `ai1=BIP5V` alone is channel 1
|
||||
alone, and a value that is not a range name is a channel that is off), `dir0`..`dir7` `i|o`,
|
||||
`plot0`..`plot7`, `plot_counter`, `do_init`, `ao0_init`, `ao1_init`). Either `address` or `mac` is
|
||||
|
||||
@@ -1838,7 +1838,7 @@ kind, so a run without it never shows that kind. The `form` line appears once pe
|
||||
- `kinds=udps,e1608,flatudp,probe`: a missing kind means `register_builtin_sources()` was not called before `parse_args()`,
|
||||
or the env var gate is wrong.
|
||||
- `round_trip=0`: a form's `write` and `read` disagree about a key -- a renamed `SourceConfig` key, or an
|
||||
absent key that was not defaulted. `valid=0` is a default configuration the form refuses. The e1608 form's sample sets address, port, scan_rate, mode, ai1, trigger, dir1 and plot0; a mismatch names one of those. The flatudp sample sets port, bind, multicast, iface, rate, endian and signals.
|
||||
absent key that was not defaulted. `valid=0` is a default configuration the form refuses. The e1608 form's sample sets address, port, scan_rate, mode, ai1, trigger, dir1, plot0 and gen_rate; a mismatch names one of those. The flatudp sample sets port, bind, multicast, iface, rate, endian and signals.
|
||||
- `panel disconnected: sensitive=0 present=1`: **disable, don't hide.** `present=0` is a panel that was hidden
|
||||
or never added; `sensitive=1` is a panel that stays live with no source behind it.
|
||||
- `panel connected: sensitive=1`: anything else means `apply_source_panels` acted on the wrong widget (it must
|
||||
@@ -1865,6 +1865,8 @@ The UDPS run has no `source-` page in `side_stack`, because the UDPS kind has no
|
||||
[e1608] scan socket closed by the board
|
||||
[e1608] reconnect: connects=2 connected=1 ok=1
|
||||
[e1608] resumed: frames_before=612 frames_after=662 ok=1
|
||||
[e1608] generator: requested=100.0 achieved=99.7 panel='100 Hz (requested 100 Hz)' ok=1
|
||||
[e1608] generator stopped: achieved=0.0 panel='off (requested 100 Hz)' ok=1
|
||||
[e1608] scan: found=1 ip=172.21.121.113 mac=00:80:2f:00:16:08 status='1 board found' fill_addr=1 fill_mac=1 rescan_replaced=1 ok=1
|
||||
```
|
||||
|
||||
@@ -1901,6 +1903,17 @@ the one `[e1608] handshake with ...: Connection refused` line, `stream: ... sign
|
||||
drop (neither the scan read nor the status check raised it), `resumed: ok=0` is a reconnect that did not restart
|
||||
the scan (it also reads 0 when `connects` is still 1, since a frame count that grows on a link that never dropped
|
||||
proves nothing).
|
||||
- `generator: requested=100.0 achieved=99.7 ... ok=1`, `generator stopped: ... ok=1`
|
||||
(`UDPSCOPE_PROBE_E1608_GEN=1500`, a run of its own with `gen_rate=100`): `requested` is `gen_rate`, `achieved`
|
||||
the source's own measurement (generator ticks that wrote, per second of wall time, over a window of about 1 s),
|
||||
`panel` the subtitle of the Analog out panel's "Update rate" row. `ok` needs `achieved` within 70% to 110% of
|
||||
`requested` **and** the panel to quote the requested rate; the mock answers at once, so it reads within a
|
||||
percent of `requested`. Far below is a `run_timers()` that re-arms with a constant (the 20 ms the setting
|
||||
replaced reads 50) or a tick that runs late; `panel='off'` while `achieved` is non-zero is a panel that
|
||||
did not refresh (it ticks only while its page is on screen) or one that reads the wrong readout. This line says
|
||||
nothing about a real board, whose DAC writes are slower; there the same row is the measurement. The stopped
|
||||
line must read `achieved=0.0` and a panel that starts with `off`; a non-zero value is a rate that
|
||||
`update_gen_flags()` did not reset when the last generator stopped.
|
||||
- `scan: found=1 ... ok=1`: the form's **Scan network** row against the mock. `found` is the result rows after
|
||||
the first scan; `0` with the second line `did not answer` is an environment with no up, non-loopback
|
||||
broadcast interface that reaches the mock (or a refused broadcast), **not a pass**. `ip` is the listed address
|
||||
|
||||
@@ -437,6 +437,15 @@ precedent, not an exception.
|
||||
levels `1.5, 2.5, 1.5` (the log prints the quantised voltage, so `1.4999, 2.4999, 1.4999` is the
|
||||
expected text), the DOUT bytes `0x00, 0x02, 0x00`, one `COUNTER_RESET`, one `DROP`;
|
||||
- **a rejected code:** mock `--code 1234`, app `code=7`: one error line, the retries stop.
|
||||
- `UDPSCOPE_PROBE_E1608_GEN=1500` with `UDPSCOPE_EXIT_AFTER_MS=5500`, run as `--source e1608 --source-opt
|
||||
address=127.0.0.1 --source-opt port=54711 --source-opt ao0_init=0 --source-opt gen_rate=100` against
|
||||
`tools/mock_e1608.py --port 54711 --log /tmp/e1608-gen100.log` -- the generator's update rate: it starts a Sine on
|
||||
DAC 0 through the Analog out panel (and switches the side stack to that page, since the panel refreshes on its
|
||||
frame clock, which does not tick for a page that is off screen), waits 2.5 s, reads the achieved rate and the
|
||||
panel's "Update rate" row, stops the generator and reads both again 400 ms later. Two lines, in
|
||||
`probe-readings.md`. Then count the mock log's `AOUT` lines: about 250 with `gen_rate=100` (the generator ran
|
||||
for about 2.5 s) and about 125 for a run without the option (default 50 Hz). Short and serial, the mock killed
|
||||
afterwards. It enables nothing else, so it can run alone.
|
||||
- `UDPSCOPE_PROBE_E1608_RECONNECT=8000` -- reads the source after the mock dropped the link and 500 ms
|
||||
later checks the frame count moved on. The reading's own entry is in `probe-readings.md`.
|
||||
- `UDPSCOPE_PROBE_E1608_SCAN=1000` with `UDPSCOPE_EXIT_AFTER_MS=6500`, run as `--source e1608 --source-opt
|
||||
|
||||
Reference in new issue
Block a user