from machine import I2C, Pin, ADC
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd
import time
from math import log
#Defining Pin numbers
I2C_ADDR = 0x27 #I2C address for LCD
THERMISTOR_PIN = 27 #ADC pin for temperature sensor
#Thermistor's characteristics
SERIES_RESISTOR = 10000 #Resistance in Ohms
BETA = 3950 #B-value for thermistor
ADC_MAX = 65535 #16-bit ADC Max value
#LCD's characteristics
LCD_ROWS = 2
LCD_COLUMNS = 16
UPDATE_INTERVAL = 1 #Time between updates given in seconds
#Setting up I2C for the LCD
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=100000)
lcd = I2cLcd(i2c, I2C_ADDR, LCD_ROWS, LCD_COLUMNS)
#Defining the PLC output channels as input pins
plc_inputs = {
"FILL": Pin(18, Pin.IN, Pin.PULL_DOWN),
"WASH": Pin(19, Pin.IN, Pin.PULL_DOWN),
"DRAIN": Pin(20, Pin.IN, Pin.PULL_DOWN),
"SPIN": Pin(21, Pin.IN, Pin.PULL_DOWN)
}
#Temperature reading function
def read_temperature():
adc = ADC(Pin(THERMISTOR_PIN))
analog_value = adc.read_u16() # Reads the ADC value between 0-65535
#Calculate resistance using voltage divider formula
Resistance = SERIES_RESISTOR / (ADC_MAX / analog_value - 1)
#Calculate temperature in Celsius using the Beta formula
Celsius = 1 / (log(Resistance / SERIES_RESISTOR) / BETA + 1 / 298.15) - 273.15
#Checking if the teperature is within 0-60 celsisus
if Celsius < 0:
return "Temp: Too Low"
elif Celsius > 60:
return "Temp: Too High"
return "Temp: {:.1f}C".format(Celsius)
#Function to update the LCD display
def update_display(status, temperature_msg):
lcd.clear() #Clears LCD with each update
#Displays status and temperature
lcd.putstr("Status: {}\n".format(status))
lcd.putstr(temperature_msg)
#Function to determine the current washer status
def get_washer_status():
for mode, pin in plc_inputs.items():
if pin.value() == 1:
return mode #Returns to the active mode
return "IDLE" #Default status if none of the modes are active
#Main loop
previous_status = None
previous_temperature_msg = None
while True:
status = get_washer_status()
try:
temperature_msg = read_temperature()
except Exception as e:
temperature_msg = "Temp: Error" #Displays to indicate an issue
#Updates the display only if the status or temperature message has changed
if status != previous_status or temperature_msg != previous_temperature_msg:
update_display(status, temperature_msg)
previous_status = status
previous_temperature_msg = temperature_msg
time.sleep(UPDATE_INTERVAL) #Updates in specified time