from machine import Pin import time import json import os CALIB_FILE = "calibration.cfg" # --------------------------------------------------------- # Calibration File Helpers # --------------------------------------------------------- def save_calibration(zero_offset, scale_factor): """Save calibration values to internal flash.""" data = { "zero_offset": zero_offset, "scale_factor": scale_factor } with open(CALIB_FILE, "w") as f: json.dump(data, f) print("✔ Calibration saved.") def load_calibration(): """Load existing calibration or return defaults.""" if CALIB_FILE not in os.listdir(): print("⚠ No calibration file found, using defaults.") return 0, 1 try: with open(CALIB_FILE, "r") as f: data = json.load(f) print("✔ Calibration loaded.") return data.get("zero_offset", 0), data.get("scale_factor", 1) except Exception as e: print("⚠ Calibration load error:", e) return 0, 1 # --------------------------------------------------------- # HX710B Class # --------------------------------------------------------- class HX710B: def __init__(self, dout_pin, sck_pin): self.dout = Pin(dout_pin, Pin.IN) self.sck = Pin(sck_pin, Pin.OUT) self.sck.value(0) # Load previous calibration (or defaults) self.zero_offset, self.scale_factor = load_calibration() # ----------------------------------------------------- # Low-level raw ADC read # ----------------------------------------------------- def read_raw(self): """Read the 24-bit raw ADC value.""" while self.dout.value(): pass # wait for data ready count = 0 for _ in range(24): self.sck.value(1) count = (count << 1) | self.dout.value() self.sck.value(0) # 25th pulse to set gain for next reading self.sck.value(1) self.sck.value(0) # Signed 24-bit conversion if count & 0x800000: count -= 0x1000000 return count # ----------------------------------------------------- # Zero Calibration # ----------------------------------------------------- def calibrate_zero(self, samples=20): """Measure 0 kPa and determine zero offset.""" total = 0 for _ in range(samples): total += self.read_raw() time.sleep_ms(5) self.zero_offset = total / samples save_calibration(self.zero_offset, self.scale_factor) print("✔ Zero calibrated:", self.zero_offset) return self.zero_offset # ----------------------------------------------------- # Full-scale / Known Pressure Calibration # ----------------------------------------------------- def calibrate_full(self, known_kpa, samples=20): """Measure raw ADC at known pressure and compute scaling.""" total = 0 for _ in range(samples): total += self.read_raw() time.sleep_ms(5) raw_avg = total / samples self.scale_factor = known_kpa / (raw_avg - self.zero_offset) save_calibration(self.zero_offset, self.scale_factor) print("✔ Scale calibrated:", self.scale_factor) return self.scale_factor # ----------------------------------------------------- # Convert raw → kPa using saved calibration # ----------------------------------------------------- def read_kpa(self): raw = self.read_raw() return (raw - self.zero_offset) * self.scale_factor