Skip to main content

Deimos

Control program and data integrations for the Deimos data acquisition ecosystem.

See the project readme for contact details as well as commentary about the goals and state of the project.

The control program and the firmware-software shared library share a changelog at the workspace level.

Deimos DAQ hardware

Install - Rust

cargo add deimos

Install - Python

pip install deimos-daq

Features & Roadmap

✅ Implemented | 💡 Planned

Feature Category Features
Control Loop ✅ Fixed-dt roundtrip control loop
✅ Network scanning for available hardware
✅ Planned loop termination
✅ Global event logging
✅ Reconnection
✅ Low-CPU-usage background operation
Control Calcs ✅ User-defined custom calcs
✅ Explicit (acyclic) calc expression
✅ Low-pass filters
✅ Sequenced state machines
✅ Polynomial calibration curves
💡 Cyclic expressions with explicit time-delay
💡 Prototype calc w/ rhai script-defined inner function
Data Integrations ✅ User-defined custom targets
✅ Manual read/write
✅ CSV
✅ In-memory dataframe
✅ TimescaleDB
💡 InfluxDB
💡 Zarr file/bucket
💡 Generic sqlite, postgres, etc.
Hardware Peripherals ✅ Deimos DAQs
✅ User-defined custom hardware
✅ User-defined hardware drivers
✅ Hardware-out-of-the-loop wrapper
Socket Interfaces
(peripheral I/O)
✅ User-defined custom interfaces
✅ UDP/IPV4
✅ Unix socket
✅ Thread channel sideloading
💡 TCP
💡 UDP/IPV6

Concept of Operation

The control program follows the hardware peripheral state machine, which is linear except that an error in any peripheral state results in returning to Connecting.

Peripheral states:

  1. Connecting (no communication with the control machine)
  2. Binding (waiting to associate with a control machine)
  3. Configuring (waiting for operation-specific configuration from control machine)
  4. Operating (roundtrip control)

The controller initialization schedule is:

                  --------------------binding timeout windows
                 /                          /
                /    Controller init       /           
             |====|=====================|====|         timeout to operating
     scan for|                          |==============|
  peripherals|                          |      \
   (broadcast|              sent binding|       \
     binding)|                          |    configuring window
                             peripherals|
                              transition|
                          to configuring|            

In words,

  1. Scan network for peripherals available to bind
    • Broadcast binding request, but do not send configuration; allow Configuring to time out back to Connecting
  2. Initialize controller (set up data integrations, initialize internal state, etc)
  3. Send binding request
  4. Wait for binding responses
  5. Send configuration
  6. Wait for start of Operating

Peripherals acknowledge binding and transition to configuring on their next internal cycle (usually 1ms) after receiving a request to bind. They will then wait for configuration input until the timeout to operating, and either proceed to Operating if configuration was successful, or return to Connecting (and likely return immediately to Binding) if configuration was not successful.

The control loop then follows a fixed schedule on each cycle:

  1. Send control input to peripherals
  2. Wait for outputs from peripherals
    • Target synchronization to middle of cycle
  3. Update time-sync control
  4. Run calculations on peripheral outputs

Control loop timing uses the control machine's best available monotonic clock. Both system time in UTC with nanoseconds and monotonic clock time are stored in order to support post-processing adjustments to account for the slow drift of the monotonic clock relative to system time.

Example: 200Hz Control Program w/ 2 DAQs

use std::time::Duration;

use deimos::calc::{Constant, Sin};
use deimos::peripheral::{PluginMap, analog_i_rev_3::AnalogIRev3};
use controller::context::ControllerCtx;
use deimos::*;

// The name of the operation will be used as the table name for databases,
// or as the file name for local storage.
let op_name = "test_op".to_owned();

// An optional dictionary mapping user-defined custom hardware
// peripheral model numbers to initializer functions.
let peripheral_plugins: Option<PluginMap> = None;

// Configure the controller
//    Sample interval is taken as integer nanoseconds
//    so that any rounding and loss of precision is visible to the user
let rate_hz = 200.0;
let dt_ns = (1e9_f64 / rate_hz).ceil() as u32;  // Control cycle period

