import machine
import time
from dht import DHT22 # Assuming you have dht module for DHT22 sensor
from i2c_lcd import I2cLcd # Adjust this import based on your specific library name
# Pin Definitions
v_pot_pin = 36 # GPIO 36 (ADC1)
c_pot_pin = 39 # GPIO 39 (ADC2)
dht_pin = 16 # GPIO 16 for DHT22 sensor
step_pin = 17 # GPIO 17 for stepper motor step
dir_pin = 18 # GPIO 18 for stepper motor direction
enable_pin = 19 # GPIO 19 for stepper motor enable
i2c_scl_pin = 22 # GPIO 22 for I2C SCL
i2c_sda_pin = 21 # GPIO 21 for I2C SDA
# Default I2C address for your LCD
DEFAULT_I2C_ADDR = 0x27 # Adjust this based on your LCD configuration
# Initialize ADC for voltage and current levels
v_pot = machine.ADC(machine.Pin(v_pot_pin))
c_pot = machine.ADC(machine.Pin(c_pot_pin))
# Initialize DHT22 sensor
dht_sensor = DHT22(machine.Pin(dht_pin))
# Initialize stepper motor pins
stepper_step = machine.Pin(step_pin, machine.Pin.OUT)
stepper_dir = machine.Pin(dir_pin, machine.Pin.OUT)
stepper_enable = machine.Pin(enable_pin, machine.Pin.OUT)
# Initialize I2C and LCD display
i2c = machine.I2C(0, scl=machine.Pin(i2c_scl_pin), sda=machine.Pin(i2c_sda_pin))
lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16) # Adjust address and dimensions as needed
# Variables
high_temp_threshold = 35 # Threshold temperature in Celsius
display_interval = 200 # Display update interval in milliseconds
last_display_update = 0 # Last display update time
# Calibration constants
VOLTAGE_DIVIDER_RATIO = 11.0 # Example ratio for a 10k/1k voltage divider
CURRENT_SENSOR_RATIO = 0.066 # Example ratio for a 50A/3.3V current sensor
# Function to read voltage level from the potentiometer and convert to actual voltage
def read_voltage_level():
raw_value = v_pot.read()
voltage = raw_value * 3.3 / 4095 * VOLTAGE_DIVIDER_RATIO # Adjust based on ADC resolution and voltage divider ratio
return voltage
# Function to read current level from the potentiometer and convert to actual current
def read_current_level():
raw_value = c_pot.read()
current = raw_value * 3.3 / 4095 / CURRENT_SENSOR_RATIO # Adjust based on ADC resolution and current sensor ratio
return current
# Function to control the stepper motor based on temperature
def control_stepper_by_temp(temperature):
if temperature is not None and temperature > high_temp_threshold:
control_stepper(True)
else:
control_stepper(False)
# Function to control the stepper motor
def control_stepper(state):
stepper_enable.value(not state) # Enable the stepper driver
if state:
stepper_dir.on()
for _ in range(200): # Example stepper movement
stepper_step.on()
time.sleep_us(1000)
stepper_step.off()
time.sleep_us(1000)
else:
stepper_step.off()
stepper_dir.off()
# Overcurrent and Overvoltage Protection
MAX_VOLTAGE = 35.1 # Example maximum voltage threshold
MAX_CURRENT = 45 # Example maximum current threshold
def check_protection(voltage, current):
if voltage > MAX_VOLTAGE:
print("Overvoltage detected! Shutting down system.")
# Add code to safely shut down the system or disconnect the battery
if current > MAX_CURRENT:
print("Overcurrent detected! Shutting down system.")
# Add code to safely shut down the system or disconnect the battery
# Main Loop
while True:
# Read voltage and current levels
voltage_level = read_voltage_level()
current_level = read_current_level()
voltage_level = read_voltage_level()
current_level = read_current_level()
# Check for overcurrent and overvoltage conditions
check_protection(voltage_level, current_level)
# Read temperature from DHT22
try:
dht_sensor.measure()
temperature = dht_sensor.temperature()
humidity = dht_sensor.humidity()
except OSError as e:
print("Failed to read from DHT22 sensor")
temperature = None
humidity = None
# Temperature-based stepper control
control_stepper_by_temp(temperature)
# Battery status determination (this is a simplified example, adjust as necessary)
if voltage_level < 3.0:
battery_status = "Low"
elif 3.0 <= voltage_level < 3.7:
battery_status = "Medium"
else:
battery_status = "High"
# Update LCD display every 200 ms
current_time = time.ticks_ms()
if time.ticks_diff(current_time, last_display_update) > display_interval:
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("V: {:.2f}V C: {:.2f}A".format(voltage_level, current_level))
lcd.move_to(0, 1)
lcd.putstr("Temp: {:.1f}C".format(temperature if temperature is not None else 0))
lcd.move_to(10, 1)
lcd.putstr(battery_status)
last_display_update = current_time
time.sleep_ms(10) # Small delay to reduce CPU usage