diff --git a/tasmota/xsns_27_apds9960.ino b/tasmota/xsns_27_apds9960.ino
index 4800a96de..e55deb276 100644
--- a/tasmota/xsns_27_apds9960.ino
+++ b/tasmota/xsns_27_apds9960.ino
@@ -61,6 +61,8 @@
#define APDS9930_CHIPID_1 0x12 // we will check, if someone got an incorrect sensor
#define APDS9930_CHIPID_2 0x39 // there are case reports about "accidentially bought" 9930's
+#define APDS9960_GESTURE // Enable Gesture feature(2k on flash)
+
/* Gesture parameters */
#define GESTURE_THRESHOLD_OUT 10
#define GESTURE_SENSITIVITY_1 50
@@ -72,13 +74,26 @@
const char APDS9960_TAG[] = "APDS9960";
#ifdef USE_WEBSERVER
-const char HTTP_APDS9960_SNS[] PROGMEM =
- "{s}" "Red" "{m}%s{e}"
- "{s}" "Green" "{m}%s{e}"
- "{s}" "Blue" "{m}%s{e}"
- "{s}" "Ambient" "{m}%s " D_UNIT_LUX "{e}"
- "{s}" "CCT" "{m}%s " "K" "{e}" // calculated color temperature in Kelvin
- "{s}" "Proximity" "{m}%s{e}"; // {s} =
, {m} = | , {e} = |
+#ifdef APDS9960_GESTURE
+
+#define D_GESTURE "Gesture"
+
+const char HTTP_SNS_GESTURE[] PROGMEM = "{s}%s " D_GESTURE "{m}%s{e}";
+
+#endif // APDS9960_GESTURE
+
+#define D_COLOR_RED "Red"
+#define D_COLOR_GREEN "Green"
+#define D_COLOR_BLUE "Blue"
+#define D_CCT "CCT"
+#define D_PROXIMITY "Proximity"
+
+const char HTTP_SNS_COLOR_RED[] PROGMEM = "{s}%s " D_COLOR_RED "{m}%u{e}";
+const char HTTP_SNS_COLOR_GREEN[] PROGMEM = "{s}%s " D_COLOR_GREEN "{m}%u{e}";
+const char HTTP_SNS_COLOR_BLUE[] PROGMEM = "{s}%s " D_COLOR_BLUE "{m}%u{e}";
+const char HTTP_SNS_CCT[] PROGMEM = "{s}%s " D_CCT "{m}%u " "K" "{e}";
+const char HTTP_SNS_PROXIMITY[] PROGMEM = "{s}%s " D_PROXIMITY "{m}%u{e}";
+
#endif // USE_WEBSERVER
/*********************************************************************************************\
@@ -236,7 +251,15 @@ const char HTTP_APDS9960_SNS[] PROGMEM =
#define APDS9960_ERROR 0xFF
+#ifdef APDS9960_GESTURE
/* Direction definitions */
+const char GESTURE_UP[] PROGMEM = "Up";
+const char GESTURE_DOWN[] PROGMEM = "Down";
+const char GESTURE_LEFT[] PROGMEM = "Left";
+const char GESTURE_RIGHT[] PROGMEM = "Right";
+const char GESTURE_LONG[] PROGMEM = "Long";
+const char GESTURE_NONE[] PROGMEM = "None";
+
enum {
DIR_NONE,
DIR_LEFT,
@@ -249,12 +272,14 @@ enum {
};
/* State definitions*/
+/*
enum {
APDS9960_NA_STATE,
APDS9960_NEAR_STATE,
APDS9960_FAR_STATE,
APDS9960_ALL_STATE
};
+*/
/* Container for gesture data */
typedef struct gesture_data_type {
@@ -268,8 +293,7 @@ typedef struct gesture_data_type {
uint8_t out_threshold;
} gesture_data_t;
-typedef struct gesture_type
-{
+typedef struct gesture_type {
int16_t ud_delta_ = 0;
int16_t lr_delta_ = 0;
int16_t ud_count_ = 0;
@@ -278,6 +302,8 @@ typedef struct gesture_type
int16_t motion_ = DIR_NONE;
} gesture_t;
+#endif // APDS9960_GESTURE
+
typedef struct color_data_type {
uint16_t a; // measured ambient
uint16_t r; // Red
@@ -289,8 +315,11 @@ typedef struct color_data_type {
} color_data_t;
/*Members*/
+#ifdef APDS9960_GESTURE
gesture_data_t gesture_data;
gesture_t gesture;
+#endif // APDS9960_GESTURE
+
color_data_t color_data;
volatile uint8_t recovery_loop_counter = 0; // count number of stateloops to switch the sensor off, if needed
@@ -721,6 +750,8 @@ void setProxPhotoMask(uint8_t mask) {
I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG3, val);
}
+#ifdef APDS9960_GESTURE
+
/**
* @brief Gets the entry proximity threshold for gesture sensing
*
@@ -924,6 +955,8 @@ void setGestureWaitTime(uint8_t time) {
I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF2, val);
}
+#endif // APDS9960_GESTURE
+
/**
* @brief Gets the low threshold for ambient light interrupts
*
@@ -1238,6 +1271,8 @@ bool APDS9960_init(void) {
I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG3, DEFAULT_CONFIG3);
/* Set default values for gesture sense registers */
+#ifdef APDS9960_GESTURE
+
setGestureEnterThresh(DEFAULT_GPENTH);
setGestureExitThresh(DEFAULT_GEXTH);
@@ -1255,6 +1290,8 @@ bool APDS9960_init(void) {
I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF3, DEFAULT_GCONF3);
setGestureIntEnable(DEFAULT_GIEN);
+
+#endif // APDS9960_GESTURE
disablePower(); // go to sleep
@@ -1357,6 +1394,7 @@ void disableProximitySensor(void) {
setMode(PROXIMITY, OFF);
}
+#ifdef APDS9960_GESTURE
/**
* @brief Starts the gesture recognition engine on the APDS-9960
*
@@ -1451,7 +1489,7 @@ int16_t readGesture(void) {
fifo_level = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GFLVL);
#ifdef USE_DEBUG_DRIVER
- AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DRV: FIFO Level : %d"), fifo_level);
+ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DRV: FIFO Level : %d"), fifo_level);
#endif // USE_DEBUG_DRIVER
/* If there's stuff in the FIFO, read it into our data block */
@@ -1504,6 +1542,8 @@ int16_t readGesture(void) {
}
}
+#endif // APDS9960_GESTURE
+
/**
* Turn the APDS-9960 on
*
@@ -1540,6 +1580,8 @@ void readAllColorAndProximityData(void) {
* High-level gesture controls
\******************************************************************************/
+#ifdef APDS9960_GESTURE
+
/**
* @brief Resets all the parameters in the gesture data member
*/
@@ -1705,28 +1747,28 @@ void handleGesture(void) {
if (isGestureAvailable()) {
switch (readGesture()) {
case DIR_UP:
- AddLog_P(LOG_LEVEL_DEBUG, PSTR("UP"));
- snprintf_P(currentGesture, sizeof(currentGesture), PSTR("Up"));
+ AddLog_P(LOG_LEVEL_DEBUG, GESTURE_UP);
+ snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_UP);
break;
case DIR_DOWN:
- AddLog_P(LOG_LEVEL_DEBUG, PSTR("DOWN"));
- snprintf_P(currentGesture, sizeof(currentGesture), PSTR("Down"));
+ AddLog_P(LOG_LEVEL_DEBUG, GESTURE_DOWN);
+ snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_DOWN);
break;
case DIR_LEFT:
- AddLog_P(LOG_LEVEL_DEBUG, PSTR("LEFT"));
- snprintf_P(currentGesture, sizeof(currentGesture), PSTR("Left"));
+ AddLog_P(LOG_LEVEL_DEBUG, GESTURE_LEFT);
+ snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_LEFT);
break;
case DIR_RIGHT:
- AddLog_P(LOG_LEVEL_DEBUG, PSTR("RIGHT"));
- snprintf_P(currentGesture, sizeof(currentGesture), PSTR("Right"));
+ AddLog_P(LOG_LEVEL_DEBUG, GESTURE_RIGHT);
+ snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_RIGHT);
break;
default:
if (APDS9960_overload) {
- AddLog_P(LOG_LEVEL_DEBUG, PSTR("LONG"));
- snprintf_P(currentGesture, sizeof(currentGesture), PSTR("Long"));
+ AddLog_P(LOG_LEVEL_DEBUG, GESTURE_LONG);
+ snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_LONG);
} else {
- AddLog_P(LOG_LEVEL_DEBUG, PSTR("NONE"));
- snprintf_P(currentGesture, sizeof(currentGesture), PSTR("None"));
+ AddLog_P(LOG_LEVEL_DEBUG, GESTURE_NONE);
+ snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_NONE);
}
break;
}
@@ -1734,6 +1776,8 @@ void handleGesture(void) {
}
}
+#endif // APDS9960_GESTURE
+
void APDS9960_adjustATime(void) { // not really used atm
// readAllColorAndProximityData();
I2cValidRead16LE(&color_data.a, APDS9960_I2C_ADDR, APDS9960_CDATAL);
@@ -1766,6 +1810,8 @@ void APDS9960_adjustATime(void) { // not really used atm
delay(20);
}
+#ifdef APDS9960_GESTURE
+
void APDS9960_loop(void) {
if (recovery_loop_counter > 0) {
recovery_loop_counter -= 1;
@@ -1794,6 +1840,8 @@ void APDS9960_loop(void) {
}
}
+#endif // APDS9960_GESTURE
+
void APDS9960_detect(void) {
if (APDS9960type || I2cActive(APDS9960_I2C_ADDR)) { return; }
@@ -1809,7 +1857,9 @@ void APDS9960_detect(void) {
I2cSetActiveFound(APDS9960_I2C_ADDR, APDS9960_TAG);
enableProximitySensor();
+#ifdef APDS9960_GESTURE
enableGestureSensor();
+#endif // APDS9960_GESTURE
} else {
APDS9960type = 0;
}
@@ -1828,41 +1878,48 @@ void APDS9960_show(bool json) {
if (!APDS9960type) { return; }
if (!gesture_mode && !APDS9960_overload) {
- char red_chr[10];
- char green_chr[10];
- char blue_chr[10];
- char ambient_chr[10];
- char cct_chr[10];
- char prox_chr[10];
+ uint16_t ambient;
readAllColorAndProximityData();
-
- sprintf(ambient_chr, "%u", color_data.a/4);
- sprintf(red_chr, "%u", color_data.r);
- sprintf(green_chr, "%u", color_data.g);
- sprintf(blue_chr, "%u", color_data.b);
- sprintf(prox_chr, "%u", color_data.p);
+ ambient = color_data.a/4;
/* disableLightSensor();
I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ATIME, DEFAULT_ATIME); // reset to default
enableLightSensor();*/
calculateColorTemperature(); // and calculate Lux
- sprintf(cct_chr, "%u", color_data.cct);
-
if (json) {
- ResponseAppend_P(PSTR(",\"%s\":{\"Red\":%s,\"Green\":%s,\"Blue\":%s,\"Ambient\":%s,\"CCT\":%s,\"Proximity\":%s}"),
- APDS9960_TAG, red_chr, green_chr, blue_chr, ambient_chr, cct_chr, prox_chr);
+ ResponseAppend_P(PSTR(",\"%s\":{\"Red\":%u,\"Green\":%u,\"Blue\":%u,\"Ambient\":%u,\"CCT\":%u,\"Proximity\":%u}"),
+ APDS9960_TAG,
+ color_data.r,
+ color_data.g,
+ color_data.b,
+ ambient,
+ color_data.cct,
+ color_data.p);
#ifdef USE_WEBSERVER
} else {
- WSContentSend_PD(HTTP_APDS9960_SNS, red_chr, green_chr, blue_chr, ambient_chr, cct_chr, prox_chr);
+ WSContentSend_PD(HTTP_SNS_COLOR_RED, APDS9960_TAG, color_data.r);
+ WSContentSend_PD(HTTP_SNS_COLOR_GREEN, APDS9960_TAG, color_data.g);
+ WSContentSend_PD(HTTP_SNS_COLOR_BLUE, APDS9960_TAG, color_data.b);
+ WSContentSend_PD(HTTP_SNS_ILLUMINANCE, APDS9960_TAG, ambient);
+ WSContentSend_PD(HTTP_SNS_CCT, APDS9960_TAG, color_data.cct);
+ WSContentSend_PD(HTTP_SNS_PROXIMITY, APDS9960_TAG, color_data.p);
#endif // USE_WEBSERVER
}
+#ifdef APDS9960_GESTURE
} else {
- if (json && (currentGesture[0] != '\0' )) {
- ResponseAppend_P(PSTR(",\"%s\":{\"%s\":1}"), APDS9960_TAG, currentGesture);
- currentGesture[0] = '\0';
+ if (currentGesture[0] != '\0') {
+ if (json) {
+ ResponseAppend_P(PSTR(",\"%s\":{\"%s\":1}"), APDS9960_TAG, currentGesture);
+#ifdef USE_WEBSERVER
+ } else {
+ WSContentSend_PD(HTTP_SNS_GESTURE, APDS9960_TAG, currentGesture);
+#endif // USE_WEBSERVER
+ currentGesture[0] = '\0';
+ }
}
+#endif // APDS9960_GESTURE
}
}
@@ -1882,11 +1939,14 @@ bool APDS9960CommandSensor(void) {
switch (XdrvMailbox.payload) {
case 0: // Off
+#ifdef APDS9960_GESTURE
disableGestureSensor();
+#endif // APDS9960_GESTURE
gesture_mode = 0;
enableLightSensor();
APDS9960_overload = false; // prevent unwanted re-enabling
break;
+#ifdef APDS9960_GESTURE
case 1: // On with default gain of 4x
if (APDS9960type) {
setGestureGain(DEFAULT_GGAIN);
@@ -1905,6 +1965,7 @@ bool APDS9960CommandSensor(void) {
gesture_mode = 1;
}
break;
+#endif // APDS9960_GESTURE
default:
int temp_aTime = (uint8_t)XdrvMailbox.payload;
if (temp_aTime > 2 && temp_aTime < 256) {
@@ -1933,9 +1994,11 @@ bool Xsns27(uint8_t function) {
APDS9960_detect();
} else if (APDS9960type) {
switch (function) {
+#ifdef APDS9960_GESTURE
case FUNC_EVERY_50_MSECOND:
APDS9960_loop();
break;
+#endif // APDS9960_GESTURE
case FUNC_COMMAND_SENSOR:
if (XSNS_27 == XdrvMailbox.index) {
result = APDS9960CommandSensor();