kapotte printf

Dependencies:   HIDScope biquadFilter mbed

Committer:
Joost38H
Date:
Mon Oct 23 09:06:57 2017 +0000
Revision:
2:dac640cad05e
Parent:
1:4d7097e583e0
kapotte printf

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Joost38H 0:33f422404c9f 1 #include "mbed.h"
Joost38H 0:33f422404c9f 2 #include "HIDScope.h"
Joost38H 0:33f422404c9f 3 #include "BiQuad.h"
Joost38H 0:33f422404c9f 4 #include "math.h"
Joost38H 0:33f422404c9f 5
Joost38H 2:dac640cad05e 6
Joost38H 2:dac640cad05e 7 Serial pc(USBTX, USBRX);
Joost38H 2:dac640cad05e 8
Joost38H 0:33f422404c9f 9
Joost38H 0:33f422404c9f 10 //Defining all in- and outputs
Joost38H 0:33f422404c9f 11 //EMG input
Joost38H 0:33f422404c9f 12 AnalogIn emgBR( A0 ); //Right Biceps
Joost38H 0:33f422404c9f 13 AnalogIn emgBL( A1 ); //Left Biceps
Joost38H 0:33f422404c9f 14
Joost38H 0:33f422404c9f 15 //LED output
Joost38H 0:33f422404c9f 16 DigitalOut led_B( LED_BLUE );
Joost38H 0:33f422404c9f 17 DigitalOut led_R( LED_RED );
Joost38H 0:33f422404c9f 18 DigitalOut led_G( LED_GREEN );
Joost38H 0:33f422404c9f 19
Joost38H 1:4d7097e583e0 20 //Setting Tickers for sampling EMG and determing if the threshold is met
Joost38H 0:33f422404c9f 21 Ticker sample_timer;
Joost38H 0:33f422404c9f 22 Ticker threshold_timer;
Joost38H 0:33f422404c9f 23
Joost38H 0:33f422404c9f 24 // Defining HIDScope ports needed
Joost38H 1:4d7097e583e0 25 HIDScope scope( 2 );
Joost38H 0:33f422404c9f 26
Joost38H 0:33f422404c9f 27
Joost38H 0:33f422404c9f 28 /* Defining all the different BiQuad filters, which contain a Notch filter,
Joost38H 0:33f422404c9f 29 High-pass filter and Low-pass filter. The Notch filter cancels all frequencies
Joost38H 0:33f422404c9f 30 between 49 and 51 Hz, the High-pass filter cancels all frequencies below 20 Hz
Joost38H 0:33f422404c9f 31 and the Low-pass filter cancels out all frequencies below 4 Hz */
Joost38H 0:33f422404c9f 32
Joost38H 0:33f422404c9f 33 /* Defining all the normalized values of b and a in the Notch filter for the
Joost38H 0:33f422404c9f 34 creation of the Notch BiQuad */
Joost38H 0:33f422404c9f 35
Joost38H 0:33f422404c9f 36 BiQuad bqNotch1( 0.9876, -1.5981, 0.9876, -1.5981, 0.9752 );
Joost38H 0:33f422404c9f 37 BiQuad bqNotch2( 0.9876, -1.5981, 0.9876, -1.5981, 0.9752 );
Joost38H 0:33f422404c9f 38
Joost38H 0:33f422404c9f 39 /* Defining all the normalized values of b and a in the High-pass filter for the
Joost38H 0:33f422404c9f 40 creation of the High-pass BiQuad */
Joost38H 0:33f422404c9f 41
Joost38H 0:33f422404c9f 42 BiQuad bqHigh1( 0.8371, -1.6742, 0.8371, -1.6475, 0.7009 );
Joost38H 0:33f422404c9f 43 BiQuad bqHigh2( 0.8371, -1.6742, 0.8371, -1.6475, 0.7009 );
Joost38H 0:33f422404c9f 44
Joost38H 0:33f422404c9f 45 /* Defining all the normalized values of b and a in the Low-pass filter for the
Joost38H 0:33f422404c9f 46 creation of the Low-pass BiQuad */
Joost38H 0:33f422404c9f 47
Joost38H 0:33f422404c9f 48 BiQuad bqLow1( 6.0985e-4, 0.0012, 6.0985e-4, -1.9289, 0.9314 );
Joost38H 0:33f422404c9f 49 BiQuad bqLow2( 6.0985e-4, 0.0012, 6.0985e-4, -1.9289, 0.9314 );
Joost38H 0:33f422404c9f 50
Joost38H 0:33f422404c9f 51 // Creating a variable needed for the creation of the BiQuadChain
Joost38H 0:33f422404c9f 52 BiQuadChain bqChain1;
Joost38H 0:33f422404c9f 53 BiQuadChain bqChain2;
Joost38H 0:33f422404c9f 54
Joost38H 0:33f422404c9f 55
Joost38H 0:33f422404c9f 56 //Defining all doubles needed in the filtering process
Joost38H 0:33f422404c9f 57 double emgBRfiltered; //Right biceps Notch+High pass filter
Joost38H 0:33f422404c9f 58 double emgBRrectified; //Right biceps rectified
Joost38H 0:33f422404c9f 59 double emgBRcomplete; //Right biceps low-pass filter, filtering complete
Joost38H 0:33f422404c9f 60
Joost38H 0:33f422404c9f 61 double emgBLfiltered; //Left biceps Notch+High pass filter
Joost38H 0:33f422404c9f 62 double emgBLrectified; //Left biceps rectified
Joost38H 0:33f422404c9f 63 double emgBLcomplete; //Left biceps low-pass filter, filtering complete
Joost38H 0:33f422404c9f 64
Joost38H 0:33f422404c9f 65
Joost38H 0:33f422404c9f 66 double threshold = 0.03;
Joost38H 0:33f422404c9f 67
Joost38H 0:33f422404c9f 68
Joost38H 0:33f422404c9f 69 /** Sample function
Joost38H 0:33f422404c9f 70 * this function samples the BR EMG, filters the EMG and sends it to HIDScope
Joost38H 0:33f422404c9f 71 **/
Joost38H 0:33f422404c9f 72 void EMG_sample()
Joost38H 0:33f422404c9f 73 {
Joost38H 0:33f422404c9f 74 emgBRfiltered = bqChain1.step( emgBR.read() ); //Notch+High-pass
Joost38H 0:33f422404c9f 75 emgBRrectified = fabs(emgBRfiltered); //Rectification
Joost38H 0:33f422404c9f 76 emgBRcomplete = bqLow1.step(emgBRrectified); //Low-pass
Joost38H 0:33f422404c9f 77
Joost38H 2:dac640cad05e 78
Joost38H 0:33f422404c9f 79
Joost38H 0:33f422404c9f 80 emgBLfiltered = bqChain2.step( emgBL.read() ); //Notch+High-pass
Joost38H 0:33f422404c9f 81 emgBLrectified = fabs( emgBLfiltered ); //Rectification
Joost38H 0:33f422404c9f 82 emgBLcomplete = bqLow2.step( emgBLrectified ); //Low-pass
Joost38H 0:33f422404c9f 83
Joost38H 0:33f422404c9f 84 /* Set the sampled emg values in channel 0 (the first channel) and 1
Joost38H 0:33f422404c9f 85 (the second channel) in the 'HIDScope' instance named 'scope' */
Joost38H 0:33f422404c9f 86
Joost38H 0:33f422404c9f 87 scope.set(1, emgBLcomplete );
Joost38H 0:33f422404c9f 88 scope.set(0, emgBRcomplete );
Joost38H 0:33f422404c9f 89
Joost38H 0:33f422404c9f 90
Joost38H 1:4d7097e583e0 91 /* Finally, send all channels to the PC at once */
Joost38H 0:33f422404c9f 92 scope.send();
Joost38H 0:33f422404c9f 93 /* To indicate that the function is working, the LED is toggled */
Joost38H 0:33f422404c9f 94 led_B = !led_B;
Joost38H 2:dac640cad05e 95
Joost38H 2:dac640cad05e 96
Joost38H 0:33f422404c9f 97 }
Joost38H 1:4d7097e583e0 98
Joost38H 2:dac640cad05e 99 double numsamples = 500;
Joost38H 2:dac640cad05e 100 double emgBRarray[500];
Joost38H 2:dac640cad05e 101 double emgBRsum;
Joost38H 2:dac640cad05e 102 double emgBRmeanMVC;
Joost38H 2:dac640cad05e 103 double thresholdBR;
Joost38H 2:dac640cad05e 104
Joost38H 2:dac640cad05e 105 double getThresholdBR()
Joost38H 2:dac640cad05e 106 {
Joost38H 2:dac640cad05e 107 for (int i=0; i<numsamples; i++) {
Joost38H 2:dac640cad05e 108 emgBRarray[i] = emgBRcomplete;
Joost38H 2:dac640cad05e 109 emgBRsum = emgBRsum + emgBRarray[i];
Joost38H 2:dac640cad05e 110 }
Joost38H 2:dac640cad05e 111
Joost38H 2:dac640cad05e 112 emgBRmeanMVC = emgBRsum / numsamples;
Joost38H 2:dac640cad05e 113
Joost38H 2:dac640cad05e 114 thresholdBR = emgBRmeanMVC * 0.3;
Joost38H 2:dac640cad05e 115 return thresholdBR;
Joost38H 2:dac640cad05e 116 }
Joost38H 2:dac640cad05e 117
Joost38H 2:dac640cad05e 118 double getThresholdBL()
Joost38H 2:dac640cad05e 119 {
Joost38H 2:dac640cad05e 120 double numsamples = 500;
Joost38H 2:dac640cad05e 121 double emgBLarray[500];
Joost38H 2:dac640cad05e 122 double emgBLsum;
Joost38H 2:dac640cad05e 123 for (int i=0; i<numsamples; i++) {
Joost38H 2:dac640cad05e 124 emgBLarray[i] = emgBLcomplete;
Joost38H 2:dac640cad05e 125 emgBLsum = emgBLsum + emgBLarray[i];
Joost38H 2:dac640cad05e 126 }
Joost38H 2:dac640cad05e 127
Joost38H 2:dac640cad05e 128 double emgBLmeanMVC = emgBLsum / numsamples;
Joost38H 2:dac640cad05e 129
Joost38H 2:dac640cad05e 130 double thresholdBL = emgBLmeanMVC * 0.3;
Joost38H 2:dac640cad05e 131 return thresholdBL;
Joost38H 2:dac640cad05e 132 }
Joost38H 2:dac640cad05e 133
Joost38H 1:4d7097e583e0 134
Joost38H 1:4d7097e583e0 135 // Function to make the BiQuadChain for the Notch and High pass filter for all three filters
Joost38H 0:33f422404c9f 136 void getbqChain()
Joost38H 0:33f422404c9f 137 {
Joost38H 0:33f422404c9f 138 bqChain1.add(&bqNotch1).add(&bqHigh1); //Making the BiQuadChain
Joost38H 0:33f422404c9f 139 bqChain2.add(&bqNotch2).add(&bqHigh2);
Joost38H 0:33f422404c9f 140 }
Joost38H 0:33f422404c9f 141
Joost38H 1:4d7097e583e0 142
Joost38H 1:4d7097e583e0 143 // Function to check if the threshold is met, with LED feedback for the user
Joost38H 0:33f422404c9f 144 void ThresholdReached()
Joost38H 0:33f422404c9f 145 {
Joost38H 2:dac640cad05e 146 if (emgBRcomplete > thresholdBR)
Joost38H 0:33f422404c9f 147 {
Joost38H 0:33f422404c9f 148 led_G = 0;
Joost38H 0:33f422404c9f 149 led_R = 1;
Joost38H 0:33f422404c9f 150 led_B = 1;
Joost38H 0:33f422404c9f 151 }
Joost38H 1:4d7097e583e0 152
Joost38H 1:4d7097e583e0 153 else if (emgBLcomplete > threshold)
Joost38H 1:4d7097e583e0 154 {
Joost38H 1:4d7097e583e0 155 led_G = 1;
Joost38H 1:4d7097e583e0 156 led_R = 0;
Joost38H 1:4d7097e583e0 157 led_B = 1;
Joost38H 1:4d7097e583e0 158 }
Joost38H 1:4d7097e583e0 159
Joost38H 0:33f422404c9f 160
Joost38H 0:33f422404c9f 161 else {
Joost38H 0:33f422404c9f 162 led_G = 1;
Joost38H 0:33f422404c9f 163 led_R = 1;
Joost38H 0:33f422404c9f 164 led_B = 0;
Joost38H 0:33f422404c9f 165 }
Joost38H 0:33f422404c9f 166
Joost38H 0:33f422404c9f 167 }
Joost38H 2:dac640cad05e 168
Joost38H 0:33f422404c9f 169
Joost38H 0:33f422404c9f 170 int main()
Joost38H 0:33f422404c9f 171 {
Joost38H 0:33f422404c9f 172 /*Attach the 'sample' function to the timer 'sample_timer'.
Joost38H 0:33f422404c9f 173 this ensures that 'sample' is executed every 0.002 seconds, to get a
Joost38H 0:33f422404c9f 174 sample frequency of 500 Hz
Joost38H 0:33f422404c9f 175 */
Joost38H 2:dac640cad05e 176 pc.baud(115200);
Joost38H 0:33f422404c9f 177 getbqChain();
Joost38H 0:33f422404c9f 178 sample_timer.attach(&EMG_sample, 0.002);
Joost38H 2:dac640cad05e 179 thresholdBR = getThresholdBR();
Joost38H 2:dac640cad05e 180 pc.printf("Threshold is %f.2\n", threshold);
Joost38H 0:33f422404c9f 181 threshold_timer.attach(&ThresholdReached, 0.002);
Joost38H 0:33f422404c9f 182
Joost38H 1:4d7097e583e0 183
Joost38H 0:33f422404c9f 184 while(1) {}
Joost38H 0:33f422404c9f 185 }