Superhans v1 (index finger click and second finger 'q')

Dependencies:   MMA8451Q USBDevice mbed-rtos mbed

Fork of Super_Hans_USB by Anurag Dhutti

SuperHansRightGlove.cpp

Committer:
InBrewJ
Date:
2014-01-30
Revision:
2:034f34663c45

File content as of revision 2:034f34663c45:

/* SuperHansRightGlove.cpp    

IDEA - MAP FLEX SENSORS TO A SET HID REPORT.data
will allow more button presses!

Code for WIRED RIGHT GLOVE

Sends mouse movement dependent on tilt
of the glove, index finger left mouse click,
middle finger 'q' press and various
finger/palm keys corresponding to various
keys on a standard keyboard

For use with:
FRDM KL25Z
 
Authors:
Tristan Hughes
Anurag Dhutti
Jason Brewer
*/ 

#include "mbed.h"
#include "rtos.h"
#define MMA8451_I2C_ADDRESS (0x1d<<1)
#include "MMA8451Q.h"
#include "USBMouseKeyboard.h"
#include "USBHID.h"

// Misc Init

DigitalOut led(LED1);
MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS);
AnalogIn ain(PTB1);    // Forefinger sensor
AnalogIn ain1(PTB0);   // Second finger Sensor
USBMouseKeyboard key_mouse;
Mutex USB_mutex;

// Button Init

// D-Pad Palm Switches
DigitalIn _up(PTE5);
DigitalIn _left(PTE4);
DigitalIn _down(PTE3);
DigitalIn _right(PTE2);
DigitalIn _sel(PTB11);
DigitalIn _start(PTB10);

// Finger Switches
DigitalIn _i1(PTE31);

DigitalIn _s1(PTA17);
DigitalIn _s2(PTA16);
DigitalIn _s3(PTC17);
DigitalIn _s4(PTC16);

DigitalIn _th1(PTC13);
DigitalIn _th2(PTC12);
DigitalIn _th3(PTC11);
DigitalIn _th4(PTC10);

DigitalIn _pi1(PTC6);

void click_thread(void const *args)
{
    bool press[2];
    bool lPress = 0;
    //bool rPress = 0;
    
    // PLEASE NOTE:
    // The following code does not allow both mouse
    // buttons to be pressed down at the same time.
    // Your system will register the press of each button
    // but as soon as one is released the other will also
    // be released. Review your application to see if this is
    // applicable. 
    
    while(true) {
        lPress = ain.read()<0.5;
        //rPress = ain1.read()<0.25;
        //key_mouse.printf("Fore: %f Sec: %f\n",ain.read(), ain1.read());
        if( lPress && (press[0] == 0) ) {
            press[0] = 1;
            led != led;
            //key_mouse.printf("L: %i\n", lPress);
            USB_mutex.lock();
            key_mouse.press(MOUSE_LEFT);
            USB_mutex.unlock();
        } else if ( !lPress && (press[0] == 1) ) {
            press[0] = 0;
            //key_mouse.printf("L: %i\n", lPress);
            USB_mutex.lock();
            key_mouse.release(MOUSE_LEFT);
            USB_mutex.unlock();
        }
        if(!_i1 && press[1] == 0) {
        //if( rPress && (press[1] == 0) ) {
             //key_mouse.printf("R: %i\n", rPress);
             press[1] = 1;
             if(!lPress) USB_mutex.lock();
             key_mouse.press(MOUSE_RIGHT);            
             if(!lPress) USB_mutex.unlock();     // As Right mouse click
         }else if(_i1 && press[1] == 1) {
        //}else if( !rPress && (press[1] == 1) ) {
             //key_mouse.printf("R: %i\n", rPress);
             press[1] = 0;
             if(!lPress) USB_mutex.lock();
             key_mouse.release(MOUSE_RIGHT);
             if(!lPress) USB_mutex.unlock();
         }
        
        Thread::wait(100);
    }
}


void mouse_thread(void const *args)
{
    while(true) {

        USB_mutex.lock();
        key_mouse.move(-acc.getAccZ()*10, 0);
        key_mouse.move(0, -acc.getAccX()*10);
        USB_mutex.unlock();
        Thread::wait(1);
    }
}

