EMG Actuation

The goal of this lab is to attenuate the noise in an electromyography signal and process it to move a prosthesis. To detect the EMG signal, two electrodes are placed on the moving muscle of choice. These electrodes provide a differential signal (V+ and V-). A third electrode is placed on a non-moving body part, to act as a ground-reference for the signal. An instrumentation amplifier is then used to amplify the differential signal, without amplifying power supply noise. Additional filters are used to mitigate electrical noise and DC offset. Finally, a microcontroller and H-bridge are used to control DC motor rotation, to facilitate prosthesis motion, in relation to muscle flexion.

Demo Video #1:  https://youtu.be/L0TjrB6G3Hw

Demo Video #2:  https://youtu.be/uunSo7D3Cy4







Instrumentation Amplifier Design

An FFT of the initial EMG setup shows the presence of a DC offset and power-supply noise occurs at integer-multiples of 60Hz (120Hz, 240Hz, 480Hz, etc.), reference Figure 1. Since EMG signals occupy 50-500Hz, using a notch/bandpass filter in this application would either attenuate useful frequencies of the signal, or would allow the presence of power supply noise. Since the signals from both EMG electrodes share the same power-supply noise, we can use a differential amplifier to amplify the difference between the two signals, without increasing power supply noise. As the difference in signal is amplified, the 60Hz gets proportionally smaller. This helps to reduce the relative strength of the power supply noise, in comparison to the EMG signal. This effectively allows for a high common mode rejection ratio (CMRR) between the two EMG electrodes.

Since the two EMG inputs may be connected to things with different resistances, an instrumentation amplifier, which is a type of differential amplifier, is used so that such differences will not interfere with measurement accuracy. LM741 ICs are used to construct a three-opamp instrumentation amplifier, as shown in Figure 2.  Testing showed that this circuit provides sufficient gain to make power supply negligible.


Figure 1 - FFT of signal from Biopac before amplifier is implemented. The code for performing this analysis is provided in the Appendix section.







Decoupling Capacitor Design

The three LM741 amplifiers used are integrated circuit components. Fundamentally, ICs add their own electrical noise to the output signal. In this application, the 9V power supply comes with tiny voltage ripples which add noise to the output signal. This high-frequency noise in power supply signals is mitigated by adding 0.1uF decoupling capacitors between the IC’s power supply and ground, reference Figure 2. The electrical noise generated by the IC is shunted through the capacitor, allowing for a cleaner signal output.



Figure 2 - Decoupling capacitor circuit diagram.








Design for Mitigating DC Offset

Referencing the FFT in Figure 1, the large impulse around frequency 0Hz implies the presence of a DC offset. This component of the signal is removed with a high-pass filter. Typically, a 0.1Hz passive high-pass filter is sufficient however, testing showed that a flexing the muscle generated a wandering DC offset. This made signal processing difficult for the microcontroller, reference Figure 3. A 0.1Hz high-pass filter therefore ineffectively mitigated the DC offset of EMG signals.



Figure 3 - Signal after amplifier is implemented, bad filters (left image).  DC offset drift caused the signal to inconsistently wander when integrating with the Arduino (right).

To mitigate the wandering DC offset, the 0.1Hz high-pass filter was replaced with a 40Hz high-pass filter, reference Figure 4. Since EMG frequency range is 50-500Hz, a 40Hz high-pass filter does not attenuate useful EMG frequencies.

The filtered signal is then input into BIOPAC equipment, which outputs an EMG signal with a DC offset. This secondary DC offset did not wander and is mitigated with a 0.1Hz high-pass filter, reference Figure 3. By mitigating these two sources of DC offset, we can optimize signal processing before it is passed into the Arduino microcontroller.


Figure 4 - Passive 40Hz (left) & 0.1Hz (middle) RC high-pass filter circuit.  This led to superior signal output (right).






Figure 5 – Using a 40Hz high-pass filter (left) vs a 0.1Hz high-pass filter (right) before sending to BIOPAC.




Figure 6 – Adding a 0.1Hz high-pass filter to BIOPAC output mitigates DC offset.
















Signal Processing for Optimal Arduino Performance

All of the above circuitry is summarized in a flowchart, reference Figure 7. The final element added to the circuit, before sending the EMG signal into the Arduino microcontroller, was an envelope detector, reference Figure 5. This makes it easy for the microcontroller to control the motor based on a threshold, rather than requiring additional local signal processing software (peak detection, signal smoothing, etc.).

The final circuit for processing and enveloping EMG signals is summarized in Figures 7 & 8.



Figure 7 - Circuit flowchart.



Figure 8 - Envelope detector circuit where R=8.2kOhm and C = 10uF.

Figure 9 – Signal before (left) and after (right) the envelope detector is added. Notice that the envelope detector adds a negative-voltage DC offset.

Using a Motor to Control Prosthesis

The enveloped signal is passed into the Arduino. The microcontroller then analyzes the signal and, based off of a certain threshold value, determines if the muscle is contracted or relaxed, and controls the DC motor accordingly. If the muscle is relaxed, then the DC motor spins one direction. If the muscle is contracted, the DC motor spins the opposite direction. An H-bridge (L293D) is necessary for controlling the DC motor’s direction, by reversing the direction of current flow. The circuit require for integration of this component into the system is provided in Figure 10. Pulse width modulation (PWM) was used to control motor speed. A minimum of 15% duty cycle was required to make the motor move, while a 20% duty cycle was required to move the prosthesis mechanism.

