Het is kut
Dependencies: HIDScope biquadFilter mbed
Fork of KUT_HIDSCOPE by
main.cpp@2:ef6c30f459a5, 2016-10-25 (annotated)
- Committer:
- Jankoekenpan
- Date:
- Tue Oct 25 15:00:21 2016 +0000
- Revision:
- 2:ef6c30f459a5
- Parent:
- 1:d357a1e80389
- Child:
- 3:d4b8692e6697
calculate standard deviation from the whole signal
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jankoekenpan | 0:e7f5d0b44e22 | 1 | #include "mbed.h" |
Jankoekenpan | 0:e7f5d0b44e22 | 2 | #include "HIDScope.h" |
Jankoekenpan | 1:d357a1e80389 | 3 | #include "BiQuad.h" |
Jankoekenpan | 1:d357a1e80389 | 4 | #include "math.h" |
Jankoekenpan | 1:d357a1e80389 | 5 | |
Jankoekenpan | 1:d357a1e80389 | 6 | AnalogIn emg1(A0); |
Jankoekenpan | 1:d357a1e80389 | 7 | |
Jankoekenpan | 1:d357a1e80389 | 8 | HIDScope scope(6); |
Jankoekenpan | 1:d357a1e80389 | 9 | Ticker ticker; |
Jankoekenpan | 1:d357a1e80389 | 10 | |
Jankoekenpan | 1:d357a1e80389 | 11 | //BiQuadChain bqc; |
Jankoekenpan | 1:d357a1e80389 | 12 | //Bandpass butterworth filter + Notch butterworth filter. |
Jankoekenpan | 1:d357a1e80389 | 13 | //Bandpass: 10 --- 500 Hz |
Jankoekenpan | 1:d357a1e80389 | 14 | //Nothc: 50 +- 2 Hz |
Jankoekenpan | 1:d357a1e80389 | 15 | //BiQuad bq1( 4.97164e-02, 9.94328e-02, 4.97164e-02, -3.04503e-01, 6.36149e-02 ); |
Jankoekenpan | 1:d357a1e80389 | 16 | //BiQuad bq2( 1.00000e+00, -2.00000e+00, 1.00000e+00, -3.87549e-01, 4.72280e-01 ); |
Jankoekenpan | 1:d357a1e80389 | 17 | //BiQuad bq3( 1.00000e+00, 2.00000e+00, 1.00000e+00, -1.95093e+00, 9.51645e-01 ); |
Jankoekenpan | 1:d357a1e80389 | 18 | //BiQuad bq4( 1.00000e+00, -2.00000e+00, 1.00000e+00, -1.97996e+00, 9.80645e-01 ); |
Jankoekenpan | 1:d357a1e80389 | 19 | //BiQuad bq5( 9.97389e-01, -1.97771e+00, 9.97389e-01, -1.97771e+00, 9.94778e-01 ); |
Jankoekenpan | 1:d357a1e80389 | 20 | |
Jankoekenpan | 2:ef6c30f459a5 | 21 | volatile float TOTAL_SAMPLE_SUM = 0; |
Jankoekenpan | 2:ef6c30f459a5 | 22 | volatile long NUMBER_SAMPLES = 0; |
Jankoekenpan | 2:ef6c30f459a5 | 23 | |
Jankoekenpan | 1:d357a1e80389 | 24 | const int numEmgCache = 50; |
Jankoekenpan | 1:d357a1e80389 | 25 | float emgCache[numEmgCache]; //sorted from new to old; |
Jankoekenpan | 1:d357a1e80389 | 26 | |
Jankoekenpan | 1:d357a1e80389 | 27 | const int numAvgCache = 50; |
Jankoekenpan | 1:d357a1e80389 | 28 | float averageCache[numAvgCache]; //sorted from new to old; |
Jankoekenpan | 1:d357a1e80389 | 29 | |
Jankoekenpan | 1:d357a1e80389 | 30 | void addFirst(float newValue, float array[], int size) { |
Jankoekenpan | 1:d357a1e80389 | 31 | for (int i = size - 2; i >= 0; i--) { |
Jankoekenpan | 1:d357a1e80389 | 32 | array[i+1] = array[i]; |
Jankoekenpan | 1:d357a1e80389 | 33 | } |
Jankoekenpan | 1:d357a1e80389 | 34 | array[0] = newValue; |
Jankoekenpan | 1:d357a1e80389 | 35 | } |
Jankoekenpan | 1:d357a1e80389 | 36 | |
Jankoekenpan | 1:d357a1e80389 | 37 | //shifts the array by adding the new emg value up front. |
Jankoekenpan | 1:d357a1e80389 | 38 | //returns the new calculated average |
Jankoekenpan | 1:d357a1e80389 | 39 | float movingAverage(float newValue) { |
Jankoekenpan | 1:d357a1e80389 | 40 | float sum = 0; |
Jankoekenpan | 1:d357a1e80389 | 41 | for (int i = numEmgCache - 2; i >= 0; i--) { |
Jankoekenpan | 1:d357a1e80389 | 42 | emgCache[i+1] = emgCache[i]; |
Jankoekenpan | 1:d357a1e80389 | 43 | sum += emgCache[i]; |
Jankoekenpan | 1:d357a1e80389 | 44 | } |
Jankoekenpan | 1:d357a1e80389 | 45 | emgCache[0] = newValue; |
Jankoekenpan | 1:d357a1e80389 | 46 | sum += newValue; |
Jankoekenpan | 1:d357a1e80389 | 47 | return sum / numEmgCache; |
Jankoekenpan | 1:d357a1e80389 | 48 | } |
Jankoekenpan | 1:d357a1e80389 | 49 | |
Jankoekenpan | 1:d357a1e80389 | 50 | float sum(float array[], int size) { |
Jankoekenpan | 1:d357a1e80389 | 51 | float sum = 0; |
Jankoekenpan | 1:d357a1e80389 | 52 | for (int i = 0; i < size; i++) { |
Jankoekenpan | 1:d357a1e80389 | 53 | sum += array[i]; |
Jankoekenpan | 1:d357a1e80389 | 54 | } |
Jankoekenpan | 1:d357a1e80389 | 55 | return sum; |
Jankoekenpan | 1:d357a1e80389 | 56 | } |
Jankoekenpan | 1:d357a1e80389 | 57 | |
Jankoekenpan | 1:d357a1e80389 | 58 | float mean(float array[], int size) { |
Jankoekenpan | 1:d357a1e80389 | 59 | return sum(array, size) / size; |
Jankoekenpan | 1:d357a1e80389 | 60 | } |
Jankoekenpan | 1:d357a1e80389 | 61 | |
Jankoekenpan | 2:ef6c30f459a5 | 62 | float variance(float array[], int size, float avg) { |
Jankoekenpan | 1:d357a1e80389 | 63 | float squaredDifferences[size]; |
Jankoekenpan | 1:d357a1e80389 | 64 | for (int i = 0; i < size; i++) { |
Jankoekenpan | 1:d357a1e80389 | 65 | float difference = array[i] - avg; |
Jankoekenpan | 1:d357a1e80389 | 66 | squaredDifferences[i] = difference*difference; |
Jankoekenpan | 1:d357a1e80389 | 67 | } |
Jankoekenpan | 1:d357a1e80389 | 68 | return mean(squaredDifferences, size); |
Jankoekenpan | 1:d357a1e80389 | 69 | } |
Jankoekenpan | 1:d357a1e80389 | 70 | |
Jankoekenpan | 2:ef6c30f459a5 | 71 | float standardDeviation(float array[], int size, float avg) { |
Jankoekenpan | 2:ef6c30f459a5 | 72 | return sqrt(variance(array, size, avg)); |
Jankoekenpan | 1:d357a1e80389 | 73 | } |
Jankoekenpan | 1:d357a1e80389 | 74 | |
Jankoekenpan | 2:ef6c30f459a5 | 75 | int decide(float value, float threshold) { |
Jankoekenpan | 2:ef6c30f459a5 | 76 | return value < threshold ? 0 : 1; |
Jankoekenpan | 1:d357a1e80389 | 77 | } |
Jankoekenpan | 0:e7f5d0b44e22 | 78 | |
Jankoekenpan | 0:e7f5d0b44e22 | 79 | |
Jankoekenpan | 0:e7f5d0b44e22 | 80 | void tick() { |
Jankoekenpan | 1:d357a1e80389 | 81 | float emg = emg1.read(); |
Jankoekenpan | 1:d357a1e80389 | 82 | scope.set(0, emg); |
Jankoekenpan | 1:d357a1e80389 | 83 | float filtered = movingAverage( fabs(emg) ); |
Jankoekenpan | 1:d357a1e80389 | 84 | scope.set(1, filtered); |
Jankoekenpan | 1:d357a1e80389 | 85 | |
Jankoekenpan | 2:ef6c30f459a5 | 86 | TOTAL_SAMPLE_SUM += emg; |
Jankoekenpan | 2:ef6c30f459a5 | 87 | NUMBER_SAMPLES++; |
Jankoekenpan | 2:ef6c30f459a5 | 88 | |
Jankoekenpan | 1:d357a1e80389 | 89 | addFirst(filtered, averageCache, numAvgCache); |
Jankoekenpan | 2:ef6c30f459a5 | 90 | float avg = TOTAL_SAMPLE_SUM / NUMBER_SAMPLES; //TODO calibrate this value. |
Jankoekenpan | 2:ef6c30f459a5 | 91 | float stdDev = standardDeviation(averageCache, numAvgCache, avg); |
Jankoekenpan | 1:d357a1e80389 | 92 | scope.set(2, stdDev); |
Jankoekenpan | 1:d357a1e80389 | 93 | |
Jankoekenpan | 1:d357a1e80389 | 94 | |
Jankoekenpan | 1:d357a1e80389 | 95 | //float filtered = bqc.step( emg ); |
Jankoekenpan | 1:d357a1e80389 | 96 | //scope.set(1, filtered); |
Jankoekenpan | 1:d357a1e80389 | 97 | |
Jankoekenpan | 1:d357a1e80389 | 98 | //scope.set(2, decide(filtered, 0.2f)); |
Jankoekenpan | 1:d357a1e80389 | 99 | //scope.set(3, decide(filtered, 0.3f)); |
Jankoekenpan | 1:d357a1e80389 | 100 | //scope.set(4, decide(filtered, 0.4f)); |
Jankoekenpan | 1:d357a1e80389 | 101 | //scope.set(5, decide(filtered, 0.5f)); |
Jankoekenpan | 1:d357a1e80389 | 102 | |
Jankoekenpan | 0:e7f5d0b44e22 | 103 | scope.send(); |
Jankoekenpan | 0:e7f5d0b44e22 | 104 | } |
Jankoekenpan | 0:e7f5d0b44e22 | 105 | |
Jankoekenpan | 0:e7f5d0b44e22 | 106 | int main() |
Jankoekenpan | 0:e7f5d0b44e22 | 107 | { |
Jankoekenpan | 1:d357a1e80389 | 108 | //bqc.add( &bq1 ).add( &bq2 );//.add( &bq3 ).add( &bq4 ).add( &bq5 ); |
Jankoekenpan | 1:d357a1e80389 | 109 | |
Jankoekenpan | 1:d357a1e80389 | 110 | ticker.attach(&tick, 8.333333333333334e-4); |
Jankoekenpan | 0:e7f5d0b44e22 | 111 | while (true); |
Jankoekenpan | 0:e7f5d0b44e22 | 112 | } |