GitHunt
TR

transover/sEMG-MMG_SYNC

Synchronous acquisition and analysis for sEMG-MMG. NI9205 and TCP/IP were used to collect data generated by Quspin and BioSemi.

logo
English简体中文

Schematic Diagram

SchematicDiagram_SignalAcquisition Sensors Synchronous_Architecture.svg

Instructions for Use

Synchronous acquisition and analysis for sEMG-MMG. NI9205 and TCP/IP were used to collect data generated by Quspin and BioSemi.

  • Analog data acquisition of QuSpin (OPMs device), BioSemi (sEMG/ECG device), CIYENIC (muscle force device) and other devices is performed through the cDAQ unit of National Instruments. This interface leads to multiple data streams of different devices, multi-threaded synchronous execution, the core technology around NI-DAQmx, PsychToolBox/PsychoPy and TCP/IP protocols. NI-DAQmx is based on the ctypes library and is a complex, highly object-oriented wrapper for developing C API implementations. The Serial/Parallel protocol controls and records stimulus levels via a serial port or parallel port (LPT driver required, InpOut32/64 is an open source Windows DLL and driver for direct access to hardware ports).
  • PsychoPy is based on the underlying controls of the PsychToolBox, combining the graphics rendering benefits of OpenGL with syntax to provide stimulus presentation and control, with asynchronous high-precision planned timing, for cognitive neuroscience and experimental psychology research. TCP/IP protocol wirelessly obtains real-time sensor information through data stream interception.
  • Click [Record] to turn on the acquisition state indicator light and click [stop] to stop recording. When the connection state, display state, acquisition state and stimulus indicator lights are all on, and the data will be automatically saved as 6 independent files. Multiple experimental tasks were recorded and named by date under the directory ./GUI_Output/Data/, and each task contains 7 independent files.

You can download the UI_Collector.exe tool in Release for the task of sEMG-MMG acquisition, as shown in the following figure:

SignalAcquisition SiganlPlotWindow


Operations

1. Using the NI9205 Acquisition Board and Installing the NI Driver:

  • In the NI-DAQmx_driver directory, run ni-daqmx_24.0_online.exe and select the default installation settings.
  • Open the device Manager and check whether the driver items under NI Data Acquisition Devices are displayed correctly, such as cDAQ-9171, NI9205(DSUB)
  • In subsequent use, if UI_collecter.exe fails to recognize NI9205, you need to match the fields of NI_Param in the following program. You must set the hardware name to cDAQ1Mod1!
  • If parallel port triggering is needed, follow help instructions to configure additional driver files. Please ensure that the parallel driver is correctly configured to prevent the _inpout dependency of psychopy from reporting errors(Important). Otherwise, delete the inpout32.dll, inpoutx64.dll or dlportio related files in the directory: C:\Windows\System32 to make sure that you can successfully start the software.

2. Using the BioSemi Acquisition Device and Installing the TCP/IP Server:

  • Download ACTIVIEW806 from the BioSemi directory and use it directly. If LabView files are missing, install LabView RuntimeEngine 2016 (64bit)/setup.exe.
  • Run the batch file in the BioSemi directory to launch ActView806-Lores.exe, and select the configuration file ACTIVIEW806/Configuring/sEMG_A32_Config.cfg.
  • Set the TCP Server local port to 8888, and choose TCP subset A1~A32 (32).

3. Completing TCP/IP Connection and Viewing Acquisition Changes on ActView806 by Selecting A1~A32 After Successful Connection:

Steps:

  1. When the user starts collecting data, the server's TCP Listening round icon turns green, indicating that Biosemi ActiveTwo is listening and ready to establish a connection.
  2. After the user runs the client function and connects successfully, the TCP Connected circular icon in Biosemi ActiveTwo will turn green, indicating that Biosemi is transmitting data to the client.
  3. Read data (Once the connection is established, parameters are disabled and can only be modified after the connection is terminated. The number of bytes received and transmitted is also reported in Biosemi ActiveTwo.)

