This page describes implementation details.
- Starting point is using a Device object matching attached hardware: DeviceP24 or DeviceI24
- If you have multiple devices, create multiple Device instances
- With capabilities it is possible to query for available layer
- To create a Device object, a Connection object is required, use SerialConnection to connect to a serial port
- Connection must be opened and closed
- Call device.initialize() to get a defined state of the device (it stops any active stimulation/measurement)
- Device object has layers to access commands
- Layer object has functions to send commands to the device and process acknowledges
- To access layer, use helper functions get_layer_xxx
- DeviceP24 has layer general, low level and mid level
- DeviceI24 has layer general and dyscom
- Do not mix usage of layers because device has a single internal state, e.g. calling low level init() and afterwards mid level update() will not work
- Each device has an instance of a PacketBuffer
- Should be used to read packets from connection
- Handles extraction of packets from byte stream
- Most functions communicating with the device are async functions using name schema xxx, because they wait for a matching acknowledge and return values from acknowledge
- If no matching acknowledge or no acknowledge arrives in time, an exception is raised
- If a command has an error information and an error is set, an exception is raised
- The async functions connection buffer handling is always identical:
- Clear buffer
- Send command
- Process incoming data until the expected acknowledge arrives
- More data remains in connection buffer
- Do not call async functions in parallel (e.g. from different event loops), because each function expects specific commands from the device and clears incoming data buffer
- Additionally functions with naming schema send_xxx are normal functions not waiting for acknowledge
- The acknowledge needs to handled manually by using PacketBuffer object from device
- Library creates a custom logger, see class Logger
- By default some information is logged to console
- Set log level to DEBUG to get more detailed information
logger().setLevel(logging.DEBUG)
- For better performance, disable logger
logger().disabled = True
- Contains functions to get common information like device serial or firmware version
- Contains functions for mid level stimulation
- This mode is good to let the device stimulate a predefined pattern until stop() is send
- Usage
- Call init() to set device in mid level mode
- Call update() with stimulation pattern
- Call get_current_data() every 1.5s to keep stimulation ongoing
- Call stop() to end stimulation and leave mid level mode
- Contains functions for low level stimulation
- This mode is good to react to a external trigger to change stimulation pattern
- Without send_channel_config() the device will not stimulate
- Usage
- Call init() to set device in low level mode
- Update configuration with send_channel_config() when external trigger occurs
- As soon as send_channel_config() arrives at device, it stimulates according stimulation pattern
- It stops stimulation when stimulation pattern is over
- Call stop() to leave low level mode
- Contains functions for dyscom level
- This mode is used by I24 to measure EMG or BI
- Usage for live data
- Call power_module() to power on measurement module
- Call init() with parameter for measurement and DyscomInitFlag for live data
- Call start() to start measurement
- Device sends now DlSendLiveData packets with measurement data
- Call stop() to end measurement
- Call power_module() to power off measurement module
- Usage for measurement data read from memory card
- Call power_module() to power on measurement module and memory card
- Call init() with parameter for measurement and DyscomInitFlag for storage mode
- Result contains measurement id, that is the filename used later
- Call start() to start measurement
- Device sends nothing but stores measurement data on memory card
- Call stop() to end measurement
- Call power_module() to power off measurement module
- Call get_meas_file_content() with filename from init() to get measurement data
- Call power_module() to power off memory card
- IMPORTANT: not all storage related functions are tested
- On Windows
- Install usbipd-win
usbipd listusbipd bind --busid <BUSID>
- On Linux
- Install usbip
sudo apt install linux-tools-generic usbip
sudo usbip attach -r <host-ip> -b <BUSID>- In case of permission error
sudo chmod 666 /dev/ttyACMx
- Install usbip
- Init state seems always be UNUSED
- Output data rate depends on init params filter property
- Setting a filter overwrite other settings
- ADS129x register channel 1-4 settings
- ADS129x config register output data rate
- Maybe more register values are changed
- Return never meaningful values, probably not implemented on I24 side
- Dl get types (table 23)
- 0 -> Battery (was Unused)
- SignalType for each sample is always 0
- Contains always 5 samples, regardless of selected signal types in DL_init
- Fifth sample value seems always be zero