i2c-moisture-sensor icon indicating copy to clipboard operation
i2c-moisture-sensor copied to clipboard

sensor lost address and reading values are not corect ocasionaly - ESP2866 tasmota

Open roblad opened this issue 6 years ago • 0 comments

Hi,

Could you look on that threat

https://github.com/Apollon77/I2CSoilMoistureSensor/issues/14

Also haw to block address sensor change when deepsleep and power is from ESP GPIO 3.3V.

And also I am attachin a code from TASMOTA ESP for reviewing potential issue caused sensor problems

CODE:

`/* xsns_chirp.ino - CHIRP ambient light sensor support for Sonoff-Tasmota

Copyright (C) 2017 Theo Arends

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.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */

#ifdef` USE_I2C #ifdef USE_CHIRP //https://github.com/Apollon77/I2CSoilMoistureSensor/blob/master/I2CSoilMoistureSensor.cpp #include <I2CSoilMoistureSensor.h>

/*********************************************************************************************\

  • CHIRP - Ambient Light Intensity *********************************************************************************************/

//#define CHIRP_CONTINUOUS_HIGH_RES_MODE 0x10 // Start measurement at 1lx resolution. Measurement time is approx 120ms.

#define CHIRP_ADDR1 0x20

#define CHIRP_LIGHT_CALIB 32775 //calibrate darknes value for light sensor #define CHIRP_CAPACITANCE_MIN 220 //calibrate CAPACITANCE min value #define CHIRP_CAPACITANCE_MAX 750 //c0calibrate CAPACITANCE max value #define CHIRP_TEMP_CAL 0 //calibrate TEMP value

uint8_t chirpaddr = CHIRP_ADDR1; uint8_t chirptype = 0; char chirpstype[7]; uint16_t light = 0;

I2CSoilMoistureSensor sensor(chirpaddr);

uint8_t I2cScan_() {

byte error; byte address; uint8_t address_st; byte any = 0; uint8_t count = 0;

for (address = 7; address <= 117; address++) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (0 == error) { any = 1; address_st = address; } else if (4 == error) { continue; any = 0; } } if (any) {

return address_st;

} else { return 0; } }

uint16_t chirp_readLux(void) { uint8_t counter = 0; sensor.startMeasureLight();

while (sensor.isBusy() && counter < 50) {

yield();
delay(100);
counter++;

}

return sensor.getLight(false);

}

boolean chirp_detect() {

uint8_t scan = 0; boolean success = false; strcpy(chirpstype, "CHIRP"); byte counter = 0; Wire.begin(); Wire.setClock(40000); Wire.setClockStretchLimit(2500); scan = I2cScan_();

if (scan != 0) {

    if (scan != 0 && scan >=7 && scan <= 117 ){

    I2CSoilMoistureSensor:I2CSoilMoistureSensor((uint8_t)scan);

      yield();
      if (sensor.setAddress(chirpaddr,true)) {

        sensor.startMeasureLight();
        success = true;
        chirptype = 1;

      }


    }

  #ifdef CHIRP_CONTINUOUS_HIGH_RES_MODE
    I2cWrite(chirpaddr, CHIRP_CONTINUOUS_HIGH_RES_MODE, 1, 0);
  #endif

} else if (scan == 0 || scan < 7 || scan > 117 ) {

  snprintf_P(log_data, sizeof(log_data), PSTR("{CHRIP: " "Unknown error"  ": 0x%2x}"), scan);
  AddLog(LOG_LEVEL_INFO);

  success = false;
  chirptype = 0;

}   else  {

  success = true;
  chirptype = 1;
}

if (success == false) { success = false; chirptype = 0; snprintf_P(log_data, sizeof(log_data), PSTR("{CHRIP: " D_I2CSCAN_NO_DEVICES_FOUND ": 0x%2x}"), chirpaddr); AddLog(LOG_LEVEL_INFO);

} else { success = true; chirptype = 1; chirpaddr = CHIRP_ADDR1; }

return success; }

/*********************************************************************************************\

  • Presentation *********************************************************************************************/ #ifdef USE_WEBSERVER #ifndef USE_BH1750 // avoid duplicate definition const char HTTP_SNS_ILLUMINANCE[] PROGMEM = "%s{s}%s " D_ILLUMINANCE ": {m}%d %{e}"; #endif //USE_BH1750 const char HTTP_SNS_MOISTURE[] PROGMEM = "%s{s}%s " D_MOISTURE ": {m}%s %{e}"; const char HTTP_SNS_CHIRPTEMP[] PROGMEM = "%s{s}%s " D_TEMPERATURE ": {m}%s °C{e}"; const char HTTP_SNS_VER[] PROGMEM = "%s{s}%s Firmware ver.: {m}0x%2x{e}"; #endif // USE_WEBSERVER

const char JSON_SNS_LIGHTMOISTTEMP[] PROGMEM = "%s,"%s":{"" D_LIGHT "":%d,"" D_MOISTURE "":%s,"" D_TEMPERATURE "":%s}";

