Gesture Controlled Music Glove
Dependencies: LSM9DS1_Library_cal mbed
Fork of LSM9DS1_Demo_wCal by
main.cpp@2:c9577006ff47, 2016-12-09 (annotated)
- Committer:
- laxman7117
- Date:
- Fri Dec 09 15:31:36 2016 +0000
- Revision:
- 2:c9577006ff47
- Parent:
- 1:14f493caf676
SmartWav
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
4180_1 | 0:e693d5bf0a25 | 1 | #include "mbed.h" |
4180_1 | 0:e693d5bf0a25 | 2 | #include "LSM9DS1.h" |
laxman7117 | 1:14f493caf676 | 3 | #include "SMARTWAV.h" |
4180_1 | 0:e693d5bf0a25 | 4 | #define PI 3.14159 |
4180_1 | 0:e693d5bf0a25 | 5 | // Earth's magnetic field varies by location. Add or subtract |
4180_1 | 0:e693d5bf0a25 | 6 | // a declination to get a more accurate heading. Calculate |
4180_1 | 0:e693d5bf0a25 | 7 | // your's here: |
4180_1 | 0:e693d5bf0a25 | 8 | // http://www.ngdc.noaa.gov/geomag-web/#declination |
4180_1 | 0:e693d5bf0a25 | 9 | #define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA. |
4180_1 | 0:e693d5bf0a25 | 10 | |
laxman7117 | 1:14f493caf676 | 11 | SMARTWAV sWav(p13,p14,p15); //(TX,RX,Reset); Music Player |
laxman7117 | 1:14f493caf676 | 12 | LSM9DS1 IMU(p9, p10, 0xD6, 0x3C); // IMU for gesture control |
laxman7117 | 1:14f493caf676 | 13 | DigitalOut myled1(LED1); // Gesture feedback |
laxman7117 | 1:14f493caf676 | 14 | DigitalOut myled2(LED2); // Gesture feedback |
laxman7117 | 1:14f493caf676 | 15 | DigitalOut myled3(LED3); // Gesture feedback |
laxman7117 | 1:14f493caf676 | 16 | DigitalOut myled4(LED4); // Gesture feedback |
laxman7117 | 1:14f493caf676 | 17 | Serial pc(USBTX, USBRX); |
laxman7117 | 1:14f493caf676 | 18 | DigitalIn pb(p20); // Read gesture input controller |
laxman7117 | 1:14f493caf676 | 19 | |
laxman7117 | 1:14f493caf676 | 20 | //define code for volume control |
laxman7117 | 1:14f493caf676 | 21 | AnalogIn IRSensor(p19); |
laxman7117 | 1:14f493caf676 | 22 | DigitalIn pushbutton(p8); //grounded - locks in volume control |
laxman7117 | 1:14f493caf676 | 23 | |
laxman7117 | 1:14f493caf676 | 24 | char level='9'; // Default volume level |
laxman7117 | 1:14f493caf676 | 25 | |
laxman7117 | 1:14f493caf676 | 26 | float Pitch; |
laxman7117 | 1:14f493caf676 | 27 | float Roll; |
laxman7117 | 1:14f493caf676 | 28 | float pitch; |
laxman7117 | 1:14f493caf676 | 29 | float roll; |
laxman7117 | 1:14f493caf676 | 30 | bool flag = true; // Reading in a base values |
laxman7117 | 1:14f493caf676 | 31 | bool start_music = true; |
laxman7117 | 1:14f493caf676 | 32 | bool music_playing = false; |
laxman7117 | 1:14f493caf676 | 33 | bool flag2 = true; |
laxman7117 | 1:14f493caf676 | 34 | |
laxman7117 | 1:14f493caf676 | 35 | |
4180_1 | 0:e693d5bf0a25 | 36 | // Calculate pitch, roll, and heading. |
4180_1 | 0:e693d5bf0a25 | 37 | // Pitch/roll calculations taken from this app note: |
4180_1 | 0:e693d5bf0a25 | 38 | // http://cache.freescale.com/files/sensors/doc/app_note/AN3461.pdf?fpsp=1 |
4180_1 | 0:e693d5bf0a25 | 39 | // Heading calculations taken from this app note: |
4180_1 | 0:e693d5bf0a25 | 40 | // http://www51.honeywell.com/aero/common/documents/myaerospacecatalog-documents/Defense_Brochures-documents/Magnetic__Literature_Application_notes-documents/AN203_Compass_Heading_Using_Magnetometers.pdf |
4180_1 | 0:e693d5bf0a25 | 41 | void printAttitude(float ax, float ay, float az, float mx, float my, float mz) |
4180_1 | 0:e693d5bf0a25 | 42 | { |
laxman7117 | 1:14f493caf676 | 43 | roll = atan2(ay, az); |
laxman7117 | 1:14f493caf676 | 44 | pitch = atan2(-ax, sqrt(ay * ay + az * az)); |
4180_1 | 0:e693d5bf0a25 | 45 | // touchy trig stuff to use arctan to get compass heading (scale is 0..360) |
4180_1 | 0:e693d5bf0a25 | 46 | mx = -mx; |
4180_1 | 0:e693d5bf0a25 | 47 | float heading; |
4180_1 | 0:e693d5bf0a25 | 48 | if (my == 0.0) |
4180_1 | 0:e693d5bf0a25 | 49 | heading = (mx < 0.0) ? 180.0 : 0.0; |
4180_1 | 0:e693d5bf0a25 | 50 | else |
4180_1 | 0:e693d5bf0a25 | 51 | heading = atan2(mx, my)*360.0/(2.0*PI); |
4180_1 | 0:e693d5bf0a25 | 52 | //pc.printf("heading atan=%f \n\r",heading); |
4180_1 | 0:e693d5bf0a25 | 53 | heading -= DECLINATION; //correct for geo location |
4180_1 | 0:e693d5bf0a25 | 54 | if(heading>180.0) heading = heading - 360.0; |
4180_1 | 0:e693d5bf0a25 | 55 | else if(heading<-180.0) heading = 360.0 + heading; |
4180_1 | 0:e693d5bf0a25 | 56 | else if(heading<0.0) heading = 360.0 + heading; |
4180_1 | 0:e693d5bf0a25 | 57 | |
4180_1 | 0:e693d5bf0a25 | 58 | |
4180_1 | 0:e693d5bf0a25 | 59 | // Convert everything from radians to degrees: |
4180_1 | 0:e693d5bf0a25 | 60 | //heading *= 180.0 / PI; |
4180_1 | 0:e693d5bf0a25 | 61 | pitch *= 180.0 / PI; |
4180_1 | 0:e693d5bf0a25 | 62 | roll *= 180.0 / PI; |
4180_1 | 0:e693d5bf0a25 | 63 | |
laxman7117 | 1:14f493caf676 | 64 | //pc.printf("Pitch: %f, Roll: %f degress\n\r",pitch, roll); |
laxman7117 | 1:14f493caf676 | 65 | //pc.printf("Magnetic Heading: %f degress\n\r",heading); |
4180_1 | 0:e693d5bf0a25 | 66 | } |
4180_1 | 0:e693d5bf0a25 | 67 | |
laxman7117 | 1:14f493caf676 | 68 | void controlvolume(){ |
laxman7117 | 1:14f493caf676 | 69 | |
laxman7117 | 1:14f493caf676 | 70 | float a = IRSensor;// 1=4cm 0=30cm |
laxman7117 | 1:14f493caf676 | 71 | if (pushbutton==0) //when the dipswitch is on change the volume; leds are defined to indicate volume level55yyh |
laxman7117 | 1:14f493caf676 | 72 | { |
laxman7117 | 1:14f493caf676 | 73 | |
laxman7117 | 1:14f493caf676 | 74 | if (a>0.9) //change to lowest volume |
laxman7117 | 1:14f493caf676 | 75 | { |
laxman7117 | 1:14f493caf676 | 76 | sWav.volume(MIN); //all volume values are defined in smartwav.h file |
laxman7117 | 1:14f493caf676 | 77 | level = '0'; |
laxman7117 | 1:14f493caf676 | 78 | |
laxman7117 | 1:14f493caf676 | 79 | } |
laxman7117 | 1:14f493caf676 | 80 | if (a>0.8 & a<=0.9) |
laxman7117 | 1:14f493caf676 | 81 | { |
laxman7117 | 1:14f493caf676 | 82 | sWav.volume(MIN0); |
laxman7117 | 1:14f493caf676 | 83 | level = '1'; |
laxman7117 | 1:14f493caf676 | 84 | } |
laxman7117 | 1:14f493caf676 | 85 | if (a>0.7 & a<=0.8) |
laxman7117 | 1:14f493caf676 | 86 | { |
laxman7117 | 1:14f493caf676 | 87 | sWav.volume(MIN1); |
laxman7117 | 1:14f493caf676 | 88 | level = '2'; |
laxman7117 | 1:14f493caf676 | 89 | } |
laxman7117 | 1:14f493caf676 | 90 | if (a>0.6 & a<=.7) |
laxman7117 | 1:14f493caf676 | 91 | { |
laxman7117 | 1:14f493caf676 | 92 | sWav.volume(MIN2); |
laxman7117 | 1:14f493caf676 | 93 | level = '3'; |
laxman7117 | 1:14f493caf676 | 94 | |
laxman7117 | 1:14f493caf676 | 95 | } |
laxman7117 | 1:14f493caf676 | 96 | if (a>0.5 & a<=.6) |
laxman7117 | 1:14f493caf676 | 97 | { |
laxman7117 | 1:14f493caf676 | 98 | sWav.volume(MIN3); |
laxman7117 | 1:14f493caf676 | 99 | level = '4'; |
laxman7117 | 1:14f493caf676 | 100 | } |
laxman7117 | 1:14f493caf676 | 101 | if(a>.4 & a<=.5) |
laxman7117 | 1:14f493caf676 | 102 | { |
laxman7117 | 1:14f493caf676 | 103 | sWav.volume(MED1); |
laxman7117 | 1:14f493caf676 | 104 | level = '5'; |
laxman7117 | 1:14f493caf676 | 105 | } |
laxman7117 | 1:14f493caf676 | 106 | if(a>.2 & a<=.3) |
laxman7117 | 1:14f493caf676 | 107 | { |
laxman7117 | 1:14f493caf676 | 108 | sWav.volume(MED2); |
laxman7117 | 1:14f493caf676 | 109 | level = '6'; |
laxman7117 | 1:14f493caf676 | 110 | } |
laxman7117 | 1:14f493caf676 | 111 | if(a>0.1 & a<=.2) |
laxman7117 | 1:14f493caf676 | 112 | { |
laxman7117 | 1:14f493caf676 | 113 | sWav.volume(MED3); |
laxman7117 | 1:14f493caf676 | 114 | level = '8'; |
laxman7117 | 1:14f493caf676 | 115 | } |
laxman7117 | 1:14f493caf676 | 116 | if(a<=0.1) //change to HIGHEST volume |
laxman7117 | 1:14f493caf676 | 117 | { |
laxman7117 | 1:14f493caf676 | 118 | sWav.volume(MAX); |
laxman7117 | 1:14f493caf676 | 119 | level = '8'; |
laxman7117 | 1:14f493caf676 | 120 | } |
laxman7117 | 1:14f493caf676 | 121 | if(level!='9'){pc.printf("v%c",level);} |
laxman7117 | 1:14f493caf676 | 122 | wait(.1); |
laxman7117 | 1:14f493caf676 | 123 | } |
laxman7117 | 1:14f493caf676 | 124 | } |
4180_1 | 0:e693d5bf0a25 | 125 | |
4180_1 | 0:e693d5bf0a25 | 126 | |
4180_1 | 0:e693d5bf0a25 | 127 | |
4180_1 | 0:e693d5bf0a25 | 128 | int main() |
4180_1 | 0:e693d5bf0a25 | 129 | { |
laxman7117 | 1:14f493caf676 | 130 | //char name[9]={0}; |
laxman7117 | 1:14f493caf676 | 131 | //char prev[9]={0}; |
laxman7117 | 1:14f493caf676 | 132 | sWav.reset(); //physically reset SMARTWAV |
laxman7117 | 1:14f493caf676 | 133 | myled1 = 1; myled2 = 1; myled3 = 1; myled4 = 1; // All 4 leds light up until calibration is finished |
laxman7117 | 1:14f493caf676 | 134 | pb.mode(PullUp); //pushbutton for controlling gesture input |
laxman7117 | 1:14f493caf676 | 135 | pushbutton.mode(PullUp); //pushbutton for controlling volume |
laxman7117 | 1:14f493caf676 | 136 | LSM9DS1 IMU(p9, p10, 0xD6, 0x3C); |
4180_1 | 0:e693d5bf0a25 | 137 | IMU.begin(); |
4180_1 | 0:e693d5bf0a25 | 138 | if (!IMU.begin()) { |
4180_1 | 0:e693d5bf0a25 | 139 | pc.printf("Failed to communicate with LSM9DS1.\n"); |
4180_1 | 0:e693d5bf0a25 | 140 | } |
4180_1 | 0:e693d5bf0a25 | 141 | IMU.calibrate(1); |
4180_1 | 0:e693d5bf0a25 | 142 | IMU.calibrateMag(0); |
laxman7117 | 1:14f493caf676 | 143 | myled1 = 0; myled2 = 0; myled3 = 0; myled4 = 0; // All leds turn off to indicate calibration is finished |
laxman7117 | 1:14f493caf676 | 144 | sWav.continuousPlay(ENABLE); |
laxman7117 | 1:14f493caf676 | 145 | while(1) { |
laxman7117 | 1:14f493caf676 | 146 | controlvolume(); //initiate volume function using IR sensor |
laxman7117 | 1:14f493caf676 | 147 | // The pushbutton controls the reading of the IMU(gestures) if it is not presseed the gestures will be ignored |
laxman7117 | 1:14f493caf676 | 148 | // Pressing the pushbutton for the first time starts the music playing |
laxman7117 | 1:14f493caf676 | 149 | if (pb == 0){ |
laxman7117 | 1:14f493caf676 | 150 | // Starting music for the first time function |
laxman7117 | 1:14f493caf676 | 151 | if (start_music == true){ |
laxman7117 | 1:14f493caf676 | 152 | pc.putc('P'); // Send 'P' to let the windows app that music has started to play |
laxman7117 | 1:14f493caf676 | 153 | sWav.playTracks(); // Play music |
laxman7117 | 1:14f493caf676 | 154 | start_music = false; // Keeps function from executing again |
laxman7117 | 1:14f493caf676 | 155 | music_playing = true; // Music is now playing |
laxman7117 | 1:14f493caf676 | 156 | } |
laxman7117 | 1:14f493caf676 | 157 | // Read IMU Values only the accel and mag values are being used to calculate the pitch and roll |
4180_1 | 0:e693d5bf0a25 | 158 | while(!IMU.tempAvailable()); |
4180_1 | 0:e693d5bf0a25 | 159 | IMU.readTemp(); |
4180_1 | 0:e693d5bf0a25 | 160 | while(!IMU.magAvailable(X_AXIS)); |
4180_1 | 0:e693d5bf0a25 | 161 | IMU.readMag(); |
4180_1 | 0:e693d5bf0a25 | 162 | while(!IMU.accelAvailable()); |
4180_1 | 0:e693d5bf0a25 | 163 | IMU.readAccel(); |
4180_1 | 0:e693d5bf0a25 | 164 | while(!IMU.gyroAvailable()); |
4180_1 | 0:e693d5bf0a25 | 165 | IMU.readGyro(); |
laxman7117 | 1:14f493caf676 | 166 | //pc.printf("\nIMU Temperature = %f C\n\r",25.0 + IMU.temperature/16.0); |
laxman7117 | 1:14f493caf676 | 167 | //pc.printf(" X axis Y axis Z axis\n\r"); |
laxman7117 | 1:14f493caf676 | 168 | //pc.printf("gyro: %9f %9f %9f in deg/s\n\r", IMU.calcGyro(IMU.gx), IMU.calcGyro(IMU.gy), IMU.calcGyro(IMU.gz)); |
laxman7117 | 1:14f493caf676 | 169 | //pc.printf("accel: %9f %9f %9f in Gs\n\r", IMU.calcAccel(IMU.ax), IMU.calcAccel(IMU.ay), IMU.calcAccel(IMU.az)); |
laxman7117 | 1:14f493caf676 | 170 | //pc.printf("mag: %9f %9f %9f in gauss\n\r", IMU.calcMag(IMU.mx), IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz)); |
4180_1 | 0:e693d5bf0a25 | 171 | printAttitude(IMU.calcAccel(IMU.ax), IMU.calcAccel(IMU.ay), IMU.calcAccel(IMU.az), IMU.calcMag(IMU.mx), |
4180_1 | 0:e693d5bf0a25 | 172 | IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz)); |
laxman7117 | 1:14f493caf676 | 173 | |
laxman7117 | 1:14f493caf676 | 174 | // The gestures are read by setting base values once the pushbutton is press and once there is a certain deviation from those base values a specific gesture can be determined |
laxman7117 | 1:14f493caf676 | 175 | |
laxman7117 | 1:14f493caf676 | 176 | // Set Base Values |
laxman7117 | 1:14f493caf676 | 177 | if (flag == true){ |
laxman7117 | 1:14f493caf676 | 178 | flag = false; |
laxman7117 | 1:14f493caf676 | 179 | Pitch = pitch; |
laxman7117 | 1:14f493caf676 | 180 | Roll = roll; |
laxman7117 | 1:14f493caf676 | 181 | } |
laxman7117 | 1:14f493caf676 | 182 | |
laxman7117 | 1:14f493caf676 | 183 | //Pause Track |
laxman7117 | 1:14f493caf676 | 184 | if (Pitch-pitch >= 20){ |
laxman7117 | 1:14f493caf676 | 185 | myled1 = 1; |
laxman7117 | 1:14f493caf676 | 186 | if (music_playing == true){ |
laxman7117 | 1:14f493caf676 | 187 | pc.putc('p'); // pause character |
laxman7117 | 1:14f493caf676 | 188 | sWav.pausePlay(); |
laxman7117 | 1:14f493caf676 | 189 | music_playing = false; |
laxman7117 | 1:14f493caf676 | 190 | } |
laxman7117 | 1:14f493caf676 | 191 | wait(.5); |
laxman7117 | 1:14f493caf676 | 192 | } |
laxman7117 | 1:14f493caf676 | 193 | else myled1 = 0; |
laxman7117 | 1:14f493caf676 | 194 | |
laxman7117 | 1:14f493caf676 | 195 | //Play Track |
laxman7117 | 1:14f493caf676 | 196 | if (pitch-Pitch >= 20){ |
laxman7117 | 1:14f493caf676 | 197 | myled2 = 1; |
laxman7117 | 1:14f493caf676 | 198 | if (music_playing == false){ |
laxman7117 | 1:14f493caf676 | 199 | pc.putc('P'); // Play character |
laxman7117 | 1:14f493caf676 | 200 | sWav.pausePlay(); |
laxman7117 | 1:14f493caf676 | 201 | music_playing = true; |
laxman7117 | 1:14f493caf676 | 202 | } |
laxman7117 | 1:14f493caf676 | 203 | wait(.5); |
laxman7117 | 1:14f493caf676 | 204 | } |
laxman7117 | 1:14f493caf676 | 205 | else myled2 = 0; |
laxman7117 | 1:14f493caf676 | 206 | |
laxman7117 | 1:14f493caf676 | 207 | // Restart Track |
laxman7117 | 1:14f493caf676 | 208 | if (Roll-roll >= 20){ |
laxman7117 | 1:14f493caf676 | 209 | myled3 = 1; |
laxman7117 | 1:14f493caf676 | 210 | if (music_playing == true){ |
laxman7117 | 1:14f493caf676 | 211 | pc.putc('b'); // Restart Track character |
laxman7117 | 1:14f493caf676 | 212 | sWav.rewindTrack(); |
laxman7117 | 1:14f493caf676 | 213 | } |
laxman7117 | 1:14f493caf676 | 214 | wait(.5); |
laxman7117 | 1:14f493caf676 | 215 | } |
laxman7117 | 1:14f493caf676 | 216 | else myled3 = 0; |
laxman7117 | 1:14f493caf676 | 217 | |
laxman7117 | 1:14f493caf676 | 218 | //Next Track |
laxman7117 | 1:14f493caf676 | 219 | if (roll-Roll >= 20){ |
laxman7117 | 1:14f493caf676 | 220 | myled4 = 1; |
laxman7117 | 1:14f493caf676 | 221 | wait(.5); |
laxman7117 | 1:14f493caf676 | 222 | if (music_playing == true){ |
laxman7117 | 1:14f493caf676 | 223 | pc.putc('n'); |
laxman7117 | 1:14f493caf676 | 224 | sWav.nextTrack(); |
laxman7117 | 1:14f493caf676 | 225 | } |
laxman7117 | 1:14f493caf676 | 226 | wait(.5); |
laxman7117 | 1:14f493caf676 | 227 | } |
laxman7117 | 1:14f493caf676 | 228 | else myled4 = 0; |
laxman7117 | 1:14f493caf676 | 229 | |
4180_1 | 0:e693d5bf0a25 | 230 | } |
laxman7117 | 1:14f493caf676 | 231 | else { |
laxman7117 | 1:14f493caf676 | 232 | flag = true; myled1 = 0; myled2 = 0; myled3 = 0; myled4 = 0; |
laxman7117 | 1:14f493caf676 | 233 | } |
laxman7117 | 1:14f493caf676 | 234 | |
laxman7117 | 1:14f493caf676 | 235 | }// end while loop |
laxman7117 | 1:14f493caf676 | 236 | |
laxman7117 | 1:14f493caf676 | 237 | }// end main |
4180_1 | 0:e693d5bf0a25 | 238 |