// Define idle controller
let mut ctx = ControllerCtx::default();
ctx.op_name = op_name;
ctx.dt_ns = dt_ns;
let mut controller = Controller::new(ctx);

// Set up any number of data integrations,
// all of which will receive the same data at each cycle of the control loop
//    TSDB-flavored postgres database
let buffer_window = Duration::from_nanos(1); // Non-buffering mode
let retention_time = Duration::from_secs(60 * 60);
let timescale_dispatcher: Box<dyn Dispatcher> = TimescaleDbDispatcher::new(
    "<database name>",  // Database name
    "<database address>", // URL or unix socket interface
    "<username>",  // Login name; for unix socket, must match OS username
    "<token env var>",  // Environment variable containing password or token
    buffer_window,
    retention_time,
);
controller.add_dispatcher("tsdb", timescale_dispatcher);

//    A 50MB CSV file that will be wrapped and overwritten when full
let csv_dispatcher: Box<dyn Dispatcher> =
    CsvDispatcher::new(50, dispatcher::Overflow::Wrap);
controller.add_dispatcher("csv", csv_dispatcher);

// Associate hardware peripherals that we expect to find on the network
// The controller can also run with no peripherals at all, and simply do
// calculations on a fixed time interval.
controller.add_peripheral("p1", Box::new(AnalogIRev3 { serial_number: 1 }));
controller.add_peripheral("p2", Box::new(AnalogIRev3 { serial_number: 2 }));

// Set up calcs that will be run at each cycle
//     Add a constant for duty cycle and a sine wave for frequency
let freq = Sin::new(1.0 / (rate_hz / 100.0), 0.25, 100.0, 250_000.0, true);
let duty = Constant::new(0.5, true);
controller.add_calc("freq", freq);
controller.add_calc("duty", duty);
//     Set a PWM on the first peripheral to change its frequency in time
controller.set_peripheral_input_source("p1.pwm0_freq", "freq.y");  // A value to be written to the hardware
controller.set_peripheral_input_source("p1.pwm0_duty", "duty.y");
//     Set a PWM frequency on one peripheral based on a measured temperature from the other peripheral
controller.set_peripheral_input_source("p2.pwm0_duty", "duty.y");  // Values can be referenced any number of times
controller.set_peripheral_input_source("p2.pwm0_freq", "p1_rtd_5.temperature_K");

// Serialize and deserialize the controller (for demonstration purposes).
// All of the configuration up to this point, including any custom peripheral plugins
// or user-defined calcs, are serialized with the controller and can be written to and read from a json file.
let serialized_controller: String = serde_json::to_string_pretty(&controller).unwrap();
let _deserialized_controller: Controller = serde_json::from_str(&serialized_controller).unwrap();


// Run the control program
// (skipped here because there are no peripherals
// or databases on the network in the test environment).
// controller.run(&peripheral_plugins, None);

Direct-to-PC Ethernet Connection and Statically-Addressed Networks

Deimos DAQs can be connected directly to your computer by ethernet, bypassing the need for a router or network switch. They can also be used on networks with a switch but no router.

When a Deimos DAQ connects to a network without a DHCP server to provide dynamic IP address assignments, it will automatically self-assign an IP address in the 169.254.x.[2-254]/16 range. It will attempt up to 3 candidate addresses, which limits the maximum amount of address resolution spam on the network, while also yielding a trivially small probability that no candidate address is available.

The rev7 firmware's IPv4 address manager follows this state machine:

stateDiagram-v2
    direction LR

    classDef a stroke-width:2px

    [*] --> Unconfigured:::a

    Unconfigured --> TentativeFallback:::a : Claim next MAC-derived<br>static address candidate
    Unconfigured --> ActiveDhcp:::a : DHCP configured

    TentativeFallback --> ActiveFallback:::a : No ARP conflict
    TentativeFallback --> Unconfigured:::a : ARP conflict
    TentativeFallback --> ActiveDhcp:::a : DHCP configured

    ActiveFallback --> ActiveDhcp:::a : DHCP configured

    ActiveDhcp:::a --> Unconfigured: DHCP deconfigured

