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

Dependencies:   MMA8451Q USBDevice mbed-rtos mbed

Fork of Super_Hans_USB by Anurag Dhutti

Revision:
2:034f34663c45
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SuperHansRightGlove.cpp	Thu Jan 30 14:48:49 2014 +0000
@@ -0,0 +1,503 @@
+/* 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) {
+    }
+}