99 lines
2.8 KiB
Python
99 lines
2.8 KiB
Python
###
|
|
# GND ADC VCC
|
|
# | | |
|
|
# R1 | |
|
|
# | | |
|
|
# |______| |
|
|
# | |
|
|
# R2_1 |
|
|
# | |
|
|
# R2_2 |
|
|
# | |
|
|
# ... ...
|
|
# | |
|
|
# ~~~~~WATER~~~~~~~~~
|
|
# | - current - -|
|
|
# R2_n |
|
|
#
|
|
#
|
|
# VCC gets toggeled by 'power_pin', so current doesn't flow continously.
|
|
#
|
|
# To have equal distances between the voltages following calculation can be used:
|
|
# r2 = [r1/(1-i/n) - r1/(1-(i-1)/n) for i in range(1,n)]
|
|
#
|
|
# example for
|
|
# n = 4 # 4 r2 resistors
|
|
# r1 = 10000 # 10k Ohms Resistor to GND
|
|
# gives resistance values:
|
|
# -> r2_1 := 3333.3 (~3300 Ohm)
|
|
# -> r2_2 := 6666.7 (~6800 Ohm)
|
|
# -> r2_3 := 20000.0
|
|
#
|
|
###
|
|
|
|
from machine import Pin, ADC
|
|
# import uasyncio as asyncio
|
|
import time
|
|
|
|
|
|
class WaterLevelSensor:
|
|
def __init__(
|
|
self,
|
|
power_pin=Pin(26),
|
|
adc_pin=Pin(35),
|
|
resistor_ground=10000,
|
|
resistors_water=[3300, 6800, 20000],
|
|
resistance_water_tolerance=[400, 550, 700, 850],
|
|
volume_liter=11*9*8.5/1000):
|
|
|
|
self.power_pin = power_pin
|
|
self.power_pin.init(mode=Pin.OUT, value=0)
|
|
|
|
self.adc_pin = adc_pin
|
|
self.adc = ADC(self.adc_pin)
|
|
self.adc.atten(ADC.ATTN_11DB)
|
|
|
|
self._r1 = resistor_ground
|
|
self._r2 = resistors_water
|
|
self.resistance_water_tolerance = resistance_water_tolerance
|
|
self._voltage_levels = \
|
|
[4096 * self._r1 / (self._r1 + sum(self._r2[:i]))
|
|
for i in range(len(self._r2), 0, -1)]
|
|
print(self._voltage_levels)
|
|
|
|
self.min_measure_time_ms = 500
|
|
self._last_measurment_time_ms = time.ticks_diff(time.ticks_ms(), 500)
|
|
self._last_level_rel = 0
|
|
|
|
self.volume = volume_liter
|
|
# asyncio.create_task(self._polling())
|
|
# from waterlevel_sensor import WaterLevelSensor; wls = WaterLevelSensor()
|
|
|
|
def _measure_value(self):
|
|
self.power_pin.on()
|
|
self._last_measure = self.adc.read()
|
|
self.power_pin.off()
|
|
return self._last_measure
|
|
|
|
@property
|
|
def _level_rel(self):
|
|
now = time.ticks_ms()
|
|
if time.ticks_diff(now, self._last_measurment_time_ms) \
|
|
> self.min_measure_time_ms:
|
|
self._last_measurment_time_ms = now
|
|
adc_value = self._measure_value()
|
|
for i, voltage in enumerate(self._voltage_levels):
|
|
if adc_value >= voltage - self.resistance_water_tolerance[i]:
|
|
self._last_level_rel = (i / (len(self._voltage_levels)))
|
|
else:
|
|
break
|
|
return self._last_level_rel
|
|
|
|
@property
|
|
def level(self):
|
|
return self._level_rel * self.volume
|
|
|
|
@property
|
|
def level_percent(self):
|
|
return self._level_rel * 100
|