## v2.0 schematic
Note that v1.2 sensor has similar circuit wiring with different capacitors / resistors' value and time chip (NE555)

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