Miceuz / i2c-moisture-sensor

I2C based soil moisture sensor
Apache License 2.0
240 stars 72 forks source link

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

Closed roblad closed 1 year ago

roblad commented 6 years ago

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

/*****\

//#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);

uint8t 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() {

uint8t 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; }

/*****\

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

 }

}

}

/*****\

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`