void SendKeyPress (uint8_t keyID, bool state, uint8_t numberPressed)
{
    // Send a simulated keyboard keypress. Returns true if successful.
    static HID_REPORT report;
    static uint8_t last_pressed;
    static uint8_t keyBuffer[3];
    
    report.data[0] = REPORT_ID_KEYBOARD;
    report.data[1] = 0;
    report.data[2] = 0;
    //report.data[3] = 0;  
    //report.data[4] = 0;
    //report.data[5] = 0;
    report.data[6] = 0;
    report.data[7] = 0;
    report.data[8] = 0;

    report.length = 9;
    
    // Multiple button press functionality
    
    if(!numberPressed)     // Clear the keyBuffer if no buttons are pressed
    {
        keyBuffer[0] = 0;
        keyBuffer[1] = 0;
        keyBuffer[2] = 0;
    }
    
    if(state)  // If a button is pressed, put it in the keyBuffer
    {
        keyBuffer[numberPressed-1] = keyID;
    }
    
    // If keys are depressed in the same order
    // in which they were pressed, swap the second
    // member of the key buffer with the first so
    // expected behaviour is maintained
    
    // Only has functionality for 2 key presses at once
    // which follows most standard keyboard
    
    // 3 key presses at once gets a little trickier
    
    if(!state && numberPressed == 1 && 
        keyBuffer[0] == keyID)
    {
        keyBuffer[0] = keyBuffer[1];
        keyBuffer[1] = 0;
    }
    
    //key_mouse.printf("keyBuffer: %X, %X, %X\n", keyBuffer[0], keyBuffer[1], keyBuffer[2]);
    
    if(numberPressed == 0)
    {
        report.data[3] = 0;
        report.data[4] = 0;
        report.data[5] = 0;
    }else if(numberPressed == 1)
    {
        report.data[3] = keyBuffer[0];
        report.data[4] = 0;
        report.data[5] = 0;
    }else if(numberPressed == 2)
    {
        report.data[3] = report.data[3];
        report.data[4] = keyBuffer[1];
        report.data[5] = 0;
    } else if(numberPressed == 3)  // not actually functional
    {
        report.data[3] = report.data[3];
        report.data[4] = report.data[4];
        report.data[5] = keyBuffer[2];
    }
    
    key_mouse.send(&report);

}

