Gesture Controlled Music Glove

Dependencies:   LSM9DS1_Library_cal mbed

Fork of LSM9DS1_Demo_wCal by jim hamblen

Committer:
laxman7117
Date:
Fri Dec 09 15:31:36 2016 +0000
Revision:
2:c9577006ff47
Parent:
1:14f493caf676
SmartWav

Who changed what in which revision?

UserRevisionLine numberNew 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