The threshold value for controlling motor direction was determined by observing the signal while the muscle was both relaxed & contracted. While under this threshold, the Arduino would move the motor in one direction. When the input signal exceeded this threshold (40mV), the Arduino interpreted this as a muscle contraction and would reverse the direction of the motor, reference Figure 11. Code for controlling the microcontroller and motor is provided in the appendix section. To simulate control over a prosthesis, a simple rack and pinion mechanism were used.



Figure 10 – Circuit diagram for integrating the H-bridge and motor with the Arduino microcontroller.





Figure 11 – Example of Arduino-input interpreting the difference between muscle moving from relaxed to contracted position.













Conclusion

The envelope detector caused a negative DC offset, which centered the signal below 0V. Since the Arduino can only read inputs within the range of 0 to 5V, some of the signal was lost. When the muscle was flexed, the signal continuously peaked and troughed, preventing it from staying above the Arduino’s threshold. These issues can be mitigated by adding a zero-offset stage amplifier circuit, as shown in Figure 12. The threshold value for indicating muscle contraction was 40mV. The maximum for Arduino is Vin=5V, so adding gain to the signal can make signal processing easier for the microcontroller.


Figure 12 – Zero-adjustment stage where a potentiometer is used to bring +/-Vin to Vout=0.

Control over prosthesis was demonstrated while physically holding the DC motor. This oftentimes led to incorrect gear meshing upon contact. Superior demonstration could be possible by adding a fixture to hold the motor in the correct orientation, in mesh with rack gears. Additionally, friction and lateral-misalignment caused occasional issues when moving the rack. Improving gear fixation and adding lubricant could also improve demonstration of prosthesis-control.














Appendix – Variation in Signal Quality


Figure 13 - Variable noise in the environment, testing different filter parameters, 60Hz noise persists.  Some of this noise is due to batteries not being fully charged. Graph on right is result when batteries are fully charged. Signal quality also seemed to depend on which BIOPAC was used.















Appendix - MATLAB Code

%%%%%%%%%%%%%%%% Gather Data %%%%%%%%%%%%%%%%%%%%%%%%%

s = daq.createSession('ni');

addAnalogInputChannel(s,'myDaq1', 0, 'Voltage');

s.Rate = 2000;

s.DurationInSeconds = 10;

[data,time]=s.startForeground;

figure();

subplot(2,1,1)

plot(time,data);

title('Original Signal');

xlabel('Time');

ylabel('Voltage');



%%%%%%%%%%%%%%%%%%%% FFT %%%%%%%%%%%%%%%%%%%%%

Fs = 2000; % Sample Rate

fs = 2000; % Sample Rate

T = 1/Fs; % Sampling period

L = length(data); % Length of signal

t = (0:L-1)*T; % Time vector

Y = fft(data); % Compute the Fourier transform of the signal.

%  Compute the two-sided spectrum P2. Then compute the single-sided

%  spectrum P1 based on P2 and the even-valued signal length L.




%  Define the frequency domain f and plot the single-sided amplitude

%  spectrum P1. The amplitudes are not exactly at 0.7 and 1, as expected,

%  because of the added noise. On average, longer signals produce better

%  frequency approximations.

f = Fs*(0:(L/2))/L;

subplot(2,1,2);

plot(f,P1)

title('Stationary:  Single-Sided Amplitude Spectrum of X(t)');

xlabel('f (Hz)');

ylabel('|P1(f)|');











Appendix - Arduino Code

const int controlPin1 = 3; // connected to pin 7 on the H-bridge const int controlPin2 = 4; // connected to pin 2 on the H-bridge const int enablePin = 9; // connected to pin 1 on the H-bridge

float threshold = 8 // threshold value

float voltage;

int counter=0;

void setup() { // initialize the inputs and outputs

pinMode(A0, INPUT);

pinMode(controlPin1, OUTPUT);

pinMode(controlPin2, OUTPUT);

pinMode(enablePin, OUTPUT);

digitalWrite(enablePin, HIGH);

Serial.begin(9600);

}

void loop() {    // read the value of the incoming voltage

voltage = analogRead(A0);

Serial.println(voltage);

if (voltage > threshold) { //if voltage is above the threshold (flexing,) turn motor one way for 3 seconds digitalWrite(controlPin1, LOW);

digitalWrite(controlPin2, HIGH);

delay(20); // 20% duty cycle to control motor speed

digitalWrite(controlPin1, LOW);

digitalWrite(controlPin2, LOW);

delay(100); // 20% duty cycle to control motor speed

}

else{

digitalWrite(controlPin1, HIGH);

digitalWrite(controlPin2, LOW);

delay(20); // 20% duty cycle to control motor speed

digitalWrite(controlPin1, LOW);

digitalWrite(controlPin2, LOW);

delay(100); // 20% duty cycle to control motor speed

}

}













0 comments:

Post a Comment

My Instagram