diff --git a/sonoff/xsns_48_chirp.ino b/sonoff/xsns_48_chirp.ino
index c54c10878..53a5e3768 100644
--- a/sonoff/xsns_48_chirp.ino
+++ b/sonoff/xsns_48_chirp.ino
@@ -1,571 +1,535 @@
/*
- xsns_48_chirp.ino - soil moisture sensor support for Sonoff-Tasmota
+ xsns_48_chirp.ino - soil moisture sensor support for Sonoff-Tasmota
- Copyright (C) 2019 Theo Arends & Christian Baars
+ Copyright (C) 2019 Theo Arends & Christian Baars
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
- --------------------------------------------------------------------------------------------
- Version Date Action Description
- --------------------------------------------------------------------------------------------
+ --------------------------------------------------------------------------------------------
+ Version Date Action Description
+ --------------------------------------------------------------------------------------------
- 1.0.0.1 20190917 changed - rework of the inner loop to enable delays in the middle of I2C-reads
- added - now really support for the (slower) CHIRP-Sensor
- ---
- 1.0.0.0 20190608 started - further development by Christian Baars - https://github.com/Staars/Sonoff-Tasmota
- forked - from arendst/tasmota - https://github.com/arendst/Sonoff-Tasmota
- base - code base from arendst and - https://github.com/Miceuz/i2c-moisture-sensor
+ 1.0.0.1 20190917 changed - rework of the inner loop to enable delays in the middle of I2C-reads
+ changed - use DEBUG_SENSOR_LOG, change ILLUMINANCE to DARKNESS
+ changed - do not publish missing temperature reads
+ added - now really support for the (slower) CHIRP-Sensor
+ ---
+ 1.0.0.0 20190608 started - further development by Christian Baars - https://github.com/Staars/Sonoff-Tasmota
+ forked - from arendst/tasmota - https://github.com/arendst/Sonoff-Tasmota
+ base - code base from arendst and - https://github.com/Miceuz/i2c-moisture-sensor
*/
-// #define USE_CHIRP
-#ifdef USE_I2C
-#ifdef USE_CHIRP
+
+#define USE_CHIRP
+#ifdef USE_I2C
+#ifdef USE_CHIRP
/*********************************************************************************************\
- * CHIRP - Soil moisture sensor
- *
- * I2C Address: 0x20 - standard address, is changeable
+ * CHIRP - Soil moisture sensor
+ *
+ * I2C Address: 0x20 - standard address, is changeable
\*********************************************************************************************/
-#define XSNS_48 48
-#define CHIRP_MAX_SENSOR_COUNT 3 // 127 is expectectd to be the max number
+#define XSNS_48 48
+#define CHIRP_MAX_SENSOR_COUNT 3 // 127 is expectectd to be the max number
-#define CHIRP_ADDR_STANDARD 0x20 // standard address
+#define CHIRP_ADDR_STANDARD 0x20 // standard address
/*********************************************************************************************\
- * constants
+ * constants
\*********************************************************************************************/
-#define D_CMND_CHIRP "CHIRP"
+#define D_CMND_CHIRP "CHIRP"
-const char S_JSON_CHIRP_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_CHIRP "%s\":%d}";
-const char S_JSON_CHIRP_COMMAND[] PROGMEM = "{\"" D_CMND_CHIRP "%s\"}";
-const char kCHIRP_Commands[] PROGMEM = "Select|Set|Scan|Reset|Sleep|Wake";
+const char S_JSON_CHIRP_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_CHIRP "%s\":%d}";
+const char S_JSON_CHIRP_COMMAND[] PROGMEM = "{\"" D_CMND_CHIRP "%s\"}";
+const char kCHIRP_Commands[] PROGMEM = "Select|Set|Scan|Reset|Sleep|Wake";
-const char kChirpTypes[] PROGMEM = "CHIRP";
+const char kChirpTypes[] PROGMEM = "CHIRP";
/*********************************************************************************************\
- * enumerations
+ * enumerations
\*********************************************************************************************/
-enum CHIRP_Commands { // commands useable in console or rules
- CMND_CHIRP_SELECT, // select active sensor by I2C address, makes only sense for multiple sensors
- CMND_CHIRP_SET, // set new I2C address for selected/active sensor, will reset
- CMND_CHIRP_SCAN, // scan the I2C bus for one or more chirp sensors
- CMND_CHIRP_RESET, // CHIRPReset, a fresh and default restart
- CMND_CHIRP_SLEEP, // put sensor to sleep
- CMND_CHIRP_WAKE }; // wake sensor by reading firmware version
+enum CHIRP_Commands { // commands useable in console or rules
+ CMND_CHIRP_SELECT, // select active sensor by I2C address, makes only sense for multiple sensors
+ CMND_CHIRP_SET, // set new I2C address for selected/active sensor, will reset
+ CMND_CHIRP_SCAN, // scan the I2C bus for one or more chirp sensors
+ CMND_CHIRP_RESET, // CHIRPReset, a fresh and default restart
+ CMND_CHIRP_SLEEP, // put sensor to sleep
+ CMND_CHIRP_WAKE }; // wake sensor by reading firmware version
/*********************************************************************************************\
- * command defines
+ * command defines
\*********************************************************************************************/
-#define CHIRP_GET_CAPACITANCE 0x00 // 16 bit, read
-#define CHIRP_SET_ADDRESS 0x01 // 8 bit, write
-#define CHIRP_GET_ADDRESS 0x02 // 8 bit, read
-#define CHIRP_MEASURE_LIGHT 0x03 // no value, write, -> initiate measurement, then wait at least 3 seconds
-#define CHIRP_GET_LIGHT 0x04 // 16 bit, read, -> higher value means darker environment, noisy data, not calibrated
-#define CHIRP_GET_TEMPERATURE 0x05 // 16 bit, read
-#define CHIRP_RESET 0x06 // no value, write
-#define CHIRP_GET_VERSION 0x07 // 8 bit, read, -> 22 means 2.2
-#define CHIRP_SLEEP 0x08 // no value, write
-#define CHIRP_GET_BUSY 0x09 // 8 bit, read, -> 1 = busy, 0 = otherwise
+#define CHIRP_GET_CAPACITANCE 0x00 // 16 bit, read
+#define CHIRP_SET_ADDRESS 0x01 // 8 bit, write
+#define CHIRP_GET_ADDRESS 0x02 // 8 bit, read
+#define CHIRP_MEASURE_LIGHT 0x03 // no value, write, -> initiate measurement, then wait at least 3 seconds
+#define CHIRP_GET_LIGHT 0x04 // 16 bit, read, -> higher value means darker environment, noisy data, not calibrated
+#define CHIRP_GET_TEMPERATURE 0x05 // 16 bit, read
+#define CHIRP_RESET 0x06 // no value, write
+#define CHIRP_GET_VERSION 0x07 // 8 bit, read, -> 22 means 2.2
+#define CHIRP_SLEEP 0x08 // no value, write
+#define CHIRP_GET_BUSY 0x09 // 8 bit, read, -> 1 = busy, 0 = otherwise
/*********************************************************************************************\
- * helper function
+ * helper function
\*********************************************************************************************/
-void ChirpWriteI2CRegister(uint8_t addr, uint8_t reg) {
- Wire.beginTransmission(addr);
- Wire.write(reg);
- Wire.endTransmission();
-} // now the original CHIRP needs 1100 ms delay
+void ChirpWriteI2CRegister(uint8_t addr, uint8_t reg) {
+ Wire.beginTransmission(addr);
+ Wire.write(reg);
+ Wire.endTransmission();
+} // now the original CHIRP needs 1100 ms delay
-uint16_t ChirpFinishReadI2CRegister16bit(uint8_t addr) {
- Wire.requestFrom(addr,(uint8_t)2);
- uint16_t t = Wire.read() << 8;
- t = t | Wire.read();
- return t;
+uint16_t ChirpFinishReadI2CRegister16bit(uint8_t addr) {
+ Wire.requestFrom(addr,(uint8_t)2);
+ uint16_t t = Wire.read() << 8;
+ t = t | Wire.read();
+ return t;
}
/********************************************************************************************/
-// globals
+// globals
-uint8_t chirp_current = 0; // current selected/active sensor
-uint8_t chirp_found_sensors = 0; // number of found sensors
+uint8_t chirp_current = 0; // current selected/active sensor
+uint8_t chirp_found_sensors = 0; // number of found sensors
-char chirp_name[7];
-uint8_t chirp_next_job = 0; //0=reset, 1=auto-wake, 2-9 = various measure steps; 10 = TELE done
-uint32_t chirp_timeout_count = 0; //is handled every second, so value is equal to seconds (it is a slow sensor)
+char chirp_name[7];
+uint8_t chirp_next_job = 0; //0=reset, 1=auto-wake, 2-13 = various measure steps; 14 = TELE done
+uint32_t chirp_timeout_count = 0; //is handled every second, so value is equal to seconds (it is a slow sensor)
-#pragma pack(1)
-struct ChirpSensor_t{
- uint16_t moisture = 0; // shall hold post-processed data, if implemented
- uint16_t light = 0; // light level, maybe already postprocessed depending on the firmware
- int16_t temperature= 0; // temperature in degrees CELSIUS * 10
- uint8_t version = 0; // firmware-version
- uint8_t address:7; // we need only 7bit so...
- uint8_t explicitSleep:1; // there is a free bit to play with ;)
+#pragma pack(1)
+struct ChirpSensor_t{
+ uint16_t moisture = 0; // shall hold post-processed data, if implemented
+ uint16_t light = 0; // light level, maybe already postprocessed depending on the firmware
+ int16_t temperature = 0; // temperature in degrees CELSIUS * 10 , we will also store the I2C error code
+ uint8_t version = 0; // firmware-version
+ uint8_t address:7; // we need only 7bit so...
+ uint8_t explicitSleep:1; // there is a free bit to play with ;)
};
-#pragma pack()
+#pragma pack()
-ChirpSensor_t chirp_sensor[CHIRP_MAX_SENSOR_COUNT]; // should be 8 bytes per sensor slot
+ChirpSensor_t chirp_sensor[CHIRP_MAX_SENSOR_COUNT]; // should be 8 bytes per sensor slot
/********************************************************************************************/
-void ChirpReset(uint8_t addr) {
- ChirpWriteI2CRegister(addr, CHIRP_RESET);
+void ChirpReset(uint8_t addr) {
+ ChirpWriteI2CRegister(addr, CHIRP_RESET);
}
/********************************************************************************************/
-void ChirpResetAll(void) {
- for (uint32_t i = 0; i < chirp_found_sensors; i++) {
- if (chirp_sensor[i].version) {
- ChirpReset(chirp_sensor[i].address);
- }
- }
+void ChirpResetAll(void) {
+ for (uint32_t i = 0; i < chirp_found_sensors; i++) {
+ if (chirp_sensor[i].version) {
+ ChirpReset(chirp_sensor[i].address);
+ }
+ }
}
/********************************************************************************************/
-void ChirpClockSet() { // set I2C for this slow sensor
- Wire.setClockStretchLimit(4000);
- Wire.setClock(50000);
+void ChirpClockSet() { // set I2C for this slow sensor
+ Wire.setClockStretchLimit(4000);
+ Wire.setClock(50000);
}
/********************************************************************************************/
-void ChirpSleep(uint8_t addr) {
- ChirpWriteI2CRegister(addr, CHIRP_SLEEP);
+void ChirpSleep(uint8_t addr) {
+ ChirpWriteI2CRegister(addr, CHIRP_SLEEP);
}
/********************************************************************************************/
-// void ChirpSleepAll(void) {
-// for (uint32_t i = 0; i < chirp_found_sensors; i++) {
-// if (chirp_sensor[i].version) {
-// ChirpSleep(chirp_sensor[i].address);
-// }
-// }
-// }
+// void ChirpSleepAll(void) {
+// for (uint32_t i = 0; i < chirp_found_sensors; i++) {
+// if (chirp_sensor[i].version) {
+// ChirpSleep(chirp_sensor[i].address);
+// }
+// }
+// }
-// /********************************************************************************************/
+// /********************************************************************************************/
-// void ChirpAutoWakeAll(void) {
-// for (uint32_t i = 0; i < chirp_found_sensors; i++) {
-// if (chirp_sensor[i].version && !chirp_sensor[i].explicitSleep) {
-// ChirpReadVersion(chirp_sensor[i].address);
-// }
-// }
-// }
+// void ChirpAutoWakeAll(void) {
+// for (uint32_t i = 0; i < chirp_found_sensors; i++) {
+// if (chirp_sensor[i].version && !chirp_sensor[i].explicitSleep) {
+// ChirpReadVersion(chirp_sensor[i].address);
+// }
+// }
+// }
/********************************************************************************************/
-void ChirpSelect(uint8_t sensor) {
- if(sensor < chirp_found_sensors) { //TODO: show some infos
- chirp_current = sensor;
- DEBUG_SENSOR_LOG(PSTR("CHIRP: Sensor %u now active."), chirp_current);
- }
- if (sensor == 255) {
- DEBUG_SENSOR_LOG(PSTR("CHIRP: Sensor %u active at address 0x%x."), chirp_current, chirp_sensor[chirp_current].address);
- }
+void ChirpSelect(uint8_t sensor) {
+ if(sensor < chirp_found_sensors) { //TODO: show some infos
+ chirp_current = sensor;
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: Sensor %u now active."), chirp_current);
+ }
+ if (sensor == 255) {
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: Sensor %u active at address 0x%x."), chirp_current, chirp_sensor[chirp_current].address);
+ }
}
/********************************************************************************************/
-// bool ChirpMeasureLight(void) {
-// for (uint32_t i = 0; i < chirp_found_sensors; i++) {
-// if (chirp_sensor[i].version && !chirp_sensor[i].explicitSleep) {
-// uint8_t lightReady = I2cRead8(chirp_sensor[i].address, CHIRP_GET_BUSY);
-// DEBUG_SENSOR_LOG(PSTR("CHIRP: busy status for light for sensor %u"), lightReady);
-// if (lightReady == 1) {
-// return false; // a measurement is still in progress, we stop everything and come back in the next loop = 1 second
-// }
-// DEBUG_SENSOR_LOG(PSTR("CHIRP: init measure light for sensor %u"), i);
-// ChirpWriteI2CRegister(chirp_sensor[i].address, CHIRP_MEASURE_LIGHT);
-// }
-// }
-// return true; // we could read all values (maybe at different times, but that does not really matter) and consider this job finished
-// }
-
-/********************************************************************************************/
-
-// void ChirpReadCapTemp() { // no timeout needed for both measurements, so we do it at once
-// for (uint32_t i = 0; i < chirp_found_sensors; i++) {
-// if (chirp_sensor[i].version && !chirp_sensor[i].explicitSleep) {
-// DEBUG_SENSOR_LOG(PSTR("CHIRP: now really read CapTemp for sensor at address 0x%x"), chirp_sensor[i].address);
-// chirp_sensor[i].moisture = I2cRead16(chirp_sensor[i].address, CHIRP_GET_CAPACITANCE);
-// chirp_sensor[i].temperature = I2cRead16(chirp_sensor[i].address, CHIRP_GET_TEMPERATURE);
-// }
-// }
-// }
-
-/********************************************************************************************/
-
-// bool ChirpReadLight() { // sophisticated calculations could be done here
-// bool success = false;
-// for (uint32_t i = 0; i < chirp_found_sensors; i++) {
-// DEBUG_SENSOR_LOG(PSTR("CHIRP: will read light for sensor %u"), i);
-// if (chirp_sensor[i].version) {
-// if (I2cValidRead16(&chirp_sensor[i].light, chirp_sensor[i].address, CHIRP_GET_LIGHT)){
-// DEBUG_SENSOR_LOG(PSTR("CHIRP: light read success"));
-// success = true;
-// }
-// if(!chirp_sensor[i].explicitSleep){ success = true;}
-// }
-// }
-// return success;
-// }
-
-/********************************************************************************************/
-
-uint8_t ChirpReadVersion(uint8_t addr) {
- return (I2cRead8(addr, CHIRP_GET_VERSION));
+uint8_t ChirpReadVersion(uint8_t addr) {
+ return (I2cRead8(addr, CHIRP_GET_VERSION));
}
/********************************************************************************************/
-bool ChirpSet(uint8_t addr) {
- if(addr < 128){
- if (I2cWrite8(chirp_sensor[chirp_current].address, CHIRP_SET_ADDRESS, addr)){
- I2cWrite8(chirp_sensor[chirp_current].address, CHIRP_SET_ADDRESS, addr); // two calls are needed for sensor firmware version 2.6
- DEBUG_SENSOR_LOG(PSTR("CHIRP: Wrote adress %u "), addr);
- ChirpReset(chirp_sensor[chirp_current].address);
- chirp_sensor[chirp_current].address = addr;
- return true;
- }
- }
- return false;
+bool ChirpSet(uint8_t addr) {
+ if(addr < 128){
+ if (I2cWrite8(chirp_sensor[chirp_current].address, CHIRP_SET_ADDRESS, addr)){
+ I2cWrite8(chirp_sensor[chirp_current].address, CHIRP_SET_ADDRESS, addr); // two calls are needed for sensor firmware version 2.6
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: Wrote adress %u "), addr);
+ ChirpReset(chirp_sensor[chirp_current].address);
+ chirp_sensor[chirp_current].address = addr;
+ return true;
+ }
+ }
+ return false;
}
/********************************************************************************************/
-bool ChirpScan() {
- ChirpClockSet();
- chirp_found_sensors = 0;
- for (uint8_t address = 1; address <= 127; address++) {
- chirp_sensor[chirp_found_sensors].version = 0;
- chirp_sensor[chirp_found_sensors].version = ChirpReadVersion(address);
- delay(2);
- chirp_sensor[chirp_found_sensors].version = ChirpReadVersion(address);
- if(chirp_sensor[chirp_found_sensors].version > 0) {
- AddLog_P2(LOG_LEVEL_DEBUG, S_LOG_I2C_FOUND_AT, "CHIRP:", address);
- if(chirp_found_sensors 0) {
+ AddLog_P2(LOG_LEVEL_DEBUG, S_LOG_I2C_FOUND_AT, "CHIRP:", address);
+ if(chirp_found_sensors 0) {
- return;
- }
- DEBUG_SENSOR_LOG(PSTR("CHIRP: scan will start ..."));
- if (ChirpScan()) {
- uint8_t chirp_model = 0; // TODO: ??
- GetTextIndexed(chirp_name, sizeof(chirp_name), chirp_model, kChirpTypes);
- }
+ if (chirp_next_job > 0) {
+ return;
+ }
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: scan will start ..."));
+ if (ChirpScan()) {
+ uint8_t chirp_model = 0; // TODO: ??
+ GetTextIndexed(chirp_name, sizeof(chirp_name), chirp_model, kChirpTypes);
+ }
}
/********************************************************************************************/
-void ChirpServiceAllSensors(uint8_t job){
- for (uint32_t i = 0; i < chirp_found_sensors; i++) {
- if (chirp_sensor[i].version && !chirp_sensor[i].explicitSleep) {
- DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare for sensor at address 0x%x"), chirp_sensor[i].address);
- switch(job){
- case 0:
- ChirpWriteI2CRegister(chirp_sensor[i].address, CHIRP_GET_CAPACITANCE);
- break;
- case 1:
- chirp_sensor[i].moisture = ChirpFinishReadI2CRegister16bit(chirp_sensor[i].address);
- break;
- case 2:
- ChirpWriteI2CRegister(chirp_sensor[i].address, CHIRP_GET_TEMPERATURE);
- break;
- case 3:
- chirp_sensor[i].temperature = ChirpFinishReadI2CRegister16bit(chirp_sensor[i].address);
- break;
- case 4:
- ChirpWriteI2CRegister(chirp_sensor[i].address, CHIRP_MEASURE_LIGHT);
- break;
- case 5:
- ChirpWriteI2CRegister(chirp_sensor[i].address, CHIRP_GET_LIGHT);
- break;
- case 6:
- chirp_sensor[i].light = ChirpFinishReadI2CRegister16bit(chirp_sensor[i].address);
- break;
- default:
- break;
- }
- }
- }
+void ChirpServiceAllSensors(uint8_t job){
+ for (uint32_t i = 0; i < chirp_found_sensors; i++) {
+ if (chirp_sensor[i].version && !chirp_sensor[i].explicitSleep) {
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare for sensor at address 0x%x"), chirp_sensor[i].address);
+ switch(job){
+ case 0:
+ ChirpWriteI2CRegister(chirp_sensor[i].address, CHIRP_GET_CAPACITANCE);
+ break;
+ case 1:
+ chirp_sensor[i].moisture = ChirpFinishReadI2CRegister16bit(chirp_sensor[i].address);
+ break;
+ case 2:
+ ChirpWriteI2CRegister(chirp_sensor[i].address, CHIRP_GET_TEMPERATURE);
+ break;
+ case 3:
+ chirp_sensor[i].temperature = ChirpFinishReadI2CRegister16bit(chirp_sensor[i].address);
+ break;
+ case 4:
+ ChirpWriteI2CRegister(chirp_sensor[i].address, CHIRP_MEASURE_LIGHT);
+ break;
+ case 5:
+ ChirpWriteI2CRegister(chirp_sensor[i].address, CHIRP_GET_LIGHT);
+ break;
+ case 6:
+ chirp_sensor[i].light = ChirpFinishReadI2CRegister16bit(chirp_sensor[i].address);
+ break;
+ default:
+ break;
+ }
+ }
+ }
}
/********************************************************************************************/
-void ChirpEvery100MSecond(void)
+void ChirpEvery100MSecond(void)
{
- // DEBUG_SENSOR_LOG(PSTR("CHIRP: every second"));
- if(chirp_timeout_count == 0) { //countdown complete, now do something
- switch(chirp_next_job) {
- case 0: //this should only be called after driver initialization
- DEBUG_SENSOR_LOG(PSTR( "CHIRP: reset all"));
- ChirpResetAll();
- chirp_timeout_count = 10; // wait a second
- chirp_next_job++;
- break;
- case 1: // auto-sleep-wake seems to expose a fundamental I2C-problem of the sensor and is deactivated
- // DEBUG_SENSOR_LOG(PSTR("CHIRP: auto-wake all"));
- // ChirpAutoWakeAll(); // this is only a wake-up call at the start of next read cycle
- chirp_next_job++; // go on, next job should start in a second
- break;
- case 2:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare moisture read"));
- ChirpServiceAllSensors(0);
- chirp_timeout_count = 11; // wait 1.1 seconds,
- chirp_next_job++;
- break;
- case 3:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: finish moisture read"));
- ChirpServiceAllSensors(1);
- chirp_next_job++;
- break;
- case 4:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare moisture read - 2nd"));
- ChirpServiceAllSensors(0);
- chirp_timeout_count = 11; // wait 1.1 seconds,
- chirp_next_job++;
- break;
- case 5:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: finish moisture read - 2nd"));
- ChirpServiceAllSensors(1);
- chirp_next_job++;
- break;
- case 6:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare temperature read"));
- ChirpServiceAllSensors(2);
- chirp_timeout_count = 11; // wait 1.1 seconds,
- chirp_next_job++;
- break;
- case 7:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: finish temperature read"));
- ChirpServiceAllSensors(3);
- chirp_next_job++;
- break;
- case 8:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare temperature read - 2nd"));
- ChirpServiceAllSensors(2);
- chirp_timeout_count = 11; // wait 1.1 seconds,
- chirp_next_job++;
- break;
- case 9:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: finish temperature read - 2nd"));
- ChirpServiceAllSensors(3);
- chirp_next_job++;
- break;
- case 10:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: start light measure process"));
- ChirpServiceAllSensors(4);
- chirp_timeout_count = 90; // wait 9 seconds,
- chirp_next_job++;
- break;
- case 11:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare light read"));
- ChirpServiceAllSensors(5);
- chirp_timeout_count = 11; // wait 1.1 seconds,
- chirp_next_job++;
- break;
- case 12:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: finish light read"));
- ChirpServiceAllSensors(6);
- chirp_next_job++;
- break;
- case 13:
- DEBUG_SENSOR_LOG(PSTR("CHIRP: paused, waiting for TELE"));
- break;
- case 14:
- if (Settings.tele_period > 16){
- chirp_timeout_count = (Settings.tele_period - 17) * 10; // sync it with the TELEPERIOD, we need about up to 17 seconds to measure
- DEBUG_SENSOR_LOG(PSTR("CHIRP: timeout: %u, tele: %u"), chirp_timeout_count, Settings.tele_period);
- }
- else{
- AddLog_P2(LOG_LEVEL_INFO, PSTR("CHIRP: TELEPERIOD must be > 16 seconds !"));
- }
- chirp_next_job = 1; // back to step 1
- break;
- }
- }
- else {
- chirp_timeout_count--; // count down
- }
+ // DEBUG_SENSOR_LOG(PSTR("CHIRP: every second"));
+ if(chirp_timeout_count == 0) { //countdown complete, now do something
+ switch(chirp_next_job) {
+ case 0: //this should only be called after driver initialization
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: reset all"));
+ ChirpResetAll();
+ chirp_timeout_count = 10; // wait a second
+ chirp_next_job++;
+ break;
+ case 1: // auto-sleep-wake seems to expose a fundamental I2C-problem of the sensor and is deactivated
+ // DEBUG_SENSOR_LOG(PSTR("CHIRP: auto-wake all"));
+ // ChirpAutoWakeAll(); // this is only a wake-up call at the start of next read cycle
+ chirp_next_job++; // go on, next job should start in a second
+ break;
+ case 2:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare moisture read"));
+ ChirpServiceAllSensors(0);
+ chirp_timeout_count = 11; // wait 1.1 seconds,
+ chirp_next_job++;
+ break;
+ case 3:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: finish moisture read"));
+ ChirpServiceAllSensors(1);
+ chirp_next_job++;
+ break;
+ case 4:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare moisture read - 2nd"));
+ ChirpServiceAllSensors(0);
+ chirp_timeout_count = 11; // wait 1.1 seconds,
+ chirp_next_job++;
+ break;
+ case 5:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: finish moisture read - 2nd"));
+ ChirpServiceAllSensors(1);
+ chirp_next_job++;
+ break;
+ case 6:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare temperature read"));
+ ChirpServiceAllSensors(2);
+ chirp_timeout_count = 11; // wait 1.1 seconds,
+ chirp_next_job++;
+ break;
+ case 7:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: finish temperature read"));
+ ChirpServiceAllSensors(3);
+ chirp_next_job++;
+ break;
+ case 8:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare temperature read - 2nd"));
+ ChirpServiceAllSensors(2);
+ chirp_timeout_count = 11; // wait 1.1 seconds,
+ chirp_next_job++;
+ break;
+ case 9:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: finish temperature read - 2nd"));
+ ChirpServiceAllSensors(3);
+ chirp_next_job++;
+ break;
+ case 10:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: start light measure process"));
+ ChirpServiceAllSensors(4);
+ chirp_timeout_count = 90; // wait 9 seconds,
+ chirp_next_job++;
+ break;
+ case 11:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: prepare light read"));
+ ChirpServiceAllSensors(5);
+ chirp_timeout_count = 11; // wait 1.1 seconds,
+ chirp_next_job++;
+ break;
+ case 12:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: finish light read"));
+ ChirpServiceAllSensors(6);
+ chirp_next_job++;
+ break;
+ case 13:
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: paused, waiting for TELE"));
+ break;
+ case 14:
+ if (Settings.tele_period > 16){
+ chirp_timeout_count = (Settings.tele_period - 17) * 10; // sync it with the TELEPERIOD, we need about up to 17 seconds to measure
+ DEBUG_SENSOR_LOG(PSTR("CHIRP: timeout: %u, tele: %u"), chirp_timeout_count, Settings.tele_period);
+ }
+ else{
+ AddLog_P2(LOG_LEVEL_INFO, PSTR("CHIRP: TELEPERIOD must be > 16 seconds !"));
+ }
+ chirp_next_job = 1; // back to step 1
+ break;
+ }
+ }
+ else {
+ chirp_timeout_count--; // count down
+ }
}
/********************************************************************************************/
-// normaly in i18n.h
+// normaly in i18n.h
-#define D_JSON_MOISTURE "Moisture"
+#define D_JSON_MOISTURE "Moisture"
+#define D_JSON_DARKNESS "Darkness"
-#ifdef USE_WEBSERVER
- // {s} = , {m} = | , {e} = |
+#ifdef USE_WEBSERVER
+ // {s} = , {m} = | , {e} = |
- const char HTTP_SNS_MOISTURE[] PROGMEM = "{s} " D_JSON_MOISTURE ": {m}%s %{e}";
- const char HTTP_SNS_CHIRPVER[] PROGMEM = "{s} CHIRP-sensor %u at address: {m}0x%x{e}"
- "{s} FW-version: {m}%s {e}"; ;
- const char HTTP_SNS_CHIRPSLEEP[] PROGMEM = "{s} {m} is sleeping ...{e}";
-#endif // USE_WEBSERVER
+ const char HTTP_SNS_MOISTURE[] PROGMEM = "{s} " D_JSON_MOISTURE "{m}%s %{e}";
+ const char HTTP_SNS_DARKNESS[] PROGMEM = "{s} " D_JSON_DARKNESS "{m}%s %{e}";
+ const char HTTP_SNS_CHIRPVER[] PROGMEM = "{s} CHIRP-sensor %u at address{m}0x%x{e}"
+ "{s} FW-version{m}%s {e}"; ;
+ const char HTTP_SNS_CHIRPSLEEP[] PROGMEM = "{s} {m} is sleeping ...{e}";
+#endif // USE_WEBSERVER
/********************************************************************************************/
-void ChirpShow(bool json)
+void ChirpShow(bool json)
{
- for (uint32_t i = 0; i < chirp_found_sensors; i++) {
- if (chirp_sensor[i].version) {
- // convert double values to string
- char str_moisture[33];
- dtostrfd(chirp_sensor[i].moisture, 0, str_moisture);
- char str_temperature[33];
- double t_temperature = ((double) chirp_sensor[i].temperature )/10.0;
- dtostrfd(t_temperature, Settings.flag2.temperature_resolution, str_temperature);
- char str_light[33];
- dtostrfd(chirp_sensor[i].light, 0, str_light);
- char str_version[33];
- dtostrfd(chirp_sensor[i].version, 0, str_version);
- if (json) {
- if(!chirp_sensor[i].explicitSleep){
- ResponseAppend_P(PSTR(",\"%s%u\":{\"" D_JSON_MOISTURE "\":%s,\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_ILLUMINANCE "\":\"%s}"),
- chirp_name, i, str_moisture, str_temperature, str_light);}
- else {
- ResponseAppend_P(PSTR(",\"%s%u\":{\"sleeping\"}"),
- chirp_name, i);
- }
- #ifdef USE_DOMOTICZ
- if (0 == tele_period) {
- DomoticzTempHumSensor(str_temperature, str_moisture);
- DomoticzSensor(DZ_ILLUMINANCE,chirp_sensor[i].light);
- }
- #endif // USE_DOMOTICZ
- #ifdef USE_WEBSERVER
- } else {
- WSContentSend_PD(HTTP_SNS_CHIRPVER, i, chirp_sensor[i].address, str_version);
- if (chirp_sensor[i].explicitSleep){
- WSContentSend_PD(HTTP_SNS_CHIRPSLEEP);
- }
- else {
- WSContentSend_PD(HTTP_SNS_MOISTURE, str_moisture);
- WSContentSend_PD(HTTP_SNS_ILLUMINANCE, " ", chirp_sensor[i].light);
- WSContentSend_PD(HTTP_SNS_TEMP, " ",str_temperature, TempUnit());
- }
-
- #endif // USE_WEBSERVER
- }
- }
- }
+ for (uint32_t i = 0; i < chirp_found_sensors; i++) {
+ if (chirp_sensor[i].version) {
+ // convert double values to string
+ char str_moisture[33];
+ dtostrfd(chirp_sensor[i].moisture, 0, str_moisture);
+ char str_temperature[33];
+ double t_temperature = ((double) chirp_sensor[i].temperature )/10.0;
+ dtostrfd(t_temperature, Settings.flag2.temperature_resolution, str_temperature);
+ char str_light[33];
+ dtostrfd(chirp_sensor[i].light, 0, str_light);
+ char str_version[33];
+ dtostrfd(chirp_sensor[i].version, 0, str_version);
+ if (json) {
+ if(!chirp_sensor[i].explicitSleep) {
+ ResponseAppend_P(PSTR(",\"%s%u\":{\"" D_JSON_MOISTURE "\":%s"),chirp_name, i, str_moisture);
+ if(chirp_sensor[i].temperature!=-1){ // this is the error code -> no temperature
+ ResponseAppend_P(PSTR(",\"" D_JSON_TEMPERATURE "\":%s"),str_temperature);
+ }
+ ResponseAppend_P(PSTR(",\"" D_JSON_DARKNESS "\":\"%s}"),str_light);
+ }
+ else {
+ ResponseAppend_P(PSTR(",\"%s%u\":{\"sleeping\"}"),chirp_name, i);
+ }
+ #ifdef USE_DOMOTICZ
+ if (0 == tele_period) {
+ DomoticzTempHumSensor(str_temperature, str_moisture);
+ DomoticzSensor(DZ_ILLUMINANCE,chirp_sensor[i].light);
+ }
+ #endif // USE_DOMOTICZ
+ #ifdef USE_WEBSERVER
+ } else {
+ WSContentSend_PD(HTTP_SNS_CHIRPVER, i, chirp_sensor[i].address, str_version);
+ if (chirp_sensor[i].explicitSleep){
+ WSContentSend_PD(HTTP_SNS_CHIRPSLEEP);
+ }
+ else {
+ WSContentSend_PD(HTTP_SNS_MOISTURE, str_moisture);
+ WSContentSend_PD(HTTP_SNS_DARKNESS, str_light);
+ if(chirp_sensor[i].temperature!=-1){ // this is the error code -> no temperature
+ WSContentSend_PD(HTTP_SNS_TEMP, " ",str_temperature, TempUnit());
+ }
+ }
+
+ #endif // USE_WEBSERVER
+ }
+ }
+ }
}
/*********************************************************************************************\
- * check the Chirp commands
+ * check the Chirp commands
\*********************************************************************************************/
-bool ChirpCmd(void) {
- char command[CMDSZ];
- bool serviced = true;
- uint8_t disp_len = strlen(D_CMND_CHIRP);
+bool ChirpCmd(void) {
+ char command[CMDSZ];
+ bool serviced = true;
+ uint8_t disp_len = strlen(D_CMND_CHIRP);
- if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_CHIRP), disp_len)) { // prefix
- int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + disp_len, kCHIRP_Commands);
+ if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_CHIRP), disp_len)) { // prefix
+ int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + disp_len, kCHIRP_Commands);
- switch (command_code) {
- case CMND_CHIRP_SELECT:
- case CMND_CHIRP_SET:
- if (XdrvMailbox.data_len > 0) {
- if (command_code == CMND_CHIRP_SELECT) { ChirpSelect(XdrvMailbox.payload); } //select active sensor, i.e. for wake, sleep or reset
- if (command_code == CMND_CHIRP_SET) { ChirpSet((uint8_t)XdrvMailbox.payload); } //set and change I2C-address of selected sensor
- Response_P(S_JSON_CHIRP_COMMAND_NVALUE, command, XdrvMailbox.payload);
- }
- else {
- if (command_code == CMND_CHIRP_SELECT) { ChirpSelect(255); } //show active sensor
- Response_P(S_JSON_CHIRP_COMMAND, command, XdrvMailbox.payload);
- }
- break;
- case CMND_CHIRP_SCAN:
- case CMND_CHIRP_SLEEP:
- case CMND_CHIRP_WAKE:
- case CMND_CHIRP_RESET:
- if (command_code == CMND_CHIRP_SCAN) { chirp_next_job = 0;
- ChirpDetect(); } // this will re-init the sensor array
- if (command_code == CMND_CHIRP_SLEEP) { chirp_sensor[chirp_current].explicitSleep = true; // we do not touch this sensor in the read functions
- ChirpSleep(chirp_sensor[chirp_current].address); }
- if (command_code == CMND_CHIRP_WAKE) { chirp_sensor[chirp_current].explicitSleep = false; // back in action
- ChirpReadVersion(chirp_sensor[chirp_current].address); } // just use read version as wakeup call
- if (command_code == CMND_CHIRP_RESET) { ChirpReset(chirp_sensor[chirp_current].address); }
- Response_P(S_JSON_CHIRP_COMMAND, command, XdrvMailbox.payload);
- break;
- default:
- // else for Unknown command
- serviced = false;
- break;
- }
- }
- return serviced;
+ switch (command_code) {
+ case CMND_CHIRP_SELECT:
+ case CMND_CHIRP_SET:
+ if (XdrvMailbox.data_len > 0) {
+ if (command_code == CMND_CHIRP_SELECT) { ChirpSelect(XdrvMailbox.payload); } //select active sensor, i.e. for wake, sleep or reset
+ if (command_code == CMND_CHIRP_SET) { ChirpSet((uint8_t)XdrvMailbox.payload); } //set and change I2C-address of selected sensor
+ Response_P(S_JSON_CHIRP_COMMAND_NVALUE, command, XdrvMailbox.payload);
+ }
+ else {
+ if (command_code == CMND_CHIRP_SELECT) { ChirpSelect(255); } //show active sensor
+ Response_P(S_JSON_CHIRP_COMMAND, command, XdrvMailbox.payload);
+ }
+ break;
+ case CMND_CHIRP_SCAN:
+ case CMND_CHIRP_SLEEP:
+ case CMND_CHIRP_WAKE:
+ case CMND_CHIRP_RESET:
+ if (command_code == CMND_CHIRP_SCAN) { chirp_next_job = 0;
+ ChirpDetect(); } // this will re-init the sensor array
+ if (command_code == CMND_CHIRP_SLEEP) { chirp_sensor[chirp_current].explicitSleep = true; // we do not touch this sensor in the read functions
+ ChirpSleep(chirp_sensor[chirp_current].address); }
+ if (command_code == CMND_CHIRP_WAKE) { chirp_sensor[chirp_current].explicitSleep = false; // back in action
+ ChirpReadVersion(chirp_sensor[chirp_current].address); } // just use read version as wakeup call
+ if (command_code == CMND_CHIRP_RESET) { ChirpReset(chirp_sensor[chirp_current].address); }
+ Response_P(S_JSON_CHIRP_COMMAND, command, XdrvMailbox.payload);
+ break;
+ default:
+ // else for Unknown command
+ serviced = false;
+ break;
+ }
+ }
+ return serviced;
}
/*********************************************************************************************\
- * Interface
+ * Interface
\*********************************************************************************************/
-bool Xsns48(uint8_t function)
+bool Xsns48(uint8_t function)
{
- bool result = false;
+ bool result = false;
- if (i2c_flg) {
- switch (function) {
- case FUNC_INIT:
- ChirpDetect(); // We can call CHIRPSCAN later to re-detect
- break;
- case FUNC_EVERY_100_MSECOND:
- if(chirp_found_sensors > 0){
- ChirpEvery100MSecond();
- }
- break;
- case FUNC_COMMAND:
- result = ChirpCmd();
- break;
- case FUNC_JSON_APPEND:
- ChirpShow(1);
- chirp_next_job = 14; // TELE done, now compute time for next measure cycle
- break;
-#ifdef USE_WEBSERVER
- case FUNC_WEB_SENSOR:
- ChirpShow(0);
- break;
-#endif // USE_WEBSERVER
- }
- }
- return result;
+ if (i2c_flg) {
+ switch (function) {
+ case FUNC_INIT:
+ ChirpDetect(); // We can call CHIRPSCAN later to re-detect
+ break;
+ case FUNC_EVERY_100_MSECOND:
+ if(chirp_found_sensors > 0){
+ ChirpEvery100MSecond();
+ }
+ break;
+ case FUNC_COMMAND:
+ result = ChirpCmd();
+ break;
+ case FUNC_JSON_APPEND:
+ ChirpShow(1);
+ chirp_next_job = 14; // TELE done, now compute time for next measure cycle
+ break;
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+ ChirpShow(0);
+ break;
+#endif // USE_WEBSERVER
+ }
+ }
+ return result;
}
-#endif // USE_CHIRP
-#endif // USE_I2C
+#endif // USE_CHIRP
+#endif // USE_I2C