In this exercise, you will measure the nerve conduction speed in the ulnar nerve, which supplies the little finger and half the ring finger. For this, we will use a nerve exciter, which will stimulate the ulnar nerve to fire. This makes the muscles in the palm below the little and ring fingers contract causing a finger spasm. By placing a pair of ECG electrodes in this area, as well as a ground wire, the muscle contractions can be measured by electromyography (EMG). The stimulation signal is powerful enough that it can be measured using the same electrodes in the hand. By detecting both stimulation and contraction, you can calculate the time between the two and combining this knowledge with the distance between excitation and contraction you can theoretically determine the nerve conduction speed. If you wish to read more on the subject, you can find additional information here.
However, using a single measurement will deliver false results. From nerve stimulation to muscle contraction, both the electrical conductance of the signal along the nerve is important, but also the transport of the signal across the terminal synaptic cleft using transmitter substances will play a role (more info on this here. The latter has nothing to do with nerve conductance speed. To exclude this component, we will make two measurements; one at the elbow, and one on the middle of the forearm. Dividing the distance between the excitation sites with the difference in timing from stimulation to muscle contraction you will be able to determine the nerve conduction speed.
In this exercise, you will download two sub-VI's containing pre-recorded data from the two excitation sites. You will construct a LabView VI, which can calculate the timing, and once finished, we will go into the biomedical laboratory to perform the measurements "Live in Vivo!".
LabView Instructions:
You will first construct a VI, which can choose between the two excitation spots, and acquire a signal from either one, plotting the data in a Waveform Graph. The latter will be scaled from -5 to 5, conforming to the amplitude of the input signal from the EMG signal:
- Basic plot:
- Create an empty VI containing a While loop and a Menu Ring with the texts Elbow -> 0 and Forearm -> 1. Call it "Excitation Spot"
- Connect "Excitation Spot" with a case-structure
- Download the SubVI NerveConductionSimSigElbow.vi and place it inside the "0 - Default" case
- Download the SubVI NerveConductionSimSigForearm.vi and place it inside the "1" case
- Connect the iteration counter with the Iteration input on the SubVIs (both of them)
- Connect the output to a Waveform Graph and name it "EMG Signal"
- Remove Y auto-scale and set the limits to -5 to 5
- Run your VI
If you can read anything on the graph you're very good:) The reason the signal flies across the screen, is the sampling rate of 10.000 Hz, sampled 1000 samples at a time. In other words, the SubVIs deliver data each 0.1 seconds - which will also be the case, when you will acquire the physical signals using the DAQ, which will acquire data in the exact same way.
However, we cannot use this setup for measuring the nerve conduction speed. Therefore, we need to construct an Oscilloscope with a trigger function, so we limit the signal to the interesting part. This is implemented using a "Trigger and Gate" function, which will detect sudden rises in signal amplitude caused by the excitation, and extract a user-defined number of samples from this point:
- Triggered Oscilloscope
- For this purpose, you can use the function "Trigger and Gate", which you also used in the Step Response exercise
- Express -> Signal Manipulation -> "Trigger and Gate"
- Set Start sense to "Rising", Start level to 1 and Number of samples to 200
- This makes the function trigger at a rise above 1 volt. The 200 samples cover the interesting part of the signal (found by trial-and-error)
- Connect a Waveform Graph to the "Triggered Signal" output (named it "Triggered EMG Signal") and run the VI
- You will now only see 200 samples. Using the sampling frequency of 10 kHz, this corresponds to 20 ms
- Notice, that the signal is flashing - why is this?
- Non-flashing Triggered signal
- To remove the flashing, you will need to use a shift register to transfer the values from iteration to iteration. Furthermore, you will use the Boolean "Data available" output from the "Trigger and Gate" function to determine if you need to update the data, or transfer it unchanged. Connect this output to a case structure, and connect the relevant wires.
- Run your VI and check that it now runs without flashing
- For this purpose, you can use the function "Trigger and Gate", which you also used in the Step Response exercise
We now have a non-flashing triggered Oscilloscope containing the relevant data starting from the excitations. We can use these to measure when the EMG signal begins. For this purpose, we will use a "Trigger Detection" VI, which will detect the signal drop, when the EMG signal occurs:
- EMG signal detection
- Set "Excitation Spot" to Elbow
- Insert a "Basic Level Trigger Detection" VI
- Programming -> Waveform -> Analog Waveform -> Waveform Measurements -> Waveform Monitoring -> Basic Level Trigger Detection
- Connect the signal from the "Trigger and Gate" function with "signal in", set level to a value close to the start of the EMG signal (read the value on the triggered graph)
- Set trigger slope to "Falling Edge"
- Divide "trigger location" with 10 to get the result in ms and connect it to an indicator called "Nerve Conduction Time"
- Run your VI, and check, that the nerve conduction time corresponds to what you can read physically on the graph.
- Try changing to the forearm data. Does your VI still perform according to plan? Are the values still valid?
Unfortunately, the forearm data have an initial dip, which triggers the EMG detection. To remove this dip, you can analyze a subset of the 200 samples, which will suppress the "false peak":
- Insert a "Get Waveform Subset" VI
- Programming -> Waveform
- Connect the signal from before the "Basic Level Trigger Detection"
- Set "start/duration format" to "Samples" and connect start samples/time with a constant, covering the initial dip - e.g. 50
- Set duration to 150 (200 samples minus the 50 from above)
- Since you have subtracted some samples (50), the trigger value will be incorrect. To correct the measured time, you need to add the 50 subtracted samples to trigger location from the "Basic Level Trigger Decection" VI
In an ideal world, all would now be well. But alas, if you try running the VI, it will fail… This is due to the fact, the initially, the data you are trying to create a subset of is empty. Not until you have found the first peak, will there be data to create a subset from. Thus, you need to create a case structure, setting the subset function to only run, if in fact you have data to create a subset from:
- Insert a case structure around the "Waveform Subset" and "Basic Level Trigger Function" VIs including all the corresponding controls
- Insert a "Number of Waveform Samples" VI and connect it to the signal. This will check if the length of the waveform is greater than zero
- Programming -> Waveform -> Analog Waveform
- Insert a "Greater than 0?" function and connect it to the "Number of Samples" output. Connect the "Greater than 0?" output to the selector terminal
- Run your VI and check that the results correspond to the graphs on both the elbow and forearm signals
Finally, the times for all the detected EMG signals will be saved, and the mean calculated for both elbow and forearm. We perform multiple measurements to increase accuracy. For this, you will use a cluster, containing two numeric arrays. For each peak, the time is appended to the correct array:
- Create a cluster on the Front Panel and name it "Nerve conduction times Initialization". Insert two control arrays into it. Fill them both with numeric controls and rename the top to "Elbow" and the bottom to "Forearm".
- Move the cluster to the left of the while loop
- Right-click the icon on the Block Diagram and choose "Hide Control"
- Create a shift register and connect the output from the cluster to it
- You need to use the "Excitation spot" menu ring icon for both selecting the input signal, and choosing where to store the detected times. Therefore, you will create a local variable for selecting the input signal and move the ring control itself into the trigger detection case structure:
- Move the "Excitation spot" menu ring icon into the case performing the trigger detection
- Create a local variable (right-click -> Local variable) and set it to read. Move it to the old position of "Excitation spot" and connect it to the input of the case structure
- Create a case structure inside the trigger detection case, inside the "True" case
- Connect the selector terminal with the menu ring "Excitation spot"
- Insert an "Unbundle By Name" and "Bundle By Name" function inside the newly created case structure
- Programming -> Cluster, Class & Variant
- Also insert a "Build Array" function
- Connect "Unbundle By Name" with the left shift register - it will now change to "Elbow". Using this function, you can access the individual structures in the cluster by name. Depending on whether you select "0, Default" or the "1" case, you will select either Elbow (=0) or Forearm (=1) by clicking the title
- Connect the output of "Unbundle By Name" witht the top input of the "Build Array" function
- Wire the value from the "Nerve conduction time" indicator to the bottom input
- This will append the latest nerve conduction time to end of the array
- Connect the cluster from the entrance to the top input of "Bundle By Name"
- Connect the output from the "Build Array" function with the left input of the "Bundle By Name" function
- This will replace the value in the input cluster, connected to the top. Only the value named in the function is replaced, and the new value is the one connected to the left input
- Make sure that the title in the unbundle/bundle functions matches the selected case (0, Default -> Elbow and 1 -> Forearm)
- Wire the output from the "Bundle By Name" function to the right shift register
- Copy all the elements into the next case (1), connect the relevant in- and outputs and remember to change the titles of the "Bundle/Unbundle By Name" to match.
- Connect the cluster input to the cluster output on the false case surrounding the Trigger Detection case
You have now stored multiple values in separate arrays for the elbow and forearm. Finally, you need to calculate the mean of the stored times in order to calculate the nerve conduction speed:
- Expand the right side of the While Loop
- Insert two "Unbundle By Name" functions into the While Loop, set one to Elbow and the other to Forearm
- Connect the cluster connected to the right shift register with the inputs of both "Unbundle By Name" functions.
- Insert two "Mean" VIs
- Mathematics -> Prob & Stat
- Connect them to the outputs of the two "Unbundle By Name" functions
- Insert two indicators to the output from the Mean functions and name them "Elbow Mean Time" and "Forearm Mean Time", respectively
- Insert a formula function to calculate the nerve conduction speed based on the two mean values
- Create three inputs named "E(lbow), F(orearm), and D(istance)" and an output named "V(elocity)" by right-clicking the left or right sides of the formula function and choosing "Create Input/Output"
- Connect the means of Elbow and Forearm with their respective inputs
- Connect the Distance input to a numeric control and name it "Length between Excitation Spots [cm]"
- Connect the V output to a numeric indicator and name it "Nerve conduction speed [m/s]"
- Insert the formula for velocity. Remember: It has to return m/s, and your input values are in cm and ms. Also remember to end the formula using a semicolon
Congratulations! You have finished the simulator, and you are almost ready to go to the biomedical laboratory and perform LIVE measurements:) However, when you are measuring live signals, you need to setup the test before performing measurements. Should any peaks be detected during the setup, you do not want these stored, as they will skew your velocity measurements. Thus, you need to add yet another Case structure to your VI containing a "Save Data" button - only when this button is active, will values be stored in the Elbow/Forearm arrays.
- Draw a case structure surrounding the case containing the clusters and "Build Array" function
- Wire a button to the Selector terminal and name it "Save Data"
- Save your VI as 5_NerveConductionSimulator.vi