To connect directly without a router,

  1. Connect the DAQ's ethernet cable to your computer's ethernet port.
  • (or to a shared network switch with no router).
  • If your computer does not have an ethernet port, an ethernet-to-USB adapter can be used at the expense of added latency.
  1. Check your computer's network settings.
  • Make sure that a static IP address was assigned in the 169.254.X.Y range.
  • This should occur automatically on MacOS and Windows.
  • On linux, you may need to manually set a static IPV4 address: 169.254.254.1/16

Make sure the netmask for your computer's static address is set to exactly /16 (255.255.0.0).

Otherwise, the DAQ will not recognize your computer as being on the same link-local network, and will not respond to your attempts to scan or bind it.

Release files for deimos-daq 0.20.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for deimos-daq 0.20.0
File Size Uploaded
deimos_daq-0.20.0.tar.gz 759.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for deimos-daq 0.20.0
File
deimos_daq-0.20.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_x86_64.whl CPython 3.11 abi3 Linux musl 1.2+ x86-64 Details
deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_i686.whl CPython 3.11 abi3 Linux musl 1.2+ x86-32 Details
deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_armv7l.whl CPython 3.11 abi3 Linux musl 1.2+ ARMv7l Details
deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_aarch64.whl CPython 3.11 abi3 Linux musl 1.2+ ARM64 Details
deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.11 abi3 Linux glibc 2.17+ x86-64 Details
deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl CPython 3.11 abi3 Linux glibc 2.17+ IBM System/390x Details
deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl CPython 3.11 abi3 Linux glibc 2.17+ PowerPC 64-le Details
deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl CPython 3.11 abi3 Linux glibc 2.17+ ARMv7l Details
deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.11 abi3 Linux glibc 2.17+ ARM64 Details
deimos_daq-0.20.0-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details
deimos_daq-0.20.0-cp311-abi3-macosx_10_12_x86_64.whl CPython 3.11 abi3 macOS 10.12+ x86-64 Details

Total release size: 31.0 MB

Release files / deimos_daq-0.20.0.tar.gz

Download URL deimos_daq-0.20.0.tar.gz
Size 759.0 kB
Tags Source
SHA-256 checksum
How to use checksums
792e6723edb016ade1dd6d24e03392e16a2fe5e9c7e3d4d1c560f415f3cb4bcc
BLAKE2b-256 checksum
How to use checksums
04bfdb982aabc0e6deed48111ed7e63a68cacd0ded0a9c74ea36935f7c1ae68a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-win_amd64.whl

Download URL deimos_daq-0.20.0-cp311-abi3-win_amd64.whl
Size 2.4 MB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
1b77a8113dc0a42c6b89ecc82592b9b13aef7f7b8d5a741abc66c4cf73f4ff72
BLAKE2b-256 checksum
How to use checksums
2f7f950e862b046513e3fa085e88c96c97d85134c8c052d03d99e3a887b8ac52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_x86_64.whl

Download URL deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_x86_64.whl
Size 2.7 MB
Tags CPython 3.11 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
e6c2016f1cdd2324dd2762edcfaf564dd57f20a2af59b17fe2ce120acf798cd3
BLAKE2b-256 checksum
How to use checksums
e855f8a0e841cb4c4f2324e3e8a06b9a65dc92da781b43313019083b6deea8b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_i686.whl

Download URL deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_i686.whl
Size 2.7 MB
Tags CPython 3.11 Linux musl 1.2+ x86-32 abi3
SHA-256 checksum
How to use checksums
d1b8de526e73f8cb41643de5531ad9361b35832cba2c246171b84c3db0ab204a
BLAKE2b-256 checksum
How to use checksums
bc60dce4af549c99b96edd8924d0f25d5138f9c1bef91714889eab02c7187a4d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_armv7l.whl

