Ghost Mouse / Mbed 2 deprecated ghost_mouse

Dependencies:   mbed

Committer:
jennabarton
Date:
Sun Apr 02 20:57:25 2017 +0000
Revision:
12:e127fa20d609
Parent:
11:cd450ce343a8
Child:
13:4f2181174071
initial attempt at clicking

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daviwang 0:1c15cf9cc4f9 1 #include "mbed.h"
daviwang 0:1c15cf9cc4f9 2
jennabarton 8:d27efcac2dd7 3 //******************************************************************
jennabarton 8:d27efcac2dd7 4 // All variables defined below
jennabarton 8:d27efcac2dd7 5 //******************************************************************
jennabarton 8:d27efcac2dd7 6
jennabarton 8:d27efcac2dd7 7 //communication
daviwang 0:1c15cf9cc4f9 8 DigitalOut myled(LED1);
daviwang 1:2e895e5272ab 9 Serial pc(USBTX, USBRX);
jennabarton 4:1f443e7a0122 10 Serial keyOut(p13, p14);
daviwang 1:2e895e5272ab 11 I2C camera1(p9, p10);
daviwang 1:2e895e5272ab 12
jennabarton 2:f501e506d62b 13 //initial camera data
daviwang 1:2e895e5272ab 14 int IRsensorAddress = 0xB0;
daviwang 1:2e895e5272ab 15 int slaveAddress;
daviwang 1:2e895e5272ab 16 char data_buf[16];
jennabarton 2:f501e506d62b 17 char s;
daviwang 1:2e895e5272ab 18 int i;
daviwang 1:2e895e5272ab 19
jennabarton 2:f501e506d62b 20 //point variables
jennabarton 2:f501e506d62b 21 int point1x = 0;
jennabarton 2:f501e506d62b 22 int point1y = 0;
jennabarton 2:f501e506d62b 23 int point2x = 0;
jennabarton 2:f501e506d62b 24 int point2y = 0;
jennabarton 2:f501e506d62b 25 int point3x = 0;
jennabarton 2:f501e506d62b 26 int point3y = 0;
jennabarton 2:f501e506d62b 27 int point4x = 0;
jennabarton 2:f501e506d62b 28 int point4y = 0;
jennabarton 2:f501e506d62b 29
daviwang 1:2e895e5272ab 30 //sensitivity
daviwang 1:2e895e5272ab 31 //Level 5: p0 = 0x96, p1 = 0xFE, p2 = 0xFE, p3 = 0x05
jennabarton 8:d27efcac2dd7 32 //highest sensitivity to more accurately detect points
daviwang 1:2e895e5272ab 33 int sen0 = 0x96;
daviwang 1:2e895e5272ab 34 int sen1 = 0xFE;
daviwang 1:2e895e5272ab 35 int sen2 = 0xFE;
daviwang 1:2e895e5272ab 36 int sen3 = 0x00;
daviwang 1:2e895e5272ab 37
jennabarton 12:e127fa20d609 38 //previous point values
jennabarton 12:e127fa20d609 39 int prevX = 1023;
jennabarton 12:e127fa20d609 40 int prevY = 1023;
jennabarton 12:e127fa20d609 41
jennabarton 8:d27efcac2dd7 42 //matrices of x and y coordinates from the first camera
jennabarton 2:f501e506d62b 43 int onex[4];
jennabarton 2:f501e506d62b 44 int oney[4];
daviwang 1:2e895e5272ab 45
jennabarton 12:e127fa20d609 46 //matrices of x and y coordinates from prev point
jennabarton 12:e127fa20d609 47 int prevx[4];
jennabarton 12:e127fa20d609 48 int prevy[4];
jennabarton 12:e127fa20d609 49
jennabarton 12:e127fa20d609 50 //movement
jennabarton 12:e127fa20d609 51 int deadzone = 5;
jennabarton 12:e127fa20d609 52
jennabarton 12:e127fa20d609 53 //counts for clicks
jennabarton 12:e127fa20d609 54 int clickDeadzone = 10;
jennabarton 12:e127fa20d609 55 int fingerDownCount = 0;
jennabarton 12:e127fa20d609 56 int fingerUpCount = 0;
jennabarton 12:e127fa20d609 57 int minLeftClickDur = 4;
jennabarton 12:e127fa20d609 58 int minRightClickDur = 10;
jennabarton 12:e127fa20d609 59 int delayForClick = 2;
jennabarton 12:e127fa20d609 60 int instabilityLimit = 3;
jennabarton 12:e127fa20d609 61 int instabilityCount = 0;
jennabarton 8:d27efcac2dd7 62 //******************************************************************
jennabarton 8:d27efcac2dd7 63 // All methods defined below
jennabarton 8:d27efcac2dd7 64 //******************************************************************
daviwang 1:2e895e5272ab 65
jennabarton 12:e127fa20d609 66 //takes in values for the movement in the x and y direction
jennabarton 12:e127fa20d609 67 //also can indicate whether you want to "click"
jennabarton 12:e127fa20d609 68 //NOTE: hard coded wait of 0.1
jennabarton 10:d67a15ba5748 69 void mouseCommand(char buttons, char x, char y) {
jennabarton 10:d67a15ba5748 70 keyOut.putc(0xFD);
jennabarton 10:d67a15ba5748 71 keyOut.putc(0x00);
jennabarton 10:d67a15ba5748 72 keyOut.putc(0x03);
jennabarton 10:d67a15ba5748 73 keyOut.putc(buttons);
jennabarton 10:d67a15ba5748 74 keyOut.putc(x);
jennabarton 10:d67a15ba5748 75 keyOut.putc(y);
jennabarton 10:d67a15ba5748 76 keyOut.putc(0x00);
jennabarton 10:d67a15ba5748 77 keyOut.putc(0x00);
jennabarton 10:d67a15ba5748 78 keyOut.putc(0x00);
jennabarton 10:d67a15ba5748 79
jennabarton 10:d67a15ba5748 80 //delay for pushing data
jennabarton 12:e127fa20d609 81 wait(0.1); //how large does this need to be?
jennabarton 10:d67a15ba5748 82 }
jennabarton 10:d67a15ba5748 83
jennabarton 4:1f443e7a0122 84
jennabarton 12:e127fa20d609 85 //moves mouse on screen from one finger input
jennabarton 12:e127fa20d609 86 //param
jennabarton 12:e127fa20d609 87 // current point (currx, curry)
jennabarton 12:e127fa20d609 88 // previous point (prevx, prevy)
jennabarton 12:e127fa20d609 89 void oneFingerResponse(int currx, int curry, int prevx, int prevy){
jennabarton 12:e127fa20d609 90 //look at delta btwn prev val and current
jennabarton 12:e127fa20d609 91 //TODO: moving average
jennabarton 12:e127fa20d609 92 if((prevx != 1023 || prevy != 1023) && (currx != 1023 && curry != 1023)){
jennabarton 12:e127fa20d609 93 int diffX = currx - prevx;
jennabarton 12:e127fa20d609 94 int diffY = -1*(curry - prevy);
jennabarton 12:e127fa20d609 95
jennabarton 12:e127fa20d609 96 //fix diffX
jennabarton 12:e127fa20d609 97 if(diffX > deadzone){
jennabarton 12:e127fa20d609 98 diffX -= deadzone;
jennabarton 12:e127fa20d609 99 } else if (diffX < -1*deadzone){
jennabarton 12:e127fa20d609 100 diffX += deadzone;
jennabarton 12:e127fa20d609 101 } else{
jennabarton 12:e127fa20d609 102 diffX = 0;
jennabarton 12:e127fa20d609 103 }
jennabarton 12:e127fa20d609 104 //fix diffY
jennabarton 12:e127fa20d609 105 if(diffY > deadzone){
jennabarton 12:e127fa20d609 106 diffY -= deadzone;
jennabarton 12:e127fa20d609 107 } else if (diffX < -1*deadzone){
jennabarton 12:e127fa20d609 108 diffY += deadzone;
jennabarton 12:e127fa20d609 109 } else{
jennabarton 12:e127fa20d609 110 diffY = 0;
jennabarton 12:e127fa20d609 111 }
jennabarton 12:e127fa20d609 112
jennabarton 12:e127fa20d609 113 //move x and y
jennabarton 12:e127fa20d609 114 mouseCommand(0, (char) diffX, (char) diffY);
jennabarton 12:e127fa20d609 115 }
jennabarton 12:e127fa20d609 116 }
jennabarton 12:e127fa20d609 117
jennabarton 12:e127fa20d609 118
jennabarton 12:e127fa20d609 119 //writes two bytes to the camera
jennabarton 12:e127fa20d609 120 void write2bytes(char data1, char data2){
jennabarton 12:e127fa20d609 121 char out[2];
jennabarton 12:e127fa20d609 122 out[0] = data1;
jennabarton 12:e127fa20d609 123 out[1] = data2;
jennabarton 12:e127fa20d609 124 camera1.write(slaveAddress, out, 2);
jennabarton 12:e127fa20d609 125 wait(0.01);
jennabarton 12:e127fa20d609 126 }
jennabarton 12:e127fa20d609 127
jennabarton 12:e127fa20d609 128
jennabarton 12:e127fa20d609 129
jennabarton 8:d27efcac2dd7 130 // Initialize WiiMote Camera
daviwang 1:2e895e5272ab 131 void initCamera(void){
daviwang 1:2e895e5272ab 132 write2bytes(0x30, 0x01);
daviwang 1:2e895e5272ab 133 write2bytes(0x00, 0x02);
daviwang 1:2e895e5272ab 134 write2bytes(0x00, 0x00);
daviwang 1:2e895e5272ab 135 write2bytes(0x71, 0x01);
daviwang 1:2e895e5272ab 136 write2bytes(0x00, sen0);
daviwang 1:2e895e5272ab 137 write2bytes(0x07, 0x00);
daviwang 1:2e895e5272ab 138 write2bytes(sen1, 0x1A);
daviwang 1:2e895e5272ab 139 write2bytes(sen2, sen3);
daviwang 1:2e895e5272ab 140 write2bytes(0x33, 0x03);
daviwang 1:2e895e5272ab 141 write2bytes(0x30, 0x08);
jennabarton 3:7b0c215eb6a7 142 //wait(0.1);
daviwang 1:2e895e5272ab 143
daviwang 1:2e895e5272ab 144 }
daviwang 0:1c15cf9cc4f9 145
jennabarton 12:e127fa20d609 146
jennabarton 12:e127fa20d609 147 //update counts for click
jennabarton 12:e127fa20d609 148 void updateClickState(int currx, int curry, int prevx, int prevy){
jennabarton 12:e127fa20d609 149 bool xStable = false;
jennabarton 12:e127fa20d609 150 bool yStable = false;
jennabarton 12:e127fa20d609 151
jennabarton 12:e127fa20d609 152 //TODO: update to handle cases where just one is 1023
jennabarton 12:e127fa20d609 153 if(currx != 1023 || curry != 1023){
jennabarton 12:e127fa20d609 154 //check x stability
jennabarton 12:e127fa20d609 155 if( currx > prevx ){
jennabarton 12:e127fa20d609 156 if(currx-prevx < clickDeadzone){
jennabarton 12:e127fa20d609 157 //barely moved in x dir
jennabarton 12:e127fa20d609 158 xStable = true;
jennabarton 12:e127fa20d609 159 }
jennabarton 12:e127fa20d609 160 } else if( currx < prevx) {
jennabarton 12:e127fa20d609 161 if(prevx-currx < clickDeadzone){
jennabarton 12:e127fa20d609 162 //barely moved in x dir
jennabarton 12:e127fa20d609 163 xStable = true;
jennabarton 12:e127fa20d609 164 }
jennabarton 12:e127fa20d609 165 } else {
jennabarton 12:e127fa20d609 166 //no movement in x
jennabarton 12:e127fa20d609 167 xStable = true;
jennabarton 12:e127fa20d609 168 }
jennabarton 12:e127fa20d609 169
jennabarton 12:e127fa20d609 170 //check y stability
jennabarton 12:e127fa20d609 171 if( curry > prevy ){
jennabarton 12:e127fa20d609 172 if(curry-prevy < clickDeadzone){
jennabarton 12:e127fa20d609 173 //barely moved in y dir
jennabarton 12:e127fa20d609 174 yStable = true;
jennabarton 12:e127fa20d609 175 }
jennabarton 12:e127fa20d609 176 } else if( curry < prevy) {
jennabarton 12:e127fa20d609 177 if(prevy-curry < clickDeadzone){
jennabarton 12:e127fa20d609 178 //barely moved in y dir
jennabarton 12:e127fa20d609 179 yStable = true;
jennabarton 12:e127fa20d609 180 }
jennabarton 12:e127fa20d609 181 } else {
jennabarton 12:e127fa20d609 182 //no movement in y
jennabarton 12:e127fa20d609 183 yStable = true;
jennabarton 12:e127fa20d609 184 }
jennabarton 12:e127fa20d609 185
jennabarton 12:e127fa20d609 186 //update finger down count
jennabarton 12:e127fa20d609 187 if(xStable && yStable){
jennabarton 12:e127fa20d609 188 //both are stable
jennabarton 12:e127fa20d609 189 fingerDownCount++;
jennabarton 12:e127fa20d609 190 //pc.printf("finger down \t");
jennabarton 12:e127fa20d609 191
jennabarton 12:e127fa20d609 192 } else{
jennabarton 12:e127fa20d609 193 //unstable, increase instability count
jennabarton 12:e127fa20d609 194 instabilityCount++;
jennabarton 12:e127fa20d609 195 if(instabilityCount > instabilityLimit){
jennabarton 12:e127fa20d609 196 //too many instable points, reset to zero
jennabarton 12:e127fa20d609 197 fingerDownCount = 0;
jennabarton 12:e127fa20d609 198 instabilityCount = 0;
jennabarton 12:e127fa20d609 199 }
jennabarton 12:e127fa20d609 200 }
jennabarton 12:e127fa20d609 201
jennabarton 12:e127fa20d609 202 } else {
jennabarton 12:e127fa20d609 203 //both are up, increment up count
jennabarton 12:e127fa20d609 204 fingerUpCount++;
jennabarton 12:e127fa20d609 205 if(fingerUpCount >= delayForClick && fingerDownCount >= minLeftClickDur){
jennabarton 12:e127fa20d609 206 //finger was down for long enough to be a click
jennabarton 12:e127fa20d609 207 //finger was lifted for long enough to indicate click
jennabarton 12:e127fa20d609 208 if(fingerDownCount >= minRightClickDur){
jennabarton 12:e127fa20d609 209 //initiate right click
jennabarton 12:e127fa20d609 210 mouseCommand(0x02, 0 , 0);
jennabarton 12:e127fa20d609 211
jennabarton 12:e127fa20d609 212 //TODO: remove. for debugging purposes only
jennabarton 12:e127fa20d609 213 pc.printf("#########RIGHT mouse click \t");
jennabarton 12:e127fa20d609 214 } else {
jennabarton 12:e127fa20d609 215 //initiate left click
jennabarton 12:e127fa20d609 216 mouseCommand(0x01, 0 , 0);
jennabarton 12:e127fa20d609 217
jennabarton 12:e127fa20d609 218 //TODO: remove. for debugging purposes only
jennabarton 12:e127fa20d609 219 pc.printf("********LEFT mouse click \t");
jennabarton 12:e127fa20d609 220 }
jennabarton 12:e127fa20d609 221
jennabarton 12:e127fa20d609 222 //reset counters
jennabarton 12:e127fa20d609 223 fingerUpCount = 0;
jennabarton 12:e127fa20d609 224 fingerDownCount = 0;
jennabarton 12:e127fa20d609 225
jennabarton 12:e127fa20d609 226 }
jennabarton 12:e127fa20d609 227 }
jennabarton 12:e127fa20d609 228
jennabarton 12:e127fa20d609 229
jennabarton 12:e127fa20d609 230 }
jennabarton 12:e127fa20d609 231
jennabarton 12:e127fa20d609 232
jennabarton 8:d27efcac2dd7 233 //get data from camera one
jennabarton 8:d27efcac2dd7 234 //populates onex and oney with values depending on the measured points
jennabarton 8:d27efcac2dd7 235 //NOTE: 1023 means nothing was detected
jennabarton 2:f501e506d62b 236 void readCameraData(void){
jennabarton 2:f501e506d62b 237
jennabarton 2:f501e506d62b 238 //request data from camera
jennabarton 2:f501e506d62b 239 char out[1];
jennabarton 2:f501e506d62b 240 out[0] = 0x36;
jennabarton 2:f501e506d62b 241 camera1.write(slaveAddress, out, 1);
jennabarton 2:f501e506d62b 242 //wait(0.2); //do we need this?
jennabarton 2:f501e506d62b 243
jennabarton 2:f501e506d62b 244 //get data from camera
jennabarton 2:f501e506d62b 245 camera1.read(slaveAddress, data_buf, 16);
jennabarton 8:d27efcac2dd7 246
jennabarton 2:f501e506d62b 247 //POINT 1
jennabarton 2:f501e506d62b 248 //get data
jennabarton 2:f501e506d62b 249 point1x = data_buf[1];
jennabarton 2:f501e506d62b 250 point1y = data_buf[2];
jennabarton 2:f501e506d62b 251 s = data_buf[3];
jennabarton 3:7b0c215eb6a7 252 //load x,y
jennabarton 3:7b0c215eb6a7 253 onex[0] = point1x + ((s & 0x30) << 4);
jennabarton 3:7b0c215eb6a7 254 oney[0] = point1y + ((s & 0xC0) << 2);
jennabarton 2:f501e506d62b 255
jennabarton 8:d27efcac2dd7 256
jennabarton 11:cd450ce343a8 257 //>>>>>>>>>>>>>>>>>Begin unfinished code for moving
jennabarton 11:cd450ce343a8 258
jennabarton 12:e127fa20d609 259 oneFingerResponse(onex[0], oney[0], prevX, prevY);
jennabarton 12:e127fa20d609 260 updateClickState(onex[0], oney[0], prevX, prevY);
jennabarton 11:cd450ce343a8 261
jennabarton 7:6b27977d1800 262
jennabarton 7:6b27977d1800 263 //update prev values
jennabarton 7:6b27977d1800 264 prevX = onex[0];
jennabarton 7:6b27977d1800 265 prevY = oney[0];
jennabarton 7:6b27977d1800 266
jennabarton 7:6b27977d1800 267
jennabarton 8:d27efcac2dd7 268 //<<<<<<<<<<<<<<<<End unfinished code for moving averages
jennabarton 8:d27efcac2dd7 269
jennabarton 2:f501e506d62b 270 //POINT 2
jennabarton 2:f501e506d62b 271 //get data
jennabarton 2:f501e506d62b 272 point2x = data_buf[4];
jennabarton 2:f501e506d62b 273 point2y = data_buf[5];
jennabarton 2:f501e506d62b 274 s = data_buf[6];
jennabarton 2:f501e506d62b 275 //load x,y
jennabarton 2:f501e506d62b 276 onex[1] = point2x + ((s & 0x30) << 4);
jennabarton 2:f501e506d62b 277 oney[1] = point2y + ((s & 0xC0) << 2);
jennabarton 3:7b0c215eb6a7 278
jennabarton 2:f501e506d62b 279 //POINT 3
jennabarton 2:f501e506d62b 280 //get data
jennabarton 2:f501e506d62b 281 point3x = data_buf[7];
jennabarton 2:f501e506d62b 282 point3y = data_buf[8];
jennabarton 2:f501e506d62b 283 s = data_buf[9];
jennabarton 2:f501e506d62b 284 //load x,y
jennabarton 2:f501e506d62b 285 onex[2] = point3x + ((s & 0x30) << 4);
jennabarton 2:f501e506d62b 286 oney[2] = point3y + ((s & 0xC0) << 2);
jennabarton 2:f501e506d62b 287
jennabarton 2:f501e506d62b 288 //POINT 4
jennabarton 2:f501e506d62b 289 //get data
jennabarton 2:f501e506d62b 290 point4x = data_buf[10];
jennabarton 2:f501e506d62b 291 point4y = data_buf[11];
jennabarton 2:f501e506d62b 292 s = data_buf[12];
jennabarton 2:f501e506d62b 293 //load x,y
jennabarton 2:f501e506d62b 294 onex[3] = point4x + ((s & 0x30) << 4);
jennabarton 2:f501e506d62b 295 oney[3] = point4y + ((s & 0xC0) << 2);
jennabarton 2:f501e506d62b 296
jennabarton 2:f501e506d62b 297 }
jennabarton 2:f501e506d62b 298
jennabarton 8:d27efcac2dd7 299 //print to serial monitor the coordinates of the points stored in
jennabarton 8:d27efcac2dd7 300 //the passed x and y arrays
jennabarton 2:f501e506d62b 301 void printCamData(int xcor[4], int ycor[4]){
jennabarton 2:f501e506d62b 302 for(int i = 0; i<4; i++){
jennabarton 2:f501e506d62b 303 int x = xcor[i];
jennabarton 2:f501e506d62b 304 int y = ycor[i];
jennabarton 2:f501e506d62b 305 //determine what to print
jennabarton 2:f501e506d62b 306 //x coordinate
jennabarton 3:7b0c215eb6a7 307 pc.printf(" %d,", x);
jennabarton 2:f501e506d62b 308
jennabarton 2:f501e506d62b 309 //y coordinate
jennabarton 8:d27efcac2dd7 310 pc.printf(" %d\t", y);
jennabarton 2:f501e506d62b 311 }
jennabarton 2:f501e506d62b 312
jennabarton 2:f501e506d62b 313 //new line and delay
jennabarton 2:f501e506d62b 314 pc.printf("\n");
jennabarton 3:7b0c215eb6a7 315 //wait(0.01);
jennabarton 2:f501e506d62b 316 }
jennabarton 2:f501e506d62b 317
jennabarton 4:1f443e7a0122 318
jennabarton 4:1f443e7a0122 319
jennabarton 4:1f443e7a0122 320
jennabarton 8:d27efcac2dd7 321 //entrance to the code
daviwang 0:1c15cf9cc4f9 322 int main() {
daviwang 1:2e895e5272ab 323 myled = 0;
jennabarton 3:7b0c215eb6a7 324 //slaveAddress = IRsensorAddress >> 1;
jennabarton 3:7b0c215eb6a7 325 slaveAddress = IRsensorAddress;
daviwang 1:2e895e5272ab 326 initCamera();
daviwang 1:2e895e5272ab 327
jennabarton 3:7b0c215eb6a7 328 //update baud rate
jennabarton 3:7b0c215eb6a7 329 pc.baud(115200);
jennabarton 3:7b0c215eb6a7 330
jennabarton 8:d27efcac2dd7 331 //loop to search for new info using the camera
daviwang 0:1c15cf9cc4f9 332 while(1) {
jennabarton 8:d27efcac2dd7 333
jennabarton 8:d27efcac2dd7 334 //wait
jennabarton 12:e127fa20d609 335 //wait(0.04);
jennabarton 8:d27efcac2dd7 336
jennabarton 8:d27efcac2dd7 337 //toggle test LED
jennabarton 2:f501e506d62b 338 myled = 1 - myled;
jennabarton 2:f501e506d62b 339
jennabarton 2:f501e506d62b 340 //get the camera data
jennabarton 2:f501e506d62b 341 readCameraData();
daviwang 1:2e895e5272ab 342
jennabarton 2:f501e506d62b 343 //print points
jennabarton 3:7b0c215eb6a7 344 printCamData(onex, oney);
daviwang 1:2e895e5272ab 345
jennabarton 8:d27efcac2dd7 346 //uncomment below to test infinite print
jennabarton 6:4ade0e1a3723 347 //keyOut.putc(0x41);
jennabarton 10:d67a15ba5748 348
jennabarton 4:1f443e7a0122 349
jennabarton 12:e127fa20d609 350 //uncomment below to infinitely move mouse in a square
jennabarton 10:d67a15ba5748 351 // double delay = 0.1;
jennabarton 10:d67a15ba5748 352 // int change = 75;
jennabarton 10:d67a15ba5748 353 // mouseCommand(0,0, (char) -1*change);
jennabarton 10:d67a15ba5748 354 // wait(delay);
jennabarton 10:d67a15ba5748 355 // mouseCommand(0,(char) -1*change,0);
jennabarton 10:d67a15ba5748 356 // wait(delay);
jennabarton 10:d67a15ba5748 357 // mouseCommand(0,0, (char) change);
jennabarton 10:d67a15ba5748 358 // wait(delay);
jennabarton 10:d67a15ba5748 359 // mouseCommand(0,(char) change,0);
jennabarton 10:d67a15ba5748 360 // wait(delay);
jennabarton 9:55473409c585 361
jennabarton 9:55473409c585 362
daviwang 0:1c15cf9cc4f9 363 }
daviwang 0:1c15cf9cc4f9 364 }