# ==========================================
# Semester 1 Project: Smart Entry System
# ESP32 Board 2: UART Receiver & LCD Display
# ==========================================
from machine import Pin, I2C, UART
import time
from machine_i2c_lcd import I2cLcd
# --- I2C LCD Configuration ---
i2c_bus = I2C(0, scl=Pin(22), sda=Pin(21))
i2c_devices = i2c_bus.scan()
if not i2c_devices:
raise RuntimeError("No I2C devices found. Check wiring!")
lcd_display = I2cLcd(i2c_bus, i2c_devices[0], 2, 16)
# --- UART Configuration ---
# Important wiring note: Ensure TX on board 1 is connected to RX on board 2 and vice versa.
uart_conn = UART(1, baudrate=9600, tx=Pin(17), rx=Pin(16), timeout=1000, timeout_char=100)
# --- Display Functions ---
def display_sensor_data(temp, humidity, object_near, door_state, gas_leak):
lcd_display.clear() # Clear the display for new data
# Top Priority: Gas leak warning
if gas_leak == 1:
lcd_display.move_to(1, 0)
lcd_display.putstr("!! GAS LEAK !!")
lcd_display.move_to(1, 1)
lcd_display.putstr("Evacuate Area!") # Additional warning message
else:
# Normal State: Display temp, humidity, and door status
# First line (Temperature & Humidity)
line1_text = "T:{:.1f}C H:{:.0f}%".format(temp, humidity)
lcd_display.move_to(0, 0)
lcd_display.putstr(line1_text)
# Second line (Door Status)
if door_state == 1:
door_text = "Door: Open"
else:
door_text = "Door: Closed"
lcd_display.move_to(0, 1)
lcd_display.putstr(door_text)
def display_waiting_screen():
lcd_display.clear()
lcd_display.move_to(2, 0)
lcd_display.putstr("Waiting Data")
lcd_display.move_to(5, 1)
lcd_display.putstr("(^_^)")
# --- System Initialization ---
display_waiting_screen()
previous_data_tuple = None
uart_data_buffer = bytearray()
print("Board 2 is ready and waiting for UART data...")
# ==========================================
# --- Main Loop ---
# ==========================================
while True:
if uart_conn.any():
uart_chunk = uart_conn.readline()
if uart_chunk:
uart_data_buffer.extend(uart_chunk)
# Process data line by line to prevent data overlap/crashes
while b"\n" in uart_data_buffer:
# Extract one complete line
line, _, remainder = uart_data_buffer.partition(b"\n")
uart_data_buffer = bytearray(remainder)
try:
csv_data = line.decode("utf-8", "ignore").strip()
except UnicodeError:
print("Ignoring invalid UART bytes")
continue
if not csv_data:
continue
print("Received:", csv_data)
data_parts = csv_data.split(",")
# Ensure the message contains exactly 5 values
if len(data_parts) != 5:
print("Invalid message format:", csv_data)
continue
# Extra protection (try/except) in case corrupted data is received (e.g., letters instead of numbers)
try:
current_temp = float(data_parts[0])
current_humidity = float(data_parts[1])
numeric_object_near = int(data_parts[2])
numeric_door_state = int(data_parts[3])
numeric_gas_leak = int(data_parts[4])
# Group current readings for comparison
current_data_tuple = (
current_temp,
current_humidity,
numeric_object_near,
numeric_door_state,
numeric_gas_leak
)
# Update the LCD *only* if the data has changed (prevents screen flickering)
if current_data_tuple != previous_data_tuple:
display_sensor_data(
current_temp,
current_humidity,
numeric_object_near,
numeric_door_state,
numeric_gas_leak
)
print("Object State (Near):", numeric_object_near)
previous_data_tuple = current_data_tuple
except ValueError:
print("Data conversion error. Waiting for clean data...")
time.sleep_ms(20)