Notes:

  1. Users must ensure that the TCP/IP function parameters in the client match those set in Biosemi ActiveTwo.
  2. Note that since Biosemi ActiveTwo acts as a server, a connection cannot be established unless Biosemi ActiveTwo is running in display or recording mode.
  3. Parameters in Biosemi ActiveTwo are located on the TCP Server tab and must be adjusted before running Biosemi ActiveTwo. Once Biosemi ActiveTwo starts data acquisition, even in display mode, parameters cannot be changed.
  4. Be careful to select the number of channels; otherwise, even if the connection is successful, data cannot be read.
  5. Streaming through TCP/IP introduces several hundred milliseconds of delay and tens of milliseconds of jitter. Data streamed via TCP/IP cannot be used directly for precise timing and requires buffering.

Data Transfer Protocol-24bit

Parameters (TCP/IP parameters used for connecting with Biosemi):

  • IP address (host):
    If running on the same machine as Biosemi ActiveTwo, set it to 127.0.0.1. Otherwise, use the IP address of the machine running Biosemi ActiveTwo.
  • Port (port):
    The port used for communication. It must match the port reported by the TCP server in Biosemi ActiveTwo. The default value is 8888.
  • Samples per packet (tcpsamples):
    This defines the number of sample points included in each packet sent by Biosemi ActiveTwo. It depends on the sampling rate chosen by the user.
  • Bytes per sample (bytes):
    This defines the number of bytes used to represent each sample. It is fixed regardless of the sampling rate and cannot be changed by the user.
  • Channels + triggers (channels):
    This shows the number of selected channels (plus triggers). It is controlled by the channels setting, which will be described later in the parameters section dedicated to EMG data (section: Biosemi parameters).
    This value must match the one reported by Biosemi ActiveTwo.
class Param:
    """
    Data Acquisition Parameter Control Class
    """
    device = None                    # ActiveTwo device instance
    host = '127.0.0.1'               # Host IP address
    port = 8888                      # Port number
    SampleFrequency = 2048           # Sampling rate (Hz), recommended value: 2048
    ChannelNum = 32                  # Number of channels
    tcpsamples = 4                   # Samples per packet
    gain = 0.03125                   # Signal gain
    bytes_data = b''                 # Temporary storage for raw byte data of all channel samples in a packet

    Status = 'off'                                     # Acquisition status ('on' = running, 'off' = stopped)
    SampleNum = 1                                      # Number of collected samples, including initial point
    BufferSize = 128                                   # Buffer size (number of samples)
    time_start, time_end = None, None                  # Task start and end timestamps (datetime objects)
    Duration = None                                    # Total recording duration (in seconds)
    IsRecording = False                                # Whether to write data to file in real time
    WindowLength = 20                                  # Length of the data window (seconds) for displaying recent samples; 
                                                       # if too large (>1500) it may cause stream buffer overflow errors
    FileName = './GUI_Output/Data/BioSemiData.txt'     # Path for saving recorded data

    Unit = 'uV'  # Data unit
    buffer = np.zeros((ChannelNum, BufferSize))     # Buffer array of size (channels × buffer_size), e.g., 32×128
    time = np.linspace(0, SampleNum / SampleFrequency, num=SampleNum, endpoint=False)  # Time vector (includes 0 at the start), size: samples
    data = np.zeros((ChannelNum, SampleNum))        # Data array (includes initial zeros), size: channels × samples