void keyboard_thread(void const *args)
{
    uint8_t numberPressed = 0;
    bool press[16] = {0};
        
    while(true) {
        
        // Uncomment for debug
        
        //key_mouse.printf("No: %d\n", numberPressed);
        /*key_mouse.printf("pressArr: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
        press[0], press[1], press[2], press[3], press[4], press[5], press[6], press[7],
        press[8], press[9], press[10], press[11], press[12], press[13], press[14], press[15]);*/
        
        // Makes the second bend sensor map to the key "q"
        // Mapping the second bend sensor to right mouse
        // poses some issues to do with how the clicks are sent
        // in the mbed libraries. An indepth analysis
        // of HID reports is required and tbh cba ukno
        
        if( (ain1.read()<0.25) && (press[0] == 0) ) {            
            if(press[0] == 0) numberPressed++;
            press[0] = 1;
            //key_mouse.printf("   qPress: %i\n", press[0]);
            //USB_mutex.lock();
            //key_mouse.press(MOUSE_RIGHT); // Sends right mouse click
            //USB_mutex.unlock();
            SendKeyPress(0x14,1,numberPressed);     // Sends 'q' keypress
        } else if ( (ain1.read()>0.25) && (press[0] == 1) ) {
            if(press[0] == 1) numberPressed--;
            press[0] = 0;
            //key_mouse.printf("R: %i\n", press[0]);
            //USB_mutex.lock();
            //key_mouse.release(MOUSE_RIGHT); // releases right mouse click
            //USB_mutex.unlock();
            SendKeyPress(0x14,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        // FOREFINGER BUTTON

        /*if(!_i1 && press[0] == 0) {
            press[0] = 1;
            SendKeyPress(0x14,0);     // Sends 'q' keypress
            //Thread::wait(60);
        } else if(_i1 && press[0] == 1) {
            press[0] = 0;
            Thread::wait(17);
            SendKeyPress(0,1);
        }*/

        // SECOND FINGER BUTTONS (4 of them)

        if(!_s1 && press[1] == 0) {
            if(press[1] == 0) numberPressed++;
            press[1] = 1;
            SendKeyPress(0x08,1,numberPressed);     // Sends 'e' keypress (a = 0x04)
            //SendKeyPress(0x04,1,numberPressed);
            //Thread::wait(60);
        } else if(_s1 && press[1] == 1) {
            if(press[1] == 1) numberPressed--;
            press[1] = 0;
            Thread::wait(17);
            SendKeyPress(0x4,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        if(!_s2 && press[2] == 0) {
            if(press[2] == 0) numberPressed++;
            press[2] = 1;
            SendKeyPress(0x15,1,numberPressed);     // Sends 'r' keypress (w = 0x1a)
            //SendKeyPress(0x1a,1,numberPressed);
        } else if(_s2 && press[2] == 1) {
            if(press[2] == 1) numberPressed--;
            press[2] = 0;
            Thread::wait(17);
            SendKeyPress(0x1a,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        if(!_s3 && press[3]== 0) {
            if(press[3] == 0) numberPressed++;
            press[3] = 1;
            SendKeyPress(0x17,1,numberPressed);     // Sends 't' keypress (s = 0x16)
            //SendKeyPress(0x16,numberPressed);
            //Thread::wait(60);
        } else if(_s3 && press[3]== 1) {
            if(press[3] == 1) numberPressed--;
            press[3] = 0;
            Thread::wait(17);
            SendKeyPress(0x17,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        if(!_s4 && press[4]== 0) {
            if(press[4] == 0) numberPressed++;
            press[4] = 1;
            SendKeyPress(0x1c,1,numberPressed);     // Sends 'y' keypress (d = 0x07)
            //SendKeyPress(0x07,0);
            //Thread::wait(60);
        } else if(_s4 && press[4]== 1) {
            if(press[4] == 1) numberPressed--;
            press[4] = 0;
            Thread::wait(17);
            SendKeyPress(0x1c,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

       // THIRD FINGER BUTTONS (4 of them)

        if(!_th1 && press[5]== 0) {
            if(press[5] == 0) numberPressed++;
            press[5]= 1;
            SendKeyPress(0x18,1,numberPressed);     // Sends 'u' keypress
            Thread::wait(60);
        } else if(_th1 && press[5]== 1) {
            if(press[5] == 1) numberPressed--;
            press[5]= 0;
            SendKeyPress(0x18,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        if(!_th2 && press[6]== 0) {
            if(press[6] == 0) numberPressed++;
            press[6]= 1;
            SendKeyPress(0x0c,1,numberPressed);     // Sends 'i' keypress
            
        } else if(_th2 && press[6]== 1) {
            if(press[6] == 1) numberPressed--;
            press[6]= 0;
            SendKeyPress(0x0c,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        if(!_th3 && press[7]== 0) {
            if(press[7] == 0) numberPressed++;
            press[7]= 1;
            SendKeyPress(0x12,1,numberPressed);     // Sends 'o' keypress
            
        } else if(_th3 && press[7]== 1) {
            if(press[7] == 1) numberPressed--;
            press[7]= 0;
            SendKeyPress(0x12,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        if(!_th4 && press[8]== 0) {
            if(press[8] == 0) numberPressed++;
            press[8]= 1;
            SendKeyPress(0x13,1, numberPressed);     // Sends 'p' keypress
            
        } else if(_th4 && press[8]== 1) {
            if(press[8] == 1) numberPressed--;
            press[8]= 0;
            SendKeyPress(0x13,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        // PINKY BUTTON

        if(!_pi1 && press[9]== 0) {
            if(press[9] == 0) numberPressed++;
            press[9]= 1;
            //SendKeyPress(0x2f,0);     // Sends '[' keypress
            SendKeyPress(0x2c,1,numberPressed);     // Sends 'space' keypress
            
        } else if(_pi1 && press[9]== 1) {
            if(press[9] == 1) numberPressed--;
            press[9]= 0;
            Thread::wait(17);
            SendKeyPress(0x2c,0, numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        // PALM D-PAD BUTTONS (6 of them)

        if(!_up && press[10]== 0) {
            if(press[10] == 0) numberPressed++;
            press[10]= 1;
            SendKeyPress(0x52,1,numberPressed);     // Sends up arrow keypress
            
        } else if(_up && press[10]== 1) {
            if(press[10] == 1) numberPressed--;
            press[10]= 0;
            SendKeyPress(0x52,1,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        if(!_left && press[11]== 0) {
            if(press[11] == 0) numberPressed++;
            press[11]= 1;
            SendKeyPress(0x50,1,numberPressed);     // Sends left arrow keypress
            
        } else if(_left && press[11]== 1) {
            if(press[11] == 1) numberPressed--;
            press[11]= 0;
            SendKeyPress(0x50,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        if(!_down && press[12]== 0) {
            if(press[12] == 0) numberPressed++;
            press[12]= 1;
            SendKeyPress(0x51,1,numberPressed);     // Sends down arrow keypress
            
        } else if(_down && press[12]== 1) {
            if(press[12] == 1) numberPressed--;
            press[12]= 0;
            SendKeyPress(0x51,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        if(!_right && press[13]== 0) {
            if(press[13] == 0) numberPressed++;
            press[13]= 1;
            SendKeyPress(0x4f,1,numberPressed);     // Sends right arrow keypress
            
        } else if(_right && press[13]== 1) {
            if(press[13] == 1) numberPressed--;
            press[13]= 0;
            SendKeyPress(0x4f,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        if(!_sel && press[14]== 0) {
            if(press[14] == 0) numberPressed++;
            press[14]= 1;
            SendKeyPress(0x1d,1,numberPressed);     // Sends 'z' keypress
            
        } else if(_sel && press[14]== 1) {
            if(press[14] == 1) numberPressed--;
            press[14]= 0;
            SendKeyPress(0x1d,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }

        if(!_start && press[15]== 0) {
            if(press[15] == 0) numberPressed++;
            press[15]= 1;
            SendKeyPress(0x1b,1,numberPressed);     // Sends 'x' keypress
            
        } else if(_start && press[15]== 1) {
            if(press[15] == 1) numberPressed--;
            press[15]= 0;
            SendKeyPress(0x1b,0,numberPressed);
        }else
        {
            numberPressed = numberPressed;
        }
    
    Thread::wait(100);  // Slows the whole thread down. Without this keys stick!
    //Thread::wait(300);

    }
}

int main()
{
    Thread click(click_thread);
    Thread mouse(mouse_thread);
    Thread keyboard(keyboard_thread);

    led = 1.0;

    while (true) {
    }
}