Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: HIDScope QEI biquadFilter mbed
Fork of EMG_Controller by
Diff: emg.h
- Revision:
- 9:1cb2d5ab51e6
- Parent:
- 6:6cb7c0247560
- Child:
- 10:25d7600d1e38
--- a/emg.h Wed Oct 26 07:59:31 2016 +0000 +++ b/emg.h Thu Oct 27 11:46:55 2016 +0000 @@ -8,29 +8,35 @@ states state = STATE_DEFAULT; //Creating two scope channels -//HIDScope scope(2); +//HIDScope scope(4); //Notch filter BiQuadChain notch_50; -BiQuad bq1( 1.00000000000, -1.60956348896, 1.00000000000, -1.40195621505, 0.74203282402); -BiQuad bq2( 1.00000000000, -1.60724786352, 1.00000000000, -1.33646101015, 0.85967899264); -BiQuad bq3( 1.00000000000, -1.61186693071, 1.00000000000, -1.64415455961, 0.89726621230); +BiQuad bq3( 0.98116526140, 0.00000000044, 0.98116526140, 0.00000000043, 0.95391787621); +BiQuad bq4( 0.97224232015, 0.00000000043, 0.97224232015, -0.04036799459, 0.97670000725); +BiQuad bq5( 1.00000000000, 0.00000000044, 1.00000000000, 0.04036799547, 0.9767000072); //High pass filter BiQuadChain high_pass; -BiQuad bq4( 1.00000000000, -1.99999967822, 1.00000000000, -1.98388291862, 0.98395921205); -BiQuad bq5( 1.00000000000, -1.99999812453, 1.00000000000, -1.99324612474, 0.99332432675); +BiQuad bq6( 0.80254782780,-1.60509565560, 0.80254782780, -1.58011656361, 0.63006219630); +BiQuad bq7( 0.90006571973,-1.80013143945, 0.900065719734, -1.77213098592, 0.8281459694); +//BiQuad bq8( 0.92490714701,-1.84981429401, 0.92490714701, -1.90032503529, 0.9352152620); +//Low pass filter +BiQuadChain low_pass; +BiQuad bq9( 0.00801840797, 0.01603681594, 0.00801840797,-1.65212256130, 0.68416767240); +BiQuad bq10( 0.00836524486, 0.01673048973, 0.00836524486,-1.72511837232, 0.75857933411); +BiQuad bq11( 0.00905039996, 0.01810079992, 0.00905039996,-1.86807725180, 0.9043110909); //Ticker Ticker emgSampleTicker; //Timeout to change state after 5 seconds Timeout change_state; -//Timeout to change state after 10 seconds +//Timeout to change state after 15 seconds Timeout change_state2; -//led +//LED DigitalOut led(LED_RED); //Emg input @@ -38,27 +44,19 @@ AnalogIn emg1( A1 ); AnalogIn emg2( A2 ); +//Go flag for emg sample bool go_emgSample; -bool go_find_minmax; + +//Variables for intermediate filter values double emg_sample[3]; +double emg_low_passed_200[3]; double emg_notch[3]; double emg_high_passed[3]; -double emg_rectified; +double emg_low_passed[3]; double min_emg[3]; double max_emg[3]; -const int n = 200; -int counter = 0; -double RMSArray0[n] = {0}; -double RMSArray1[n] = {0}; -double RMSArray2[n] = {0}; -double RMS0; -double RMS1; -double RMS2; -double SumRMS0; -double SumRMS1; -double SumRMS2; - +//Calculating normalized outputs double Norm_EMG_0; double Norm_EMG_1; double Norm_EMG_2; @@ -71,8 +69,8 @@ } void calibrate() { - state = STATE_CALIBRATION; - led.write(0); + state = STATE_CALIBRATION; + led.write(0); } void run() { @@ -81,22 +79,6 @@ } void EMG_filter(); -/* -int main() { - //combine biquads in biquad chains for notch/high- low-pass filters - notch_50.add( &bq1 ).add( &bq2 ).add( &bq3 ); - high_pass.add( &bq4 ).add( &bq5 ); - - change_state.attach( &calibrate,5); - change_state2.attach( &run,10); - emgSampleTicker.attach( &emgSample, 0.002); - while( true ){ - if(go_emgSample == true){ - EMG_filter(); - } - } -} -*/ void EMG_filter() { if(go_emgSample == true){ @@ -105,84 +87,66 @@ emg_sample[1] = emg1.read(); emg_sample[2] = emg2.read(); - for (int i = 0; i < 3; i++){ - //filter out the 50Hz components with a notch filter - //emg_notch[i] = notch_50.step(emg_sample[i]); - - //high pass the signal (removing motion artifacts and offset) - emg_high_passed[i] = high_pass.step(emg_sample[i]); - } - - //Calculating RMS - SumRMS0 -= pow(RMSArray0[counter],2); - SumRMS1 -= pow(RMSArray1[counter],2); - SumRMS2 -= pow(RMSArray2[counter],2); + //filter out the 50Hz components with a notch filter + emg_notch[0] = notch_50.step(emg_sample[0]); - RMSArray0[counter] = emg_high_passed[0]; - RMSArray1[counter] = emg_high_passed[1]; - RMSArray2[counter] = emg_high_passed[2]; - - SumRMS0 += pow(RMSArray0[counter],2); - SumRMS1 += pow(RMSArray1[counter],2); - SumRMS2 += pow(RMSArray2[counter],2); + //high pass the signal (removing motion artifacts and offset) + emg_high_passed[0] = high_pass.step(emg_notch[0]); + + //low pass the rectified emg signal + emg_low_passed[0] = low_pass.step(fabs(emg_high_passed[0])); - counter++; - if (counter == n){ - counter = 0; - } - - RMS0 = sqrt(SumRMS0/n); - RMS1 = sqrt(SumRMS1/n); - RMS2 = sqrt(SumRMS2/n); //Calculating min value and max value of emg signal if(state == STATE_CALIBRATION) { if (start_calibration == 0) { - min_emg[0] = RMS0; - max_emg[0] = RMS0; - min_emg[1] = RMS1; - max_emg[1] = RMS1; - min_emg[2] = RMS2; - max_emg[2] = RMS2; + min_emg[0] = emg_low_passed[0]; + max_emg[0] = emg_low_passed[0]; + min_emg[1] = emg_low_passed[1]; + max_emg[1] = emg_low_passed[1]; + min_emg[2] = emg_low_passed[2]; + max_emg[2] = emg_low_passed[2]; start_calibration++; } else { //finding min and max of emg0 - if (RMS0 < min_emg[0]) { - min_emg[0] = RMS0; + if (emg_low_passed[0] < min_emg[0]) { + min_emg[0] = emg_low_passed[0]; } - else if (RMS0 > max_emg[0]) { - max_emg[0] = RMS0; + else if (emg_low_passed[0] > max_emg[0]) { + max_emg[0] = emg_low_passed[0]; } //finding min and max of emg1 - if (RMS1 < min_emg[1]) { - min_emg[1] = RMS1; + if (emg_low_passed[1] < min_emg[1]) { + min_emg[1] = emg_low_passed[1]; } - else if (RMS1 > max_emg[1]) { - max_emg[1] = RMS1; + else if (emg_low_passed[1] > max_emg[1]) { + max_emg[1] = emg_low_passed[1]; } //finding min and max of emg2 - if (RMS2 < min_emg[2]) { - min_emg[2] = RMS2; + if (emg_low_passed[2] < min_emg[2]) { + min_emg[2] = emg_low_passed[2]; } - else if (RMS2 > max_emg[2]) { - max_emg[2] = RMS2; + else if (emg_low_passed[2] > max_emg[2]) { + max_emg[2] = emg_low_passed[2]; } } } //calculating input_forces for controller - Norm_EMG_0 = (RMS0 - min_emg[0])/(max_emg[0]-min_emg[0]); - Norm_EMG_1 = (RMS1 - min_emg[1])/(max_emg[1]-min_emg[1]); - Norm_EMG_2 = (RMS2 - min_emg[2])/(max_emg[2]-min_emg[2]); + Norm_EMG_0 = (emg_low_passed[0] - min_emg[0])/(max_emg[0]-min_emg[0]); + Norm_EMG_1 = (emg_low_passed[1] - min_emg[1])/(max_emg[1]-min_emg[1]); + Norm_EMG_2 = (emg_low_passed[2] - min_emg[2])/(max_emg[2]-min_emg[2]); //Send scope data - // scope.set(0,emg_sample[0]); - //scope.set(1,Norm_EMG_0); - //scope.set(2,input_force1); + //scope.set(0,emg_sample[0]); + //scope.set(1,emg_notch[0]); + //scope.set(2,emg_high_passed[0]); + //scope.set(3,input_force0); + //scope.set(2,emg_low_passed[0]); //scope.set(3,input_force2); //scope.send();