350 lines
6.5 KiB
C++
350 lines
6.5 KiB
C++
|
/* ===========================================================================
|
||
|
# This is the library for Hover.
|
||
|
#
|
||
|
# Hover is a development kit that lets you control your hardware projects in a whole new way.
|
||
|
# Wave goodbye to physical buttons. Hover detects hand movements in the air for touch-less interaction.
|
||
|
# It also features five touch-sensitive regions for even more options.
|
||
|
# Hover uses I2C and 2 digital pins. It is compatible with Arduino, Raspberry Pi and more.
|
||
|
#
|
||
|
# Hover can be purchased here: http://www.hoverlabs.co
|
||
|
#
|
||
|
# Written by Emran Mahbub and Jonathan Li for Hover Labs.
|
||
|
# BSD license, all text above must be included in any redistribution
|
||
|
# ===========================================================================
|
||
|
#
|
||
|
# INSTALLATION
|
||
|
# The 3 library files (Hover.cpp, Hover.h and keywords.txt) in the Hover folder should be placed in your Arduino Library folder.
|
||
|
# Run the HoverDemo.ino file from your Arduino IDE.
|
||
|
#
|
||
|
# SUPPORT
|
||
|
# For questions and comments, email us at support@hoverlabs.co
|
||
|
# v3.0
|
||
|
# ===========================================================================*/
|
||
|
|
||
|
#include "Hover.h"
|
||
|
#include <Wire.h>
|
||
|
|
||
|
#define WIRE Wire
|
||
|
|
||
|
Hover::Hover(uint8_t ts, uint8_t rst, uint8_t gestmode, uint8_t touchmode, uint8_t tapmode, uint8_t posmode) {
|
||
|
_i2caddr = 0x42;
|
||
|
_ts = ts;
|
||
|
_rst = rst;
|
||
|
_gestmode = gestmode;
|
||
|
_touchmode = touchmode;
|
||
|
_tapmode = tapmode;
|
||
|
_posmode = posmode;
|
||
|
}
|
||
|
|
||
|
void Hover::begin() {
|
||
|
WIRE.begin();
|
||
|
pinMode(_ts, INPUT);
|
||
|
pinMode(_rst, OUTPUT);
|
||
|
digitalWrite(_rst, LOW);
|
||
|
pinMode(_rst, INPUT);
|
||
|
//delay(3000);
|
||
|
Serial.println("Hover is ready");
|
||
|
}
|
||
|
|
||
|
void Hover::setRelease() {
|
||
|
digitalWrite(_ts, HIGH);
|
||
|
pinMode(_ts, INPUT);
|
||
|
}
|
||
|
|
||
|
boolean Hover::getStatus() {
|
||
|
if (digitalRead(_ts) == 0) {
|
||
|
pinMode(_ts, OUTPUT);
|
||
|
digitalWrite(_ts, LOW);
|
||
|
return 0;
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
void Hover::readI2CData(void) {
|
||
|
if (getStatus() == 0){
|
||
|
int c = 0;
|
||
|
WIRE.requestFrom((uint8_t)_i2caddr, (uint8_t)26); // request 26 bytes from slave device at 0x42
|
||
|
while(WIRE.available()) // slave may send less than requested
|
||
|
{
|
||
|
_dat[c] = WIRE.read(); // receive a byte as character
|
||
|
c++;
|
||
|
}
|
||
|
setRelease();
|
||
|
_valid = 1;
|
||
|
delay(6);
|
||
|
} else {
|
||
|
_valid = 0;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
Gesture::Gesture(){
|
||
|
strcpy(gestureType, "none");
|
||
|
gestureID = 0;
|
||
|
gestureValue = 0;
|
||
|
}
|
||
|
|
||
|
Gesture::Gesture (char * type, uint8_t id, uint8_t value){
|
||
|
strcpy(gestureType, type);
|
||
|
gestureID = id;
|
||
|
gestureValue = value;
|
||
|
}
|
||
|
|
||
|
Gesture Hover::getGesture(void) {
|
||
|
char gtype[15];
|
||
|
uint8_t gid;
|
||
|
uint8_t gval;
|
||
|
|
||
|
if (_valid == 1 && _gestmode == 0x01) {
|
||
|
readGestureData(gtype, &gid, &gval);
|
||
|
} else {
|
||
|
strcpy(gtype, "none");
|
||
|
gid = 0x00;
|
||
|
gval = 0x00;
|
||
|
}
|
||
|
|
||
|
return Gesture(gtype, gid, gval);
|
||
|
}
|
||
|
|
||
|
void Hover::readGestureData(char * gtype, uint8_t * gid, uint8_t * gval) {
|
||
|
|
||
|
switch (_dat[10]){
|
||
|
case 2:
|
||
|
strcpy(gtype, "Right Swipe");
|
||
|
*gid = 0x01;
|
||
|
*gval = 0x01;
|
||
|
break;
|
||
|
case 3:
|
||
|
strcpy(gtype, "Left Swipe");
|
||
|
*gid = 0x01;
|
||
|
*gval = 0x02;
|
||
|
break;
|
||
|
case 4:
|
||
|
strcpy(gtype, "Up Swipe");
|
||
|
*gid = 0x01;
|
||
|
*gval = 0x03;
|
||
|
break;
|
||
|
case 5:
|
||
|
strcpy(gtype, "Down Swipe");
|
||
|
*gid = 0x01;
|
||
|
*gval = 0x04;
|
||
|
break;
|
||
|
default:
|
||
|
strcpy(gtype, "None");
|
||
|
*gid = 0x00;
|
||
|
*gval = 0x00;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
Touch::Touch(){
|
||
|
strcpy(touchType, "none");
|
||
|
touchID = 0;
|
||
|
touchValue = 0;
|
||
|
}
|
||
|
|
||
|
Touch::Touch (char * type, uint8_t id, uint8_t value){
|
||
|
strcpy(touchType, type);
|
||
|
touchID = id;
|
||
|
touchValue = value;
|
||
|
}
|
||
|
|
||
|
Touch Hover::getTouch(void) {
|
||
|
char ttype[20];
|
||
|
uint8_t tid;
|
||
|
uint8_t tval;
|
||
|
|
||
|
if (_valid == 1) {
|
||
|
readTouchData(ttype, &tid, &tval);
|
||
|
} else {
|
||
|
strcpy(ttype, "None");
|
||
|
tid = 0x00;
|
||
|
tval = 0x00;
|
||
|
}
|
||
|
|
||
|
return Touch(ttype, tid, tval);
|
||
|
}
|
||
|
|
||
|
void Hover::readTouchData(char * ttype, uint8_t * tid, uint8_t * tval) {
|
||
|
|
||
|
uint8_t touch, tap, doubleTap;
|
||
|
|
||
|
touch = (_touchmode==0x01) ? (touch = (_dat[14] & 0x1F)) : (0);
|
||
|
|
||
|
if (_tapmode!=0x00){
|
||
|
if (_tapmode == 0x01){
|
||
|
tap = (((_dat[15] & 0x03) << 3 ) | (_dat[14]>>5));
|
||
|
doubleTap = ((_dat[15]>>2) & 0x1F);
|
||
|
} else {
|
||
|
tap = (_tapmode==0x02) ? (tap = (((_dat[15] & 0x03) << 3 ) | (_dat[14]>>5))) : (0);
|
||
|
doubleTap = (_tapmode==0x03) ? (doubleTap = ((_dat[15]>>2) & 0x1F)) : (0);
|
||
|
}
|
||
|
} else {
|
||
|
tap = 0;
|
||
|
doubleTap = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (doubleTap != 0) {
|
||
|
switch (doubleTap) {
|
||
|
case 1:
|
||
|
strcpy(ttype, "Double Tap South");
|
||
|
*tid = 0x03;
|
||
|
*tval = 0x04;
|
||
|
break;
|
||
|
case 2:
|
||
|
strcpy(ttype, "Double Tap West");
|
||
|
*tid = 0x03;
|
||
|
*tval = 0x02;
|
||
|
break;
|
||
|
case 4:
|
||
|
strcpy(ttype, "Double Tap North");
|
||
|
*tid = 0x03;
|
||
|
*tval = 0x03;
|
||
|
break;
|
||
|
case 8:
|
||
|
strcpy(ttype, "Double Tap East");
|
||
|
*tid = 0x03;
|
||
|
*tval = 0x01;
|
||
|
break;
|
||
|
case 16:
|
||
|
strcpy(ttype, "Double Tap Center");
|
||
|
*tid = 0x03;
|
||
|
*tval = 0x05;
|
||
|
break;
|
||
|
default:
|
||
|
strcpy(ttype, "None");
|
||
|
*tid = 0x00;
|
||
|
*tval = 0x00;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} else if (tap != 0) {
|
||
|
switch (tap){
|
||
|
case 1:
|
||
|
strcpy(ttype, "Tap South");
|
||
|
*tid = 0x02;
|
||
|
*tval = 0x04;
|
||
|
break;
|
||
|
case 2:
|
||
|
strcpy(ttype, "Tap West");
|
||
|
*tid = 0x02;
|
||
|
*tval = 0x02;
|
||
|
break;
|
||
|
case 4:
|
||
|
strcpy(ttype, "Tap North");
|
||
|
*tid = 0x02;
|
||
|
*tval = 0x03;
|
||
|
break;
|
||
|
case 8:
|
||
|
strcpy(ttype, "Tap East");
|
||
|
*tid = 0x02;
|
||
|
*tval = 0x01;
|
||
|
break;
|
||
|
case 16:
|
||
|
strcpy(ttype, "Tap Center");
|
||
|
*tid = 0x02;
|
||
|
*tval = 0x05;
|
||
|
break;
|
||
|
default:
|
||
|
strcpy(ttype, "None");
|
||
|
*tid = 0x00;
|
||
|
*tval = 0x00;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} else if (touch!=0) {
|
||
|
switch (touch){
|
||
|
case 1:
|
||
|
strcpy(ttype, "Touch South");
|
||
|
*tid = 0x01;
|
||
|
*tval = 0x04;
|
||
|
break;
|
||
|
case 2:
|
||
|
strcpy(ttype, "Touch West");
|
||
|
*tid = 0x01;
|
||
|
*tval = 0x02;
|
||
|
break;
|
||
|
case 4:
|
||
|
strcpy(ttype, "Touch North");
|
||
|
*tid = 0x01;
|
||
|
*tval = 0x03;
|
||
|
break;
|
||
|
case 8:
|
||
|
strcpy(ttype, "Touch East");
|
||
|
*tid = 0x01;
|
||
|
*tval = 0x01;
|
||
|
break;
|
||
|
case 16:
|
||
|
strcpy(ttype, "Touch Center");
|
||
|
*tid = 0x01;
|
||
|
*tval = 0x05;
|
||
|
break;
|
||
|
default:
|
||
|
strcpy(ttype, "None");
|
||
|
*tid = 0x00;
|
||
|
*tval = 0x00;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
strcpy(ttype, "None");
|
||
|
*tid = 0x00;
|
||
|
*tval = 0x00;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
Position::Position (uint16_t x0, uint16_t y0, uint16_t z0) {
|
||
|
x = x0;
|
||
|
y = y0;
|
||
|
z = z0;
|
||
|
}
|
||
|
|
||
|
Position Hover::getPosition(void) {
|
||
|
|
||
|
uint16_t x, y, z;
|
||
|
|
||
|
if (_valid == 1 && _posmode == 0x01) {
|
||
|
|
||
|
readPositionData(&x, &y, &z);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
x = 0;
|
||
|
y = 0;
|
||
|
z = 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
return Position(x, y, z);
|
||
|
}
|
||
|
|
||
|
void Hover::readPositionData(uint16_t *x, uint16_t *y, uint16_t *z) {
|
||
|
|
||
|
if ((_dat[7] & 0x01) == 1){
|
||
|
|
||
|
*x = ((_dat[21] << 8) | _dat[20]);
|
||
|
*y = ((_dat[23] << 8) | _dat[22]);
|
||
|
*z = ((_dat[25] << 8) | _dat[24]);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
*x = 0;
|
||
|
*y = 0;
|
||
|
*z = 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|