Gesture Controlled Music Glove

Dependencies:   LSM9DS1_Library_cal mbed

Fork of LSM9DS1_Demo_wCal by jim hamblen

main.cpp

Committer:
laxman7117
Date:
2016-12-09
Revision:
2:c9577006ff47
Parent:
1:14f493caf676

File content as of revision 2:c9577006ff47:

#include "mbed.h"
#include "LSM9DS1.h"
#include "SMARTWAV.h"
#define PI 3.14159
// Earth's magnetic field varies by location. Add or subtract
// a declination to get a more accurate heading. Calculate
// your's here:
// http://www.ngdc.noaa.gov/geomag-web/#declination
#define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA.

SMARTWAV sWav(p13,p14,p15);    //(TX,RX,Reset); Music Player
LSM9DS1 IMU(p9, p10, 0xD6, 0x3C); // IMU for gesture control
DigitalOut myled1(LED1);          // Gesture feedback
DigitalOut myled2(LED2);          // Gesture feedback
DigitalOut myled3(LED3);          // Gesture feedback
DigitalOut myled4(LED4);          // Gesture feedback
Serial pc(USBTX, USBRX);          
DigitalIn pb(p20);                // Read gesture input controller

//define code for volume control
AnalogIn IRSensor(p19);
DigitalIn pushbutton(p8); //grounded - locks in volume control

char level='9'; // Default volume level

float Pitch;
float Roll;
float pitch;
float roll;
bool flag = true; // Reading in a base values
bool start_music = true; 
bool music_playing = false;
bool flag2 = true;


// Calculate pitch, roll, and heading.
// Pitch/roll calculations taken from this app note:
// http://cache.freescale.com/files/sensors/doc/app_note/AN3461.pdf?fpsp=1
// Heading calculations taken from this app note:
// http://www51.honeywell.com/aero/common/documents/myaerospacecatalog-documents/Defense_Brochures-documents/Magnetic__Literature_Application_notes-documents/AN203_Compass_Heading_Using_Magnetometers.pdf
void printAttitude(float ax, float ay, float az, float mx, float my, float mz)
{
    roll = atan2(ay, az);
    pitch = atan2(-ax, sqrt(ay * ay + az * az));
// touchy trig stuff to use arctan to get compass heading (scale is 0..360)
    mx = -mx;
    float heading;
    if (my == 0.0)
        heading = (mx < 0.0) ? 180.0 : 0.0;
    else
        heading = atan2(mx, my)*360.0/(2.0*PI);
    //pc.printf("heading atan=%f \n\r",heading);
    heading -= DECLINATION; //correct for geo location
    if(heading>180.0) heading = heading - 360.0;
    else if(heading<-180.0) heading = 360.0 + heading;
    else if(heading<0.0) heading = 360.0  + heading;


    // Convert everything from radians to degrees:
    //heading *= 180.0 / PI;
    pitch *= 180.0 / PI;
    roll  *= 180.0 / PI;

    //pc.printf("Pitch: %f,    Roll: %f degress\n\r",pitch, roll);
    //pc.printf("Magnetic Heading: %f degress\n\r",heading);
}

void controlvolume(){
    
    float a = IRSensor;// 1=4cm 0=30cm 
    if (pushbutton==0) //when the dipswitch is on change the volume; leds are defined to indicate volume level55yyh
    {             
             
                              if (a>0.9) //change to lowest volume
                            {
                                 sWav.volume(MIN); //all volume values are defined in smartwav.h file
                                 level = '0';
                              
                            }   
                             if (a>0.8 & a<=0.9)
                            {
                           sWav.volume(MIN0); 
                           level = '1';
                            }   
                            if (a>0.7 & a<=0.8)
                            {
                           sWav.volume(MIN1);
                             level = '2';
                            }
                            if (a>0.6 & a<=.7)
                         {
                          sWav.volume(MIN2);
                          level = '3';
                             
                            }
                            if (a>0.5 & a<=.6)
                         {
                          sWav.volume(MIN3);
                             level = '4';
                            }
                            if(a>.4 & a<=.5)
                            {
                          sWav.volume(MED1);
                          level = '5';  
                            }
                            if(a>.2 & a<=.3)
                            {
                          sWav.volume(MED2);
                               level = '6'; 
                            }
                            if(a>0.1 & a<=.2) 
                            {
                         sWav.volume(MED3);
                         level = '8';
                                    }
                            if(a<=0.1) //change to HIGHEST volume
                            {
                         sWav.volume(MAX);
                              level = '8';
                                    }
                                      if(level!='9'){pc.printf("v%c",level);}
    wait(.1);
    }
}