class NI_Param:
    """
    NI Acquisition Parameters (Parameters)
    """
    DeviceTypeName = 'NI9205'                          # Hardware name of the acquisition card (for reference only, not used in the program)
    DeviceName = 'cDAQ1Mod1'                           # Device name (can be found in NI-MAX, e.g., cDAQ1Mod1)
    Status = 'on'                                      # Acquisition status ('on' means reading, 'off' means stopped)
    SampleFrequency = 1000                             # Sampling rate (Hz), recommended value is 1000
    SampleNum = 1                                      # Number of sample points, including the starting point
    DropSampleNum = 1                                  # Number of sample points collected before recording starts
    callback_samples = 0                               # Actual amount of data read per channel in the callback
    BufferSize = 100                                   # Data buffer size per channel
    CallbackSize = BufferSize                          # Threshold of data amount to trigger the callback
    buffer_in_size_cfg = round(BufferSize * 1)         # Internal buffer size, for clock configuration
    ChannelNum = 30                                    # Number of valid AI channels set for the NI device (NI9205 has 10 physical slots; OPMs use Bx, By, and Bz axes per slot, resulting in 30 AI channels)
    Unit = 'V'                                         # Unit of the data
    MaxVoltage, MinVoltage = 10.0, -10.0               # Maximum and minimum analog voltages (V)
    time_start, time_end = None, None                  # Start and end times of the task (datetime, when "start" is clicked)
    time_start_acquire, time_end_acquire = None, None  # Start and end times of data acquisition (datetime, when "record" is clicked)
    Duration = None                                    # Total recording duration (s)
    IsRecording = False                                # Whether real-time file writing is enabled
    WindowLength = 10                                  # Length of the latest data window (s); defines maximum data size; if too large (>1500), may cause stream buffer overflow errors
    start_time_list = []                               # List of timestamps for each task start
    stop_time_list = []                                # List of timestamps for each task pause
    FileDir = './GUI_Output/Data'                      # Directory for saving data
    FileName = 'NewTempData.txt'                       # Filename for saving data
    FilePath = os.path.join(FileDir, FileName)         # Full path for saving data

4. Launch UI_Collector and Follow Help Instructions to Complete Data Acquisition

  1. Launch the software. If the NI9205 is connected properly, the [Connection Status] indicator will light up; otherwise, an error message will pop up.
  2. Check [Enable EMG] to light up the [EMG] indicator.
  3. Enter the stimulus information and click [STI On]. An experiment paradigm prompt will appear; click [OK] to light up the [Stimulus] indicator.
  4. Click [Record] to light up the [Acquisition Status] indicator, indicating that data streams are being written to file in real time (to accurately record timestamps, you must click [Record] to enter recording mode before clicking [Start]).
  5. Click [Start] to light up the [Display Status] indicator, indicating that the NI task is active and data collection and display have started (if [Record] is not clicked, data will be previewed but not saved).
  6. Click [Stop] to turn off both [Display Status] and [Acquisition Status] indicators, indicating that the acquisition or preview task is paused (in stimulus presentation mode, [Start] cannot be clicked again).
  7. Click [Close] to turn off all indicators, indicating that the task has ended. To start a new acquisition, the software must be restarted.
  8. Click [Save] (not needed in recording mode) to save partial data from the graph into a custom file (Note: it is not recommended for saving all data, as real-time data can be saved automatically. Long-term recording with this method requires a large amount of memory).
  9. Click the toolbar [Export (PDF)] to export experimental information as a PDF file.
  10. Click the toolbar [View Timing] to view timing information and compare the start and end times and delays of different modalities.
  11. Click the toolbar [Plot Image] to plot high-resolution images and preview collected data.
  12. Check [Enable Filter] to filter real-time images without affecting the written data.
  13. Check [Enable Unit] to switch data units for real-time images and automatically convert values (configurable in [Tab Config] under channel modality settings).
  14. Click [Choose CH] to switch the displayed channels.
  15. The control bar widgets allow play, pause, global view, zoom, and removal control of real-time images.
  16. Hover the mouse over any button to view its function information.

Example of signal acquisition process
Example of signal acquisition process

Verification

  • The residual magnetism of the magnetic shielding environment under the non-magnetic sEMG device was shown in the following figure. All the residual magnetism in the radial direction is within the magnetic compensation range (<50 nT) and has a small variation range, which indicates the feasibility of the sEMG-MMG hardware configuration.

Remanence Orientation Remanence Intensity

  • The collected analog data is 100% consistent with the digital signal, demonstrating the lossless and distortionless characteristics of the software UI_Collector.exe. This reflects the accuracy and stability of the acquisition system.
  • Furthermore, from the measured sEMG-MMG signal images, the timing alignment of each trial of the 2 modalities can be seen. These results indicate that we can record sEMG and MMG simultaneously very well and maintain a high modal synchrony between the signals.

Analog/Digital Signals sEMG-MMG Signals

