## v2.0 schematic Note that v1.2 sensor has similar circuit wiring with different capacitors / resistors' value and time chip (NE555) ![cap-soil-moisture-v2.0-compact](https://hackmd.io/_uploads/SJdAbO1aWg.svg) ## How it works under the hood ### Voltage Regulator - the 662k chip regulates and converts extra power to 3.3V - without the regulator input voltage must be around 3.3V ### Timer Chip the timer chip here is TLC555 generating continuous electrical nearly-square wave, with very short rising / falling-edge transition latencies (see waveform started at [7:18 in this video](https://www.youtube.com/watch?v=pdGRs7GXBeE&t=438s)) - time frequency is determined by part of the circuit `R2`, `R3`, and `C3` - official datasheet provides formula for the frequency calculation - `1.44 / ((r3 + 2 * r2) * c3)`. - voltage magnitude of the wave is either : nearly `VDD` (HIGH state) or `GND` (LOW statee) ### RC circuit behind the timer the nearly-square wave in previous stage propagates to the RC circuit network : - formed by `R1` and `C_probe` - `C_probe` indicates the probe capacitance , it contains two conductive traces on a PCB - it produces triangle wave afterwards (see waveform started at [7:39](https://www.youtube.com/watch?v=pdGRs7GXBeE&t=459s) and [8:42](https://www.youtube.com/watch?v=pdGRs7GXBeE&t=522s) in the video) > Technically this is sometimes called RC low-pass filter , however the point here is NOT for filtering any high frequency component , it is for adjusting voltage amplitude of the wave by varying probe capatitance at fixed timer frequency. Consider relevant equations below : ```python # capacitive reactance , Xc in Ohm Xc = 1 / (2 * math.pi * freq * C) # voltage divider V_out = V_in * R_bottom / (R_up + R_bottom) ``` In this sensor, `freq` is fixed, the capacitance `C` varies depending on moisture detected from probe : - When the soil is wet - `C` goes up , more time to charge the cap, the reactance `Xc` (in Ohm) goes down. - Since bottom part of voltage divider (now `R_bottom = Xc`) is now smaller, more voltage at the junction (the probe) drops - lower output voltage --> lower peak point of triangle wave after processed - When the soil is dry - `C` goes down , charge the cap quickly to full state, `Xc` (in Ohm) goes up. - voltage drop at the junction becomes subtle - higher output voltage --> higher peak point of the triangle wave. ### Peak Detector this part of circuit network forms by `D1`, `C4`, and `R4` for smoothing out the triangle wave and picking peak point of each pulse, to more stable voltage line. --- `C4` keeps previous voltage state between 2 pulses of the triangle wave : - Every time a pulse comes through the doide `D1` , it dumps a bit of charge into `C4`. - Because the pulses happen so fast (few hundred kilo hertz to 1.5 mega hertz), `C4` quickly fills up to the maximum voltage of those triangles. - it smooths the gaps between pulses, turning a bumpy signal into a flat line. --- `D1` avoids charge in `C4` from flowing backwards to previous RC circuit / the probe capacitor : - the triangle wave from the previous stage is constantly jumping between `0V` and its peak. - `D1` only allows current to flow when the incoming pulse is **higher** than the voltage already stored in `C4`. - when the triangle wave drops below the voltage in `C4`, the diode **shuts** preventing the electricity in the capacitor from flowing backward. --- `R4` provides a path for the energy to slowly leak away : - this allows the sensor to **forget the old peak** and **track new, lower peaks** in real-time - If we only had `D1` and `C4`, the output would get **stuck** at the highest voltage it ever saw. - If you pulled the sensor out of wet soil (low voltage) and put it into dry soil (high voltage), it would update fine. - But if you went from dry to wet, it takes ridiculously long time (10 to 15 seconds in my case) to drop the voltage. ## Approximate Probe Capacitance The [python class `CapSoilSensorV2` here](https://github.com/metalalive/EnvToolSetupJunkBox/blob/master/code_snippet/python/electrical.py#L123) is used to estimate probe capacitance in different moisture conditions , create a `CapSoilSensorV2` object with given impedance (in Ohm, measured by multimeter) and check the probe capacitance in python shell environment. > TODO, improve the calculation , this might not be correct Input arguments are impedance in Ohm measured at different points : - the first one is across `R1` before the diode `D1` - the second one is from `R1` to `AOUT` pin ```python! # when the probe in dry / air sensordry = CapSoilSensorV2(83.6 * pow(10, 3), 74.8 * pow(10, 3)) # when in water / saturated sensorwater = CapSoilSensorV2(88 * pow(10, 3), 76.7 * pow(10, 3)) # approximate probe capacitance is around 4nF to 5nF sensordry.probe_capatitance() [4.606611517512703e-09, 5.157900874897261e-09] sensorwater.probe_capatitance() [4.373187332407344e-09, 5.027892168307814e-09] ``` ## Troubleshooting Faulty Sensor ### Wrong Timer Chip normally it should be TLC555 which can run at 3.3V , otherwise the circuit might not work correctly , replace the wrong one with TLC555 ### Missing connection between `R4` and ground This might be due to low-quality manufacture ,in my case when moving v2.0 sensors instantly from air to water, only few can dischange within one second ; while the rest takes more than 10 seconds. Solder an extra wire between the 2 points to resolve this issue. | Bend the wire | after solder work | | -------- | -------- | | ![bent-solder-wire-for-cap-soil-sensor](https://hackmd.io/_uploads/r1ygWIth-l.jpg) | ![cap-soil-sensor-solder-bridge-R4-GND](https://hackmd.io/_uploads/H1GgWLF3bg.jpg) | ## Analog-to-Digital Conversion Sampling Estimation Overall impedance (from `R1` to `AOUT`) ranges from `74.8k` to `76.7k` Ohm , the appropriate / minimal sampling time depends on each embedded-system board. ### STM32F4xx [the python class `STM32F4ADC` here](https://github.com/metalalive/EnvToolSetupJunkBox/blob/master/code_snippet/python/electrical.py#L4C7-L4C18) estimates sampling time on the analog input signal , which determines how many ADC clock cycles are needed to charge the **internal sample-and-hold capacitor** to accurately capture an analog signal with minimal error. #### Core Parameters | Parameter | Purpose | | -------- | -------- | | `resistance_ain` | External analog input source resistance (Ohms) | | `resistance_adc` | Internal ADC input resistance (Ohms) | |`capacitance_adc` |Internal ADC sampling capacitor (Farads) | |`num_bits_resolution` | ADC resolution in bits (e.g., 10-bit, 12-bit) | |`freq_mhz_adc` | ADC clock frequency (MHz) | | | | #### Estimation result ```python! adccfg0 = STM32F4ADC( resistance_ain=76.7 * pow(10, 3), resistance_adc=6 * pow(10, 3), capacitance_adc=4 * pow(10, -12), num_bits_resolution=10, freq_mhz_adc=20, ) print(adccfg0.summary()) --- ADC Parameter Estimation Summary --- Input Resistance (R_AIN): 76700.0 Ohms ADC Input Resistance (R_ADC): 6000 Ohms ADC Sampling Capacitance (C_ADC): 4e-12 Farads ADC impedance: 6321.222882957761 Ohms Parasitic Capacitance (C_Parasitic): 5e-12 Farads ADC Resolution: 10 bits ADC Clock Frequency: 20 MHz Estimated Number of Total Sample Time: 6.190913357889207e-06 Seconds Estimated Number of Sampling Cycles: 124.32 cycles ---------------------------------------- ``` For capacitive soil moisture sensors , the estimated minimal sampling time on STM32 board is `6.19 us` --> `124.32` ADC clock cycles based on the frequency `20Mhz` . > 124 to 125 ADC clock cycles can be covered by setting `ADC_SAMPLETIME_480CYCLES` in software implementation with STM32 HAL ### Improve Sampling Time [Op-amp](https://hackmd.io/@0V3cv8JJRnuK3jMwbJ-EeA/SJ1IyBWi-l) can be used as [buffer amplifier](https://www.electronics-tutorials.ws/opamp/opamp_3.html) to reasonably reduce the sampling cycles, so the ADC can be more responsive and still get stable samples. ## Reference - [Hack the soil snesor - Underwater Arduino Data Loggers](https://thecavepearlproject.org/2020/10/27/hacking-a-capacitive-soil-moisture-sensor-for-frequency-output/) - [Capacitive Soil Moisture Sensors don't work correctly + Fix for v2.0 v1.2](https://www.youtube.com/watch?v=IGP38bz-K48&t=438s) - [Impedance - Electronic Tutorial](https://www.electronics-tutorials.ws/accircuits/impedance.html) - [Waveform and Signal Types - Electronic Tutorial](https://www.electronics-tutorials.ws/waveforms/waveforms.html) - [Passive Low-Pass Filter - Electronic Tutorial](https://www.electronics-tutorials.ws/filter/filter_2.html) - [TLC555 CMOS timer datasheet](https://www.ti.com/lit/ds/symlink/tlc555.pdf) - [What is the purpose of the diode in this peak detector? -- EE StackExchange](https://electronics.stackexchange.com/q/605547/549311) - [How to set up ADC sampling time - STM32 forum](https://community.st.com/t5/stm32-mcus-products/how-to-set-up-the-adc-sampling-time/td-p/157703)