From a371fb9a000ee59502df04fb0097ddd1064c97e9 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Tue, 19 Nov 2024 20:08:40 +1000 Subject: [PATCH] capsules: chirp_i2c_moisture: Improve reliability and accuracy To ensure that we always get the capacitance we issue the GET_CAPACITANCE command twice. The first to start a fresh request and the second to get the latest value. Previously we missed the second request as it was just a read operation instead of a write/read with the second GET_CAPACITANCE request. This returned out of date data. Fix this by issueing two GET_CAPACITANCE requests. While here let's convert the data processing to return a percentage of moisture (from air to full water) instead of returning the dry basis moisture content. Signed-off-by: Alistair Francis --- capsules/extra/src/chirp_i2c_moisture.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/capsules/extra/src/chirp_i2c_moisture.rs b/capsules/extra/src/chirp_i2c_moisture.rs index d137ab6819..333f65a360 100644 --- a/capsules/extra/src/chirp_i2c_moisture.rs +++ b/capsules/extra/src/chirp_i2c_moisture.rs @@ -148,7 +148,8 @@ impl<'a, I: I2CDevice> I2CClient for ChirpI2cMoisture<'a, I> { Operation::None => (), Operation::Moisture => { self.state.set(DeviceState::FinalMoisture); - if let Err((e, buf)) = self.i2c.read(buffer, 2) { + buffer[0] = GET_CAPACITANCE; + if let Err((e, buf)) = self.i2c.write_read(buffer, 1, 2) { self.buffer.replace(buf); self.op.set(Operation::None); @@ -163,11 +164,12 @@ impl<'a, I: I2CDevice> I2CClient for ChirpI2cMoisture<'a, I> { Operation::Moisture => { let capacitance = (((buffer[0] as u32) << 8) | (buffer[1] as u32)) as f32; - // Based on results from - // https://github.com/Miceuz/i2c-moisture-sensor/raw/master/Soil%20Moisture%20Sensor%20Calibration.pdf - let moisture_content = (0.01007 * capacitance * capacitance) - + (0.24885 * capacitance) - - 625.0872; + // 247 is the capacitance in air + // 510 is the capacitance in water + // Use those to calculate the moisture percentage, which is rougly linear + // https://github.com/Miceuz/i2c-moisture-sensor/blob/master/README.md#how-to-interpret-the-readings + // Note that this gives moisture in hundredths of a percent + let moisture_content = ((capacitance - 247.0) / (510.0 - 247.0)) * 10000.0; self.state.set(DeviceState::Normal); self.buffer.replace(buffer);