Apollon77 / I2CSoilMoistureSensor

Simple Arduino Library for the I2C Soil Moisture Sensor version from Chirp (https://github.com/Miceuz/i2c-moisture-sensor)
MIT License
73 stars 27 forks source link

change addr after declaration of sensor #14

Closed roblad closed 6 years ago

roblad commented 6 years ago

Hi,

I have a question regarding bat addres of sensor when it will chnge during hot unplug.

Is it possible to change addr through I2CSoilMoistureSensor:I2CSoilMoistureSensor((uint8_t)found chip_addr_during_scat);

I have scan function

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

and when it will be found:

I wouldlike to change declared in that:

I2CSoilMoistureSensor sensor(chirpaddr);

to:

2CSoilMoistureSensor:I2CSoilMoistureSensor((uint8_t)new_chirpaddr)

and after that

sensor.setAddress(chirpaddr,true)

Apollon77 commented 6 years ago

Sorry, but I do not understand the question.

roblad commented 6 years ago

Hi,

I prepared a code for ESP, I have a lot of errors with the reading values, I did the some mechanism for changing the address of sensor because I switch it out through MOSFET transistor during ESP deep sleep. Some times, sensor lost address and need to be changed. My code has to find and change the address automatically, but currently I am not using your library for that but I want.

Could you look on code and comments below and answer me if such method will change the private variable from class:

int sensorAddress;

through that function from your library:

I2CSoilMoistureSensor::I2CSoilMoistureSensor(uint8_t addr) : sensorAddress(addr) { // nothing to do ... Wire.begin needs to be put outside of class }

method:

I2CSoilMoistureSensor:I2CSoilMoistureSensor((uint8_t)scan);

.>and after that I will be able to run with success that function:

(sensor.setAddress(0x20,true)) ;

From the begging haw it looks like in my code:

include

define CHIRP_ADDR1 0x20

uint8_t chirpaddr = CHIRP_ADDR1;

I2CSoilMoistureSensor sensor(chirpaddr);

function for detecting proper address boolean chirp_detect() { uint8t scan = 0; byte counter = 0; Wire.begin(); Wire.setClock(40000); Wire.setClockStretchLimit(2500); scan = I2cScan();

if (scan != 0) {

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

In hear I would like to use such trick:

2CSoilMoistureSensor:I2CSoilMoistureSensor((uint8_t)scan)

(sensor.setAddress(0x20,true))

*/

there is my other function that changes address

    if (I2cWrite(scan, SOILMOISTURESENSOR_SET_ADDRESS, 0x20, 1))  {
    I2cWrite(scan, SOILMOISTURESENSOR_RESET, 0, 0);
    counter = 0;

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

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

return true;

} ....

code for checking if address is correct - through your function, if not my function is looking for new i2c address:

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

Apollon77 commented 6 years ago

Do you also tried to contact @Miceuz about the "loosing adress" topic before thinking about workarounds??

And please put your code in correct MARKDOWN Tags (normaally three `) because formatting is broken completely

roblad commented 6 years ago

Hi,

There is only one question to you:

Will it work ?

include

define CHIRP_ADDR1 0x20

uint8_t chirpaddr = CHIRP_ADDR1;

I2CSoilMoistureSensor sensor(chirpaddr);

some scanning sensor code will be hear for founding address of sensor different than default:

I2CSoilMoistureSensor:I2CSoilMoistureSensor((uint8_t)scan)

(sensor.setAddress(0x20,true))

roblad commented 6 years ago

Hi, Could you answere ?

Additionally could you thing about some buffer for reading , I have many errors reading values from sensor. There is probably synchronisation with clock betwen sensor and ESP Wemeos module. I use Tasmota and many errors happening.

I discovered the I2C valid reading i.e:

define I2C_RETRY_COUNTER 3

uint32_t i2c_buffer = 0;

bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size) { byte x = I2C_RETRY_COUNTER;

i2c_buffer = 0; do { Wire.beginTransmission(addr); // start transmission to device Wire.write(reg); // sends register address to read from if (0 == Wire.endTransmission(false)) { // Try to become I2C Master, send data and collect >bytes, keep master status for next request... Wire.requestFrom((int)addr, (int)size); // send data n-bytes read if (Wire.available() == size) { for (byte i = 0; i < size; i++) { i2c_buffer = i2c_buffer << 8 | Wire.read(); // receive DATA } } } x--; } while (Wire.endTransmission(true) != 0 && x != 0); // end transmission return (x); }

bool I2cValidRead8(uint8_t data, uint8_t addr, uint8_t reg) { bool status = I2cValidRead(addr, reg, 1); data = (uint8_t)i2c_buffer; return status; }

Apollon77 commented 6 years ago

Sorry, but I do not use HWs and combinations as you ... So you are welcome to try to solve it and I will be happy to check and accept PRs