Results

  • The ./GUI_Package directory contains resources such as NI9205_offset and subject, which can be configured for the NI physical channel bias voltage, preloaded subject information, etc
  • Click [Record] to turn on the acquisition state indicator light and click [stop] to stop recording. When the connection state, display state, acquisition state and stimulus indicator lights are all on, and the data will be automatically saved as 6 independent files. As shown in the following figure, multiple experimental tasks were recorded and named by date under the directory ./GUI_Output/Data/, and each task contains 7 independent files:

Files

  • The PDF file records the brief information of the experiment (which needs to be exported manually), which offers the overall preview;
  • NewTempData.txt and BioSemiData.txt respectively represent the MMG and sEMG data recorded under the autonomous contraction of skeletal muscle;
  • NIConfig.pkl and BioSemiConfig.pkl respectively record the configuration information such as experiments, hardware, channels, and timing of MMG and sEMG;
  • Psychopy.pkl records the occurrence time of stimuli for event division;
  • Info.txt records the experimental description information, such as paradigm information and subject information;
  • The post-processing results of the above original data are under the Process directory (which need to be analyzed and obtained in UI_Reader.exe).

Files Files Files


License

  • The texts, code, images, photos, and videos in this repository are licensed under BSL-1.0 license

Optimization

✨ New Function

  • New functions such as Magnetomyography (MMG), Electromyography (EMG), Muscle Power Assessment (MPA) have been added.
  • The main interface supports translation between Chinese and English by [Settings] in the menubar
  • Enable preloading of subject information, real-time data acquisition, display and saving, and uses process isolation and asynchronous execution in multiple tasks. There is no need to worry about conflicts in tasks such as audio stimulation, data collection, real-time data file writing and dynamic image display.
  • Added PDF export function and timing viewing function.
  • The NI9205 hardware voltage bias has been added. The baseline voltage detected when no hardware is connected (which can be regarded as a constant amount for a short period of time) has been software-calibrated in the program (updated on 2024-5-16 23:08).
  • After clicking the button [Record], enter the automatic save mode. The save location is in the ./GUI_Output directory of the same directory as exe. The data composition can be seen in ./Help.

⚡ Improvement

  • Performance Enhancement: Developed in environments like gcc and python310, compiled into C project files, achieving a speed increase of over 30% for the modules.
  • Accuracy Improvement: Leveraged low-level control through PsychToolBox to achieve sub-millisecond stimulus delay, with state markers ensuring data synchronization across different virtual channels.
  • Compilation Optimization: Disabled slow operations such as LTO and debug symbols, streamlined dependencies for parallel packaging, significantly reducing library resource dependencies, dynamic library calls, and external dependency issues.
  • UI Enhancement: Developed using the ctypes library, supporting the nidaqmx library (implementing complex, highly object-oriented wrappers around the NI-DAQmx C API).

🐛 Bug Fixes

  • It perfectly solved the stream buffer overflow error that occurred in the task of nidaqmx, avoiding data loss in long-term tasks (This error was caused by the accumulation of data volume leading to heavy memory burden, resulting in a delay of assignment operation for about 30 minutes, and then callback delay).
  • Fixed thread crash issues caused by Process finished with exit code -1073741819 (0xC0000005) access violation errors.
  • Resolved missing driver compatibility issues for psychopy.parallel._inpout.
  • Fixed UnboundLocalError, FileNotFoundError, and crash issues caused by missing temporary compressed packages (embedded resources).

📦 Dependency Updates

  • Upgraded psychopy to version 2023.
  • Please ensure that the parallel driver is correctly configured to prevent the _inpout dependency of psychopy from reporting errors(Important). Otherwise, delete the inpout32.dll, inpoutx64.dll or dlportio related files in the directory: C:\Windows\System32.
  • File resources are located under the ./GUI_Package directory in the compressed package, where users can modify participant information files (csv) and bias files (pkl).

Feedback

🙏 Support

  • If this content is helpful to you, please click Star ⭐ on the top right corner of the page to show your support. Thank you!
  • If you encounter any issues, please contact the author at transover@buaa.edu.cn for support.