int main()
{
    //char name[9]={0};
    //char prev[9]={0}; 
    sWav.reset();                //physically reset SMARTWAV
    myled1 = 1; myled2 = 1; myled3 = 1; myled4 = 1; // All 4 leds light up until calibration is finished
    pb.mode(PullUp); //pushbutton for controlling gesture input 
    pushbutton.mode(PullUp); //pushbutton for controlling volume
    LSM9DS1 IMU(p9, p10, 0xD6, 0x3C); 
    IMU.begin();
    if (!IMU.begin()) {
        pc.printf("Failed to communicate with LSM9DS1.\n");
    }
    IMU.calibrate(1);
    IMU.calibrateMag(0);
    myled1 = 0; myled2 = 0; myled3 = 0; myled4 = 0; // All leds turn off to indicate calibration is finished
    sWav.continuousPlay(ENABLE);
while(1) {
controlvolume(); //initiate volume function using IR sensor
    // The pushbutton controls the reading of the IMU(gestures) if it is not presseed the gestures will be ignored
    // Pressing the pushbutton for the first time starts the music playing      
    if (pb == 0){
        // Starting music for the first time function
        if (start_music == true){
            pc.putc('P'); // Send 'P' to let the windows app that music has started to play
            sWav.playTracks(); // Play music
            start_music = false; // Keeps function from executing again
            music_playing = true; // Music is now playing
            }
        // Read IMU Values only the accel and mag values are being used to calculate the pitch and roll
        while(!IMU.tempAvailable());
        IMU.readTemp();
        while(!IMU.magAvailable(X_AXIS));
        IMU.readMag();
        while(!IMU.accelAvailable());
        IMU.readAccel();
        while(!IMU.gyroAvailable());
        IMU.readGyro();
        //pc.printf("\nIMU Temperature = %f C\n\r",25.0 + IMU.temperature/16.0);
        //pc.printf("        X axis    Y axis    Z axis\n\r");
        //pc.printf("gyro:  %9f %9f %9f in deg/s\n\r", IMU.calcGyro(IMU.gx), IMU.calcGyro(IMU.gy), IMU.calcGyro(IMU.gz));
        //pc.printf("accel: %9f %9f %9f in Gs\n\r", IMU.calcAccel(IMU.ax), IMU.calcAccel(IMU.ay), IMU.calcAccel(IMU.az));
        //pc.printf("mag:   %9f %9f %9f in gauss\n\r", IMU.calcMag(IMU.mx), IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz));
        printAttitude(IMU.calcAccel(IMU.ax), IMU.calcAccel(IMU.ay), IMU.calcAccel(IMU.az), IMU.calcMag(IMU.mx),
                      IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz));
                      
        // 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
        
        // Set Base Values
        if (flag == true){
            flag = false;
            Pitch = pitch;
            Roll = roll;
        }
        
        //Pause Track 
        if (Pitch-pitch >= 20){
            myled1 = 1; 
            if (music_playing == true){
                pc.putc('p'); // pause character
                sWav.pausePlay();
                music_playing = false;
            }
            wait(.5);
        }
        else myled1 = 0;
        
        //Play Track 
        if (pitch-Pitch >= 20){
             myled2 = 1;
             if (music_playing == false){
                 pc.putc('P'); // Play character
                 sWav.pausePlay();
                 music_playing = true;
                }
            wait(.5);
        }
        else myled2 = 0;
        
        // Restart Track
        if (Roll-roll >= 20){
            myled3 = 1;
            if (music_playing == true){
                pc.putc('b'); // Restart Track character
                sWav.rewindTrack();
            }
            wait(.5);
        }
        else myled3 = 0;
        
        //Next Track
        if (roll-Roll >= 20){
            myled4 = 1;
            wait(.5);
            if (music_playing == true){
                pc.putc('n');
                sWav.nextTrack();  
            }
            wait(.5);
        }
        else myled4 = 0;
        
    }
    else {
        flag = true; myled1 = 0; myled2 = 0; myled3 = 0; myled4 = 0;
    }
    
}// end while loop
 
}// end main