void reader_wait(uint8_t trying) { uint8_t round = 0; while (sensor.isBusy() && round < trying){ yield(); delay(20); trying++; }

} static uint8_t count = 0; void chirp_Show(boolean json) {

if (!I2cDevice(chirpaddr)) {

chirptype = 0;

  AddLog_P(LOG_LEVEL_DEBUG, PSTR("No CHRIP detected !!!"));



  ExecuteCommandPower(1,7);
  ExecuteCommandPower(1,6);
  yield();
  delay(200);
  ExecuteCommandPower(1,7);
  count++;

  while (sensor.isBusy() && count < 20 ){
    AddLog_P(LOG_LEVEL_DEBUG, PSTR("Waiting for sensor"));
    count++;
    yield();
    delay(50);
  if (count == 18 ) {

    AddLog_P(LOG_LEVEL_DEBUG, PSTR("Traing to redefine sensor"));

    if (chirp_detect()) chirptype = 1;

   }

}
count = 0;

} else { count = 0; AddLog_P(LOG_LEVEL_DEBUG, PSTR("CHRIP detected.")); chirpaddr = CHIRP_ADDR1; chirptype = 1; }

if (chirptype == 1) { char temperature[Settings.flag2.temperature_resolution+3]; char moisture[Settings.flag2.humidity_resolution+3]; float readmoisture = 0; float readtemperature = 0; uint8_t ver = 0; uint8_t counter = 0;

if (!sensor.isBusy() ) {
 ver  = sensor.getVersion();
} else {

 delay(100);
 ver  = sensor.getVersion();
}

do {
  if (!sensor.isBusy() ) {
  readtemperature = sensor.getTemperature();
  } else {
    sensor.getTemperature();
    yield();
    delay(50);

  }

  counter++;

} while ((readtemperature >850.0 || readtemperature < -500.0) && counter < 8);

counter = 0;

do {


if (!sensor.isBusy() ) {

  readmoisture = sensor.getCapacitance();

} else {
  sensor.getCapacitance();
  yield();
  delay(50);

}

  counter++;

} while ((readmoisture > CHIRP_CAPACITANCE_MAX + 200.0 || readmoisture < CHIRP_CAPACITANCE_MIN - 100.0 ) && counter < 8  );

counter = 0;



if (!sensor.isBusy() ) {

    light = chirp_readLux();

  } else {

     do {

          light = sensor.getLight(false);

          counter++;

       } while ((light > CHIRP_LIGHT_CALIB + 1500) && counter < 3);

    counter = 0;

   }


light = (map((light > CHIRP_LIGHT_CALIB  ? CHIRP_LIGHT_CALIB : light),CHIRP_LIGHT_CALIB,0,0,100));
readtemperature = ((readtemperature+CHIRP_TEMP_CAL)/10.0);
readmoisture = (map(readmoisture,CHIRP_CAPACITANCE_MIN,CHIRP_CAPACITANCE_MAX,0,1000)/10.0);
dtostrfd((readmoisture < 0.0 ? 0.0 : (readmoisture > 99 ? 100.0 : readmoisture)), Settings.flag2.humidity_resolution, moisture);
dtostrfd((readtemperature > 85.0 ? 85.0 : readtemperature) , Settings.flag2.temperature_resolution-1, temperature);

if (readtemperature >=85.0 || readtemperature < -40.0 || readmoisture >= 99.9 || readmoisture < 1.0 || light > 99.99 || light < 0) {

sensor.resetSensor(); yield(); delay(500); }

if (json) {
   snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_LIGHTMOISTTEMP, mqtt_data, chirpstype, light, moisture,temperature);

   #ifdef USE_DOMOTICZ
     DomoticzTempHumSensor(temperature, moisture);
     DomoticzSensor(DZ_ILLUMINANCE,light);
   #endif  // USE_DOMOTICZ

#ifdef USE_WEBSERVER } else { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ILLUMINANCE, mqtt_data, chirpstype, light); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_MOISTURE, mqtt_data, chirpstype, moisture ); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_CHIRPTEMP, mqtt_data, chirpstype, temperature); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_VER, mqtt_data, chirpstype, ver);

#endif // USE_WEBSERVER

 }

}

}

/*********************************************************************************************\

  • Interface *********************************************************************************************/

#define XSNS_20

boolean Xsns20(byte function) { boolean result = false;

if (i2c_flg) { switch (function) { case FUNC_XSNS_INIT: chirp_detect(); break; case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: chirp_detect(); break; case FUNC_XSNS_JSON_APPEND: chirp_Show(1); break; #ifdef USE_WEBSERVER case FUNC_XSNS_WEB_APPEND: chirp_Show(0); break; #endif // USE_WEBSERVER } }

return result; }

#endif // USE_CHIRP #endif // USE_I2C`

roblad avatar Jan 07 '18 10:01 roblad