Download URL deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_armv7l.whl
Size 2.8 MB
Tags CPython 3.11 Linux musl 1.2+ ARMv7l abi3
SHA-256 checksum
How to use checksums
21a422e988f4b85a0e33f343596de0839fbcec85a1b1b23f8988444371d2a535
BLAKE2b-256 checksum
How to use checksums
fe0d12b317d3e27a088a5e51cf127435f5807788258463bb43c30b1a24be7d8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_aarch64.whl

Download URL deimos_daq-0.20.0-cp311-abi3-musllinux_1_2_aarch64.whl
Size 2.6 MB
Tags CPython 3.11 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
29e589ac614c0b68e4b2ce5a2825ae5e498089daaf72bec3c0ac2a6f7d2b77af
BLAKE2b-256 checksum
How to use checksums
419e9ea34ca2fedac81e3242a51e092fe98853621b8a6047978921ef93745160
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.4 MB
Tags CPython 3.11 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
51d8126afff1cdc6e954a177cb0402d1e4371fa67145d2539910cb7d09442f01
BLAKE2b-256 checksum
How to use checksums
01e1080e4741836d3fa5a96eee3e2d9bb43cb20e62b8c1f46515a80be5a2b028
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl

Download URL deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
Size 2.5 MB
Tags CPython 3.11 Linux glibc 2.17+ IBM System/390x abi3
SHA-256 checksum
How to use checksums
c89b23e4338ed1251c0e5f22ec123bdb3b15301fb305c2f5498f9c6925b185b4
BLAKE2b-256 checksum
How to use checksums
908fcd1e1afc79a429e9ba41483016fe33c44039630aee02910077cef0fddf5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl

Download URL deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Size 2.6 MB
Tags CPython 3.11 Linux glibc 2.17+ PowerPC 64-le abi3
SHA-256 checksum
How to use checksums
d1c5f1fa0986553e26dfcf3cb9ecb7d84045f2535da8ffec0658022a1fd5e8a9
BLAKE2b-256 checksum
How to use checksums
8a4490f3d2161af2807d2e573d202edb84c9188d3df6f116f5ce05ec3c837983
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl

Download URL deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Size 2.5 MB
Tags CPython 3.11 Linux glibc 2.17+ ARMv7l abi3
SHA-256 checksum
How to use checksums
efdccd51af07e0450ace3445459395d28af4ee40f02285d8afd1cb5812c0ebfb
BLAKE2b-256 checksum
How to use checksums
0ad04d348ce7ef6a6c7736a4fef73b3bb0fea729a352e86c1774c3404eab67ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL deimos_daq-0.20.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 2.4 MB
Tags CPython 3.11 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
cb64283205565e9a342653bdf4df400fde2a6abf4fea80c41d0223b17a6d52db
BLAKE2b-256 checksum
How to use checksums
f2802536e581ef9cc036d86c1b2c6b40deab8a5ad2fad22c42c6215b95de8695
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-macosx_11_0_arm64.whl

Download URL deimos_daq-0.20.0-cp311-abi3-macosx_11_0_arm64.whl
Size 2.3 MB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
cad4ba5c43db0c63722b8f0fd0a26bf4c719051fab3ae7f5ca983abbd65b7d81
BLAKE2b-256 checksum
How to use checksums
55e1530270573c2f4228d6a4d428fb59c2692c61c6cf53a044a937a43c596beb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / deimos_daq-0.20.0-cp311-abi3-macosx_10_12_x86_64.whl

Download URL deimos_daq-0.20.0-cp311-abi3-macosx_10_12_x86_64.whl
Size 2.4 MB
Tags CPython 3.11 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
a53823ca3c27d9a86f6fe40a5e0d76f9e48373976ebc4b97c6dcf7f8b01d29ba
BLAKE2b-256 checksum
How to use checksums
cce7dac6d3b6e0f3227b57292ca49e729c6db9285f7c0f7379141ec3f426a707
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release history Release notifications | RSS feed

This release

0.20.0 This release

13 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page