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@1:984b6b6812c7, 2016-11-02 (annotated)
- Committer:
- ofosakar
- Date:
- Wed Nov 02 13:19:42 2016 +0000
- Revision:
- 1:984b6b6812c7
- Parent:
- 0:44d3f99b08c1
- Child:
- 2:8b790c03a760
Calibrating the EMG signals done.
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 | 1:984b6b6812c7 | 4 | DigitalIn calibrating(SW2); |
ofosakar | 1:984b6b6812c7 | 5 | InterruptIn calibrateButton(SW3); |
ofosakar | 0:44d3f99b08c1 | 6 | AnalogIn calibrateEmg1(A0); |
ofosakar | 0:44d3f99b08c1 | 7 | AnalogIn calibrateEmg2(A1); |
ofosakar | 0:44d3f99b08c1 | 8 | Serial pc(USBTX, USBRX); |
ofosakar | 0:44d3f99b08c1 | 9 | |
ofosakar | 0:44d3f99b08c1 | 10 | DigitalOut led_red(LED_RED); |
ofosakar | 0:44d3f99b08c1 | 11 | DigitalOut led_green(LED_GREEN); |
ofosakar | 1:984b6b6812c7 | 12 | DigitalOut led_blue(LED_BLUE); |
ofosakar | 1:984b6b6812c7 | 13 | |
ofosakar | 0:44d3f99b08c1 | 14 | |
ofosakar | 0:44d3f99b08c1 | 15 | |
ofosakar | 0:44d3f99b08c1 | 16 | BiQuadChain calibrateBqc1; |
ofosakar | 0:44d3f99b08c1 | 17 | BiQuadChain calibrateBqc2; |
ofosakar | 0:44d3f99b08c1 | 18 | BiQuad calibrateBq11( 9.93756e-01, -1.89024e+00, 9.93756e-01, -1.89024e+00, 9.87512e-01 ); |
ofosakar | 0:44d3f99b08c1 | 19 | BiQuad calibrateBq12( 9.93756e-01, -1.89024e+00, 9.93756e-01, -1.89024e+00, 9.87512e-01 ); |
ofosakar | 0:44d3f99b08c1 | 20 | |
ofosakar | 0:44d3f99b08c1 | 21 | const int calibrateNumEmgCache = 100; |
ofosakar | 0:44d3f99b08c1 | 22 | float calibrateEmgCache1[calibrateNumEmgCache]; //sorted from new to old; |
ofosakar | 0:44d3f99b08c1 | 23 | float calibrateEmgCache2[calibrateNumEmgCache]; //sorted from new to old; |
ofosakar | 0:44d3f99b08c1 | 24 | |
ofosakar | 1:984b6b6812c7 | 25 | volatile float threshold1 = 0.2; |
ofosakar | 1:984b6b6812c7 | 26 | volatile float threshold2 = 0.2; |
ofosakar | 0:44d3f99b08c1 | 27 | |
ofosakar | 0:44d3f99b08c1 | 28 | Ticker sampler; |
ofosakar | 0:44d3f99b08c1 | 29 | |
ofosakar | 0:44d3f99b08c1 | 30 | float sample_frequency = 500.0f; //Hz |
ofosakar | 0:44d3f99b08c1 | 31 | float Ts = 1.0f / sample_frequency; |
ofosakar | 0:44d3f99b08c1 | 32 | |
ofosakar | 0:44d3f99b08c1 | 33 | volatile float total1; |
ofosakar | 0:44d3f99b08c1 | 34 | volatile float total2; |
ofosakar | 0:44d3f99b08c1 | 35 | |
ofosakar | 0:44d3f99b08c1 | 36 | |
ofosakar | 0:44d3f99b08c1 | 37 | volatile float average1; |
ofosakar | 0:44d3f99b08c1 | 38 | volatile float average2; |
ofosakar | 0:44d3f99b08c1 | 39 | |
ofosakar | 0:44d3f99b08c1 | 40 | volatile bool isCalibrating; |
ofosakar | 0:44d3f99b08c1 | 41 | |
ofosakar | 0:44d3f99b08c1 | 42 | float rectifierC(float value) { |
ofosakar | 0:44d3f99b08c1 | 43 | return fabs(value - 0.5f)*2.0f; |
ofosakar | 0:44d3f99b08c1 | 44 | } |
ofosakar | 0:44d3f99b08c1 | 45 | float movingAverageC(float newValue, float array[], int size) { |
ofosakar | 0:44d3f99b08c1 | 46 | float sumC = 0; |
ofosakar | 0:44d3f99b08c1 | 47 | for (int i = size - 2; i >= 0; i--) { |
ofosakar | 0:44d3f99b08c1 | 48 | array[i+1] = array[i]; |
ofosakar | 0:44d3f99b08c1 | 49 | sumC += array[i]; |
ofosakar | 0:44d3f99b08c1 | 50 | } |
ofosakar | 0:44d3f99b08c1 | 51 | array[0] = newValue; |
ofosakar | 0:44d3f99b08c1 | 52 | sumC += newValue; |
ofosakar | 0:44d3f99b08c1 | 53 | return sumC / size; |
ofosakar | 0:44d3f99b08c1 | 54 | } |
ofosakar | 0:44d3f99b08c1 | 55 | |
ofosakar | 0:44d3f99b08c1 | 56 | float sumC(float array[], int size) { |
ofosakar | 0:44d3f99b08c1 | 57 | float sumC = 0; |
ofosakar | 0:44d3f99b08c1 | 58 | for (int i = 0; i < size; i++) { |
ofosakar | 0:44d3f99b08c1 | 59 | sumC += array[i]; |
ofosakar | 0:44d3f99b08c1 | 60 | } |
ofosakar | 0:44d3f99b08c1 | 61 | return sumC; |
ofosakar | 0:44d3f99b08c1 | 62 | } |
ofosakar | 0:44d3f99b08c1 | 63 | |
ofosakar | 0:44d3f99b08c1 | 64 | float meanC(float array[], int size) { |
ofosakar | 0:44d3f99b08c1 | 65 | return sumC(array, size) / size; |
ofosakar | 0:44d3f99b08c1 | 66 | } |
ofosakar | 0:44d3f99b08c1 | 67 | |
ofosakar | 0:44d3f99b08c1 | 68 | void sample() { |
ofosakar | 0:44d3f99b08c1 | 69 | |
ofosakar | 0:44d3f99b08c1 | 70 | //TODO apply filters and such. |
ofosakar | 0:44d3f99b08c1 | 71 | //Make use of EMG Processing library. |
ofosakar | 0:44d3f99b08c1 | 72 | //For now we will just sumC the raw emg signals |
ofosakar | 0:44d3f99b08c1 | 73 | |
ofosakar | 0:44d3f99b08c1 | 74 | float emgOne = calibrateEmg1.read(); |
ofosakar | 0:44d3f99b08c1 | 75 | float notch1 = calibrateBqc1.step( emgOne ); |
ofosakar | 0:44d3f99b08c1 | 76 | |
ofosakar | 0:44d3f99b08c1 | 77 | float emgTwo = calibrateEmg2.read(); |
ofosakar | 0:44d3f99b08c1 | 78 | float notch2 = calibrateBqc2.step( emgTwo ); |
ofosakar | 0:44d3f99b08c1 | 79 | |
ofosakar | 0:44d3f99b08c1 | 80 | float rect1 = rectifierC(notch1); |
ofosakar | 0:44d3f99b08c1 | 81 | float rect2 = rectifierC(notch2); |
ofosakar | 0:44d3f99b08c1 | 82 | |
ofosakar | 0:44d3f99b08c1 | 83 | |
ofosakar | 0:44d3f99b08c1 | 84 | float filtered1 = movingAverageC( rect1, calibrateEmgCache1, calibrateNumEmgCache); |
ofosakar | 0:44d3f99b08c1 | 85 | float filtered2 = movingAverageC( rect2, calibrateEmgCache2, calibrateNumEmgCache); |
ofosakar | 0:44d3f99b08c1 | 86 | |
ofosakar | 0:44d3f99b08c1 | 87 | |
ofosakar | 0:44d3f99b08c1 | 88 | } |
ofosakar | 0:44d3f99b08c1 | 89 | |
ofosakar | 0:44d3f99b08c1 | 90 | void onPress() { |
ofosakar | 0:44d3f99b08c1 | 91 | sampler.attach(&sample, Ts); |
ofosakar | 0:44d3f99b08c1 | 92 | led_red = true; |
ofosakar | 0:44d3f99b08c1 | 93 | led_green = false; |
ofosakar | 0:44d3f99b08c1 | 94 | |
ofosakar | 0:44d3f99b08c1 | 95 | } |
ofosakar | 0:44d3f99b08c1 | 96 | |
ofosakar | 0:44d3f99b08c1 | 97 | void onRelease() { |
ofosakar | 0:44d3f99b08c1 | 98 | led_red = false; |
ofosakar | 0:44d3f99b08c1 | 99 | led_green = true; |
ofosakar | 0:44d3f99b08c1 | 100 | sampler.detach(); |
ofosakar | 0:44d3f99b08c1 | 101 | average1 = meanC(calibrateEmgCache1, calibrateNumEmgCache); |
ofosakar | 0:44d3f99b08c1 | 102 | average2 = meanC(calibrateEmgCache2, calibrateNumEmgCache); |
ofosakar | 1:984b6b6812c7 | 103 | |
ofosakar | 0:44d3f99b08c1 | 104 | pc.printf ("(avg1, avg2) = (%f, %f)\r\n", average1, average2); //Why NaN? am I deviding by zero? |
ofosakar | 0:44d3f99b08c1 | 105 | } |
ofosakar | 0:44d3f99b08c1 | 106 | |
ofosakar | 1:984b6b6812c7 | 107 | void calibrate() { |
ofosakar | 1:984b6b6812c7 | 108 | while(calibrating) { |
ofosakar | 1:984b6b6812c7 | 109 | led_red = false; |
ofosakar | 1:984b6b6812c7 | 110 | wait(0.5); |
ofosakar | 1:984b6b6812c7 | 111 | led_red = true; |
ofosakar | 1:984b6b6812c7 | 112 | wait(0.5); |
ofosakar | 1:984b6b6812c7 | 113 | } |
ofosakar | 1:984b6b6812c7 | 114 | |
ofosakar | 1:984b6b6812c7 | 115 | // Button pressed for rest measurement |
ofosakar | 1:984b6b6812c7 | 116 | led_red = true; |
ofosakar | 1:984b6b6812c7 | 117 | sampler.attach(&sample, Ts); |
ofosakar | 1:984b6b6812c7 | 118 | led_blue = false; |
ofosakar | 1:984b6b6812c7 | 119 | wait(10); |
ofosakar | 1:984b6b6812c7 | 120 | // 10 seconds sampled |
ofosakar | 1:984b6b6812c7 | 121 | led_blue = true; |
ofosakar | 1:984b6b6812c7 | 122 | sampler.detach(); |
ofosakar | 1:984b6b6812c7 | 123 | float restAvg1 = meanC(calibrateEmgCache1, calibrateNumEmgCache); |
ofosakar | 1:984b6b6812c7 | 124 | float restAvg2 = meanC(calibrateEmgCache2, calibrateNumEmgCache); |
ofosakar | 1:984b6b6812c7 | 125 | |
ofosakar | 1:984b6b6812c7 | 126 | int i =0; |
ofosakar | 1:984b6b6812c7 | 127 | while(i<3) { |
ofosakar | 1:984b6b6812c7 | 128 | led_green = false; |
ofosakar | 1:984b6b6812c7 | 129 | wait(0.5); |
ofosakar | 1:984b6b6812c7 | 130 | led_green = true; |
ofosakar | 1:984b6b6812c7 | 131 | wait(0.5); |
ofosakar | 1:984b6b6812c7 | 132 | i++; |
ofosakar | 1:984b6b6812c7 | 133 | } |
ofosakar | 1:984b6b6812c7 | 134 | led_green = true; |
ofosakar | 1:984b6b6812c7 | 135 | |
ofosakar | 1:984b6b6812c7 | 136 | while(calibrating) { |
ofosakar | 1:984b6b6812c7 | 137 | led_red = false; |
ofosakar | 1:984b6b6812c7 | 138 | wait(0.5); |
ofosakar | 1:984b6b6812c7 | 139 | led_red = true; |
ofosakar | 1:984b6b6812c7 | 140 | wait(0.5); |
ofosakar | 1:984b6b6812c7 | 141 | } |
ofosakar | 1:984b6b6812c7 | 142 | // Button pressed for contracted measurement |
ofosakar | 1:984b6b6812c7 | 143 | led_red = true; |
ofosakar | 1:984b6b6812c7 | 144 | sampler.attach(&sample, Ts); |
ofosakar | 1:984b6b6812c7 | 145 | led_blue = false; |
ofosakar | 1:984b6b6812c7 | 146 | wait(10); |
ofosakar | 1:984b6b6812c7 | 147 | |
ofosakar | 1:984b6b6812c7 | 148 | // 10 seconds sampled |
ofosakar | 1:984b6b6812c7 | 149 | led_blue = true; |
ofosakar | 1:984b6b6812c7 | 150 | sampler.detach(); |
ofosakar | 1:984b6b6812c7 | 151 | |
ofosakar | 1:984b6b6812c7 | 152 | i =0; |
ofosakar | 1:984b6b6812c7 | 153 | while(i<3) { |
ofosakar | 1:984b6b6812c7 | 154 | led_green = false; |
ofosakar | 1:984b6b6812c7 | 155 | wait(0.5); |
ofosakar | 1:984b6b6812c7 | 156 | led_green = true; |
ofosakar | 1:984b6b6812c7 | 157 | wait(0.5); |
ofosakar | 1:984b6b6812c7 | 158 | i++; |
ofosakar | 1:984b6b6812c7 | 159 | } |
ofosakar | 1:984b6b6812c7 | 160 | |
ofosakar | 1:984b6b6812c7 | 161 | float contAvg1 = meanC(calibrateEmgCache1, calibrateNumEmgCache); |
ofosakar | 1:984b6b6812c7 | 162 | float contAvg2 = meanC(calibrateEmgCache2, calibrateNumEmgCache); |
ofosakar | 1:984b6b6812c7 | 163 | |
ofosakar | 1:984b6b6812c7 | 164 | threshold1 = (contAvg1 + restAvg1)/2; |
ofosakar | 1:984b6b6812c7 | 165 | threshold2 = (contAvg2 + restAvg2)/2; |
ofosakar | 1:984b6b6812c7 | 166 | pc.printf("threshold1: %f\tthreshold2:%f\n\r", threshold1, threshold2); |
ofosakar | 1:984b6b6812c7 | 167 | |
ofosakar | 1:984b6b6812c7 | 168 | } |
ofosakar | 1:984b6b6812c7 | 169 | |
ofosakar | 1:984b6b6812c7 | 170 | int main() |
ofosakar | 1:984b6b6812c7 | 171 | { |
ofosakar | 1:984b6b6812c7 | 172 | pc.baud(115200); |
ofosakar | 1:984b6b6812c7 | 173 | led_red = true; |
ofosakar | 1:984b6b6812c7 | 174 | led_green = true; |
ofosakar | 1:984b6b6812c7 | 175 | led_blue = true; |
ofosakar | 1:984b6b6812c7 | 176 | calibrateButton.fall(&calibrate); |
ofosakar | 1:984b6b6812c7 | 177 | |
ofosakar | 1:984b6b6812c7 | 178 | calibrate(); |
ofosakar | 1:984b6b6812c7 | 179 | pc.printf("threshold1: %f\tthreshold2:%f\n\r", threshold1, threshold2); |
ofosakar | 1:984b6b6812c7 | 180 | |
ofosakar | 0:44d3f99b08c1 | 181 | // |
ofosakar | 0:44d3f99b08c1 | 182 | // calibrateBqc1.add( &calibrateBq11 ); |
ofosakar | 0:44d3f99b08c1 | 183 | // calibrateBqc2.add( &calibrateBq12 ); |
ofosakar | 0:44d3f99b08c1 | 184 | // |
ofosakar | 0:44d3f99b08c1 | 185 | // button.rise(&onRelease); |
ofosakar | 0:44d3f99b08c1 | 186 | // |
ofosakar | 1:984b6b6812c7 | 187 | while(true); |
ofosakar | 1:984b6b6812c7 | 188 | } |