Okay, so what we have, renaming the ADC lines for convenience later, is -
Let's assume the resitors are perfect, but the GPIO output voltages are not consistent. All voltages are measured with reference to some common 0V point. Thus we can do it all with single-ended ADC as per RP2040, will handle any differentials purely in software -In one direction 'FWD' we have -In the other direction, 'REV', we have -When we exercise both of those cases the host has the following information, and only this information -From that we want to calculate 'Rs'. That should be 330 for both cases -
That seems to be pretty close to me, on the desktop and the PIco, though my port of MicroPython has floats as doubles.
If we swap the resistors over, now know the 330, want to determine the 4700, that also works -So the principle of being able to determine a resistor value from three voltages and a known resistor, reading with current in either direction, looks to be proven.
Code:
GPIO22 >----.-------> Vh .|. Rh |_| 4700 | }-------> V .|. Rs |_| 330 | GPIO27 >----^-------> Vs
Code:
.-----.-----. | 1 | 0 | .--------|-----|-----| | GPIO22 | 3.2 | 0.1 | |--------|-----|-----| | GPIO27 | 3.1 | 0.6 | `--------^-----^-----^
Code:
GPIO22 3.2 >----.-------> Vh 3.2 .|. Rh |_| 4700 | }-------> V 0.770576540755 .|. Rs |_| 330 | GPIO27 0.6 >----^-------> Vs 0.6
Code:
GPIO27 3.1 >----.-------> Vs 3.1 .|. Rs |_| 330 | }-------> V 2.90318091451 .|. Rh |_| 4700 | GPIO22 0.1 >----^-------> Vh 0.1
Code:
.-----.-----. .-----.----------------.-----.------. | P22 | P27 | | Vh | V | Vs | Rh | .-----|-----|-----| |-----|----------------|-----|------| | FWD | 1 | 0 | | 3.2 | 0.770576540755 | 0.6 | 4700 | |-----|-----|-----| |-----|----------------|-----|------| | REV | 0 | 1 | | 0.1 | 2.90318091451 | 3.1 | 4700 | `-----^-----^-----' `-----^----------------^-----^------'
Code:
Vh, V, Vs, Rh = 3.2, 0.770576540755, 0.6, 4700Rs = Rh / (((Vh - Vs) / (V - Vs)) - 1)print("FWD Rs = {}".format(Rs))Vh, V, Vs, Rh = 0.1, 2.90318091451, 3.1, 4700Rs = ((Vs - Vh) * Rh / (V - Vh)) - Rhprint("REV Rs = {}".format(Rs))
Code:
pi@Pi3B:~/mypico/soil-sensor $ python3 soil-rs.pyFWD Rs = 329.9999999990328REV Rs = 330.00000000524415
Code:
pi@Pi3B:~/mypico/soil-sensor $ mpremote run soil-rs.pyFWD Rs = 329.9999999990328REV Rs = 330.0000000052441
If we swap the resistors over, now know the 330, want to determine the 4700, that also works -
Code:
.-----.-----. .-----.--------------------.-----.-----. | P22 | P27 | | Vh | V | Vs | Rs | .-----|-----|-----| |-----|--------------------|-----|-----| | FWD | 1 | 0 | | 3.2 | 3.029423459244533 | 0.6 | 330 | |-----|-----|-----| |-----|--------------------|-----|-----| | REV | 0 | 1 | | 0.1 | 0.2968190854870775 | 3.1 | 330 | `-----^-----^-----' `-----^--------------------^-----^-----'
Code:
Vh, V, Vs, Rs = 3.2, 3.029423459244533, 0.6, 330Rh = ((Vs - Vh) * Rs / (V - Vh)) - Rsprint("FWD Rh = {}".format(Rh))Vh, V, Vs, Rs = 0.1, 0.2968190854870775, 3.1, 330Rh = Rs / (((Vh - Vs) / (V - Vs)) - 1)print("REV Rh = {}".format(Rh))
Code:
pi@Pi3B:~/mypico/soil-sensor $ mpremote run soil-rh.pyFWD Rh = 4700.000000000002REV Rh = 4700.000000000005
Statistics: Posted by hippy — Sat May 04, 2024 4:02 pm