from machine import ADC, Pin import time class ECSensor: VREF = 3.3 ADC_RESOLUTION = 65535 NUM_SAMPLES = 10 R1 = 820.0 R2 = 200.0 ECREF = 1000.0 def __init__(self, ec_pin, button_pin, temp_sensor=None): self.adc = ADC(Pin(ec_pin)) self.button = Pin(button_pin, Pin.IN, Pin.PULL_UP) self.temp_sensor = temp_sensor self.kvalue_low = 1.0 self.kvalue_high = 1.0 self.kvalue = 1.0 self.load_calibration() def average_readings(self): total = 0 for _ in range(self.NUM_SAMPLES): total += self.read_adc_raw() time.sleep(0.2) return total / self.NUM_SAMPLES def read_adc_raw(self): return self.adc.read_u16() def read_voltage(self, raw): return (raw / self.ADC_RESOLUTION) * self.VREF def read_temperature(self, samples=1): temp = 22.0 if self.temp_sensor is None: temp = 22.0 else: temp = self.temp_sensor.read_temp(samples=samples) print(f"Temperature reading: {temp} C") return temp def read_ec(self, voltage, temperature): raw_ec = self.ECREF * voltage / (self.R1 * self.R2) value_temp = raw_ec * self.kvalue if value_temp > 2.5: self.kvalue = self.kvalue_high elif value_temp < 2.0: self.kvalue = self.kvalue_low value = raw_ec * self.kvalue value = value / (1.0 + 0.0185 * (temperature - 25.0)) return value def calibration(self, voltage, temperature, level): raw_ec = self.ECREF * voltage / (self.R1 * self.R2) if level == "low": comp_ec_solution = 1.413 * (1.0 + 0.0185 * (temperature - 25.0)) kvalue_temp = self.R1 * self.R2 * comp_ec_solution / self.ECREF / voltage self.kvalue_low = round(kvalue_temp, 2) print("Low K = ", self.kvalue_low) self.save_calibration() elif level == "high": comp_ec_solution = 12.88 * (1.0 + 0.0185 * (temperature - 25.0)) kvalue_temp = self.R1 * self.R2 * comp_ec_solution / self.ECREF / voltage self.kvalue_high = round(kvalue_temp, 2) print("High K = ", self.kvalue_high) self.save_calibration() else: print("Buffer Solution Error Try Again") def save_calibration(self): try: with open('ecdata.txt', 'w') as f: f.write(f'kvalueLow={self.kvalue_low}\n') f.write(f'kvalueHigh={self.kvalue_high}\n') print("Calibration saved successfully.") except OSError as e: print("Failed to save calibration:", e) def load_calibration(self): try: with open('ecdata.txt', 'r') as f: self.kvalue_low = float(f.readline().strip('kvalueLow=\n')) self.kvalue_high = float(f.readline().strip('kvalueHigh=\n')) print(f'Loaded kvalue_low={self.kvalue_low}, kvalue_high={self.kvalue_high}') except OSError: print("Failed to load calibration. Please calibrate.") def reset_calibration(self): self.kvalue_low = 1.0 self.kvalue_high = 1.0 self.save_calibration() print("Reset to default parameters") def wait_for_button_press(self): print("Press the button to continue...") while self.button.value(): time.sleep(0.1) while not self.button.value(): time.sleep(0.1) def calibrate(self): print("Starting calibration process...") self.load_calibration() print("Place the probe into the 1.413ms/cm calibration solution.") self.wait_for_button_press() print('Calibrating, please wait...') raw_average = self.average_readings() voltage_average = self.read_voltage(raw_average) temperature = self.read_temperature(samples=3) self.calibration(voltage_average, temperature, "low") print("Place the probe into the 12.88ms/cm calibration solution.") self.wait_for_button_press() print('Calibrating, please wait...') raw_average = self.average_readings() voltage_average = self.read_voltage(raw_average) temperature = self.read_temperature(samples=3) self.calibration(voltage_average, temperature, "high") print("Calibration process completed.") def main_loop(self): while True: raw = self.read_adc_raw() voltage = self.read_voltage(raw) temperature = self.read_temperature() ec_value = self.read_ec(voltage, temperature) print(f"Voltage: {voltage}V, EC: {ec_value:.2f} mS/cm") time.sleep(1) def get_ec_reading(self, samples=1): if samples < 1: raise ValueError("Samples must be 1 or more.") total_voltage = 0 total_ec = 0 for _ in range(samples): raw = self.read_adc_raw() voltage = self.read_voltage(raw) temperature = self.read_temperature() ec_value = self.read_ec(voltage, temperature) total_voltage += voltage total_ec += ec_value time.sleep(0.1) # Sleep to allow some time between readings, if necessary average_voltage = total_voltage / samples average_ec = total_ec / samples return average_ec if __name__ == "__main__": ec_sensor = ECSensor(ec_pin=26, button_pin=29) ec_sensor.main_loop()