Why do you want a countdown in the first place?
I would rather use a 2 point controller.
Here the changed code, but not checked everything...
main.py:temperature.py
I would rather use a 2 point controller.
Here the changed code, but not checked everything...
main.py:
Code:
#!/home/brewmaster/projects/autoferment/venv/bin/python3"""The purpose of this program is to take temperature readings from a DS18B20 temperaturesensor (function), write to a file in CSV format (for export to excel), and print what is going into thefile on an LCD screen"""import datetimefrom dataclasses import dataclassimport subprocessimport timefrom gpiozero import Button, OutputDevicefrom RPLCD.i2c import CharLCDfrom temperature import read_temperatureRELAY_PIN = 17MIN_TEMP = 24MAX_TEMP = 26STOP_BUTTON = 27@dataclassclass Heater: """ https://en.wikipedia.org/wiki/Bang%E2%80%93bang_control """ min_temp: float max_temp: float relay: OutputDevice last: bool | None = None def set_state(self, degree_celsius) -> tuple[bool, bool]: """ If the heater is off, then the temperature must be lower than min_temp to switch the heater on If the heater is on, then the temperature must be higher than max_temp to switch the heater off """ # getting the first time the current state of the output if self.last is None: # if active_high is False, then the signal is inverted self.last = bool(self.relay.value ^ self.relay.active_high) _last = self.last if self.last and degree_celsius > self.max_temp: self.last = False elif not self.last and degree_celsius < self.min_temp: self.last = True changed = _last != self.last if changed: if self.last: # the method on and off does the right thing, # even if active_high is False self.relay.on() else: self.relay.off() return changed, self.lastdef temp_display(heater: Heater, lcd: CharLCD): celsius, fahrenheit = read_temperature() if celsius is None: return with open("Ferment Log.txt", "a+") as fd: fd.write( f"{datetime.datetime.now():%m/%d/%Y,%H:%M:%S},Temperatures:{celsius},{fahrenheit}" ) fd.write("\n") lcd.clear() lcd.write_string(f"Temp: {celsius:.2f}°C") # the method heater.set_state also activates/deactivates the relay state_changed, new_state = heater.set_state(celsius) if state_changed: if new_state: print("Power on", celsius) else: print("Power off", celsius)def main(heater, lcd): while True: temp_display(heater, lcd) time.sleep(1)def shutdown(): subprocess.run(["shutdown", "-h", "now"])stopButton = Button(STOP_BUTTON)stopButton.when_activated = shutdownrelay = OutputDevice(RELAY_PIN, active_high=False, initial_value=True)lcd = CharLCD(i2c_expander="PCF8574", address=0x27, port=1, cols=16, rows=2, dotsize=8)heater = Heater(min_temp=MIN_TEMP, max_temp=MAX_TEMP, relay=relay)try: main(heater, lcd)except KeyboardInterrupt: lcd.clear() lcd.write_string("Cancelled by\n\rUser")
Code:
"""The purpose of this script is to take temperature readings from a DS18B20 temperaturesensor, then have the function return the temperature in F and Celcius"""import reimport subprocessfrom pathlib import PathDEVICE = "28-3ce1e3809a4e"MODULES = ("w1-gpio", "w1-therm")for module in MODULES: subprocess.run(["modprobe", module])def read_temperature(device: str | None = None) -> tuple[float | None, float | None]: """ 24 01 4b 46 7f ff 0c 10 48 : crc=48 YES 24 01 4b 46 7f ff 0c 10 48 t=18250 18.25 °C """ device = device or DEVICE sensor_data = Path("/sys/bus/w1/devices/").joinpath(DEVICE, "w1_slave").read_text() if not re.search(r"crc=\d+ YES", sensor_data): return None, None if match := re.search(r"t=(\d+)", sensor_data): celsius = int(match.group(1)) / 1_000 fahrenheit = celsius * 9 / 5 + 32 return celsius, fahrenheit return None, None
Statistics: Posted by DeaD_EyE — Mon Sep 02, 2024 8:07 pm