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: biquadFilter mbed
calibrate.cpp@0:44d3f99b08c1, 2016-11-02 (annotated)
- Committer:
- ofosakar
- Date:
- Wed Nov 02 11:08:53 2016 +0000
- Revision:
- 0:44d3f99b08c1
- Child:
- 1:984b6b6812c7
EMG processing for two EMG signals.;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ofosakar | 0:44d3f99b08c1 | 1 | #include "mbed.h" |
ofosakar | 0:44d3f99b08c1 | 2 | #include "BiQuad.h" |
ofosakar | 0:44d3f99b08c1 | 3 | |
ofosakar | 0:44d3f99b08c1 | 4 | InterruptIn button(SW2); |
ofosakar | 0:44d3f99b08c1 | 5 | AnalogIn calibrateEmg1(A0); |
ofosakar | 0:44d3f99b08c1 | 6 | AnalogIn calibrateEmg2(A1); |
ofosakar | 0:44d3f99b08c1 | 7 | Serial pc(USBTX, USBRX); |
ofosakar | 0:44d3f99b08c1 | 8 | |
ofosakar | 0:44d3f99b08c1 | 9 | DigitalOut led_red(LED_RED); |
ofosakar | 0:44d3f99b08c1 | 10 | DigitalOut led_green(LED_GREEN); |
ofosakar | 0:44d3f99b08c1 | 11 | |
ofosakar | 0:44d3f99b08c1 | 12 | |
ofosakar | 0:44d3f99b08c1 | 13 | BiQuadChain calibrateBqc1; |
ofosakar | 0:44d3f99b08c1 | 14 | BiQuadChain calibrateBqc2; |
ofosakar | 0:44d3f99b08c1 | 15 | BiQuad calibrateBq11( 9.93756e-01, -1.89024e+00, 9.93756e-01, -1.89024e+00, 9.87512e-01 ); |
ofosakar | 0:44d3f99b08c1 | 16 | BiQuad calibrateBq12( 9.93756e-01, -1.89024e+00, 9.93756e-01, -1.89024e+00, 9.87512e-01 ); |
ofosakar | 0:44d3f99b08c1 | 17 | |
ofosakar | 0:44d3f99b08c1 | 18 | const int calibrateNumEmgCache = 100; |
ofosakar | 0:44d3f99b08c1 | 19 | float calibrateEmgCache1[calibrateNumEmgCache]; //sorted from new to old; |
ofosakar | 0:44d3f99b08c1 | 20 | float calibrateEmgCache2[calibrateNumEmgCache]; //sorted from new to old; |
ofosakar | 0:44d3f99b08c1 | 21 | |
ofosakar | 0:44d3f99b08c1 | 22 | |
ofosakar | 0:44d3f99b08c1 | 23 | |
ofosakar | 0:44d3f99b08c1 | 24 | Ticker sampler; |
ofosakar | 0:44d3f99b08c1 | 25 | |
ofosakar | 0:44d3f99b08c1 | 26 | float sample_frequency = 500.0f; //Hz |
ofosakar | 0:44d3f99b08c1 | 27 | float Ts = 1.0f / sample_frequency; |
ofosakar | 0:44d3f99b08c1 | 28 | |
ofosakar | 0:44d3f99b08c1 | 29 | volatile float total1; |
ofosakar | 0:44d3f99b08c1 | 30 | volatile float total2; |
ofosakar | 0:44d3f99b08c1 | 31 | |
ofosakar | 0:44d3f99b08c1 | 32 | |
ofosakar | 0:44d3f99b08c1 | 33 | volatile float average1; |
ofosakar | 0:44d3f99b08c1 | 34 | volatile float average2; |
ofosakar | 0:44d3f99b08c1 | 35 | |
ofosakar | 0:44d3f99b08c1 | 36 | volatile bool isCalibrating; |
ofosakar | 0:44d3f99b08c1 | 37 | |
ofosakar | 0:44d3f99b08c1 | 38 | float rectifierC(float value) { |
ofosakar | 0:44d3f99b08c1 | 39 | return fabs(value - 0.5f)*2.0f; |
ofosakar | 0:44d3f99b08c1 | 40 | } |
ofosakar | 0:44d3f99b08c1 | 41 | float movingAverageC(float newValue, float array[], int size) { |
ofosakar | 0:44d3f99b08c1 | 42 | float sumC = 0; |
ofosakar | 0:44d3f99b08c1 | 43 | for (int i = size - 2; i >= 0; i--) { |
ofosakar | 0:44d3f99b08c1 | 44 | array[i+1] = array[i]; |
ofosakar | 0:44d3f99b08c1 | 45 | sumC += array[i]; |
ofosakar | 0:44d3f99b08c1 | 46 | } |
ofosakar | 0:44d3f99b08c1 | 47 | array[0] = newValue; |
ofosakar | 0:44d3f99b08c1 | 48 | sumC += newValue; |
ofosakar | 0:44d3f99b08c1 | 49 | return sumC / size; |
ofosakar | 0:44d3f99b08c1 | 50 | } |
ofosakar | 0:44d3f99b08c1 | 51 | |
ofosakar | 0:44d3f99b08c1 | 52 | float sumC(float array[], int size) { |
ofosakar | 0:44d3f99b08c1 | 53 | float sumC = 0; |
ofosakar | 0:44d3f99b08c1 | 54 | for (int i = 0; i < size; i++) { |
ofosakar | 0:44d3f99b08c1 | 55 | sumC += array[i]; |
ofosakar | 0:44d3f99b08c1 | 56 | } |
ofosakar | 0:44d3f99b08c1 | 57 | return sumC; |
ofosakar | 0:44d3f99b08c1 | 58 | } |
ofosakar | 0:44d3f99b08c1 | 59 | |
ofosakar | 0:44d3f99b08c1 | 60 | float meanC(float array[], int size) { |
ofosakar | 0:44d3f99b08c1 | 61 | return sumC(array, size) / size; |
ofosakar | 0:44d3f99b08c1 | 62 | } |
ofosakar | 0:44d3f99b08c1 | 63 | |
ofosakar | 0:44d3f99b08c1 | 64 | void sample() { |
ofosakar | 0:44d3f99b08c1 | 65 | |
ofosakar | 0:44d3f99b08c1 | 66 | //TODO apply filters and such. |
ofosakar | 0:44d3f99b08c1 | 67 | //Make use of EMG Processing library. |
ofosakar | 0:44d3f99b08c1 | 68 | //For now we will just sumC the raw emg signals |
ofosakar | 0:44d3f99b08c1 | 69 | |
ofosakar | 0:44d3f99b08c1 | 70 | float emgOne = calibrateEmg1.read(); |
ofosakar | 0:44d3f99b08c1 | 71 | float notch1 = calibrateBqc1.step( emgOne ); |
ofosakar | 0:44d3f99b08c1 | 72 | |
ofosakar | 0:44d3f99b08c1 | 73 | float emgTwo = calibrateEmg2.read(); |
ofosakar | 0:44d3f99b08c1 | 74 | float notch2 = calibrateBqc2.step( emgTwo ); |
ofosakar | 0:44d3f99b08c1 | 75 | |
ofosakar | 0:44d3f99b08c1 | 76 | float rect1 = rectifierC(notch1); |
ofosakar | 0:44d3f99b08c1 | 77 | float rect2 = rectifierC(notch2); |
ofosakar | 0:44d3f99b08c1 | 78 | |
ofosakar | 0:44d3f99b08c1 | 79 | |
ofosakar | 0:44d3f99b08c1 | 80 | float filtered1 = movingAverageC( rect1, calibrateEmgCache1, calibrateNumEmgCache); |
ofosakar | 0:44d3f99b08c1 | 81 | float filtered2 = movingAverageC( rect2, calibrateEmgCache2, calibrateNumEmgCache); |
ofosakar | 0:44d3f99b08c1 | 82 | |
ofosakar | 0:44d3f99b08c1 | 83 | |
ofosakar | 0:44d3f99b08c1 | 84 | } |
ofosakar | 0:44d3f99b08c1 | 85 | |
ofosakar | 0:44d3f99b08c1 | 86 | void onPress() { |
ofosakar | 0:44d3f99b08c1 | 87 | sampler.attach(&sample, Ts); |
ofosakar | 0:44d3f99b08c1 | 88 | led_red = true; |
ofosakar | 0:44d3f99b08c1 | 89 | led_green = false; |
ofosakar | 0:44d3f99b08c1 | 90 | |
ofosakar | 0:44d3f99b08c1 | 91 | } |
ofosakar | 0:44d3f99b08c1 | 92 | |
ofosakar | 0:44d3f99b08c1 | 93 | void onRelease() { |
ofosakar | 0:44d3f99b08c1 | 94 | led_red = false; |
ofosakar | 0:44d3f99b08c1 | 95 | led_green = true; |
ofosakar | 0:44d3f99b08c1 | 96 | sampler.detach(); |
ofosakar | 0:44d3f99b08c1 | 97 | average1 = meanC(calibrateEmgCache1, calibrateNumEmgCache); |
ofosakar | 0:44d3f99b08c1 | 98 | average2 = meanC(calibrateEmgCache2, calibrateNumEmgCache); |
ofosakar | 0:44d3f99b08c1 | 99 | pc.printf ("(avg1, avg2) = (%f, %f)\r\n", average1, average2); //Why NaN? am I deviding by zero? |
ofosakar | 0:44d3f99b08c1 | 100 | } |
ofosakar | 0:44d3f99b08c1 | 101 | |
ofosakar | 0:44d3f99b08c1 | 102 | //int main() |
ofosakar | 0:44d3f99b08c1 | 103 | //{ |
ofosakar | 0:44d3f99b08c1 | 104 | // pc.baud(115200); |
ofosakar | 0:44d3f99b08c1 | 105 | // led_red = false; |
ofosakar | 0:44d3f99b08c1 | 106 | // led_green = true; |
ofosakar | 0:44d3f99b08c1 | 107 | // |
ofosakar | 0:44d3f99b08c1 | 108 | // calibrateBqc1.add( &calibrateBq11 ); |
ofosakar | 0:44d3f99b08c1 | 109 | // calibrateBqc2.add( &calibrateBq12 ); |
ofosakar | 0:44d3f99b08c1 | 110 | // |
ofosakar | 0:44d3f99b08c1 | 111 | // button.rise(&onRelease); |
ofosakar | 0:44d3f99b08c1 | 112 | // button.fall(&onPress); |
ofosakar | 0:44d3f99b08c1 | 113 | // |
ofosakar | 0:44d3f99b08c1 | 114 | // while(true); |
ofosakar | 0:44d3f99b08c1 | 115 | //} |