import network
import _thread
import time
from machine import Pin
import machine
from pico_i2c_lcd import I2cLcd
from umqtt_simple import MQTTClient
from hx711 import HX711 # Library for HX711 load cell amplifiers
# Wi-Fi credentials
WIFI_SSID = "Wokwi-GUEST"
WIFI_PASSWORD = ""
# Adafruit IO credentials
ADAFRUIT_AIO_USERNAME = "preethi_kannan"
ADAFRUIT_AIO_KEY = "aio_Rqyc95apVwXs8gn0wzAGxVQiDxXV"
# MQTT settings
BROKER = "io.adafruit.com"
FOOD_AVAILABLE_FEED = f"{ADAFRUIT_AIO_USERNAME}/feeds/food"
WAIT_TIME_FEED = f"{ADAFRUIT_AIO_USERNAME}/feeds/queue"
WAIT_TIME_GRAPH = f"{ADAFRUIT_AIO_USERNAME}/feeds/queue"
# I2C Pins for LCD
i2c = machine.I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16) # 2x16 LCD display
# Load cell setup for three load cells
DT1 = 5 # Data pin for HX711 of Load Cell 1
SCK1 = 18 # Clock pin for HX711 of Load Cell 1
DT2 = 19 # Data pin for HX711 of Load Cell 2
SCK2 = 20 # Clock pin for HX711 of Load Cell 2
DT3 = 21 # Data pin for HX711 of Load Cell 3
SCK3 = 22 # Clock pin for HX711 of Load Cell 3
AVERAGE_WEIGHT = 65.0 # Average weight of a college student in kilograms
CALIBRATION_FACTOR = 210.0 # Calibration factor for HX711 (adjust as needed)
# Initialize HX711 for three load cells
load_cell_1 = HX711(dout=DT1, pd_sck=SCK1)
load_cell_2 = HX711(dout=DT2, pd_sck=SCK2)
load_cell_3 = HX711(dout=DT3, pd_sck=SCK3)
# Food dictionary
food_dict = {
"1234": "veg fried rice",
"5678": "channa masala",
"1256": "battura"
}
current_food = [] # List of available food items
# Keypad setup (Example: 4x4 keypad matrix)
rows = [Pin(i, Pin.OUT) for i in [13, 12, 11, 10]] # Adjust pins for your setup
cols = [Pin(i, Pin.IN, Pin.PULL_DOWN) for i in [9, 8, 7, 6]]
key_map = [
['1', '2', '3', 'A'],
['4', '5', '6', 'B'],
['7', '8', '9', 'C'],
['*', '0', '#', 'D']
]
# Load cell setup and calibration
def setup_load_cells():
"""Set up and calibrate the load cells."""
load_cell_1.set_scale(CALIBRATION_FACTOR)
load_cell_2.set_scale(CALIBRATION_FACTOR)
load_cell_3.set_scale(CALIBRATION_FACTOR)
load_cell_1.tare()
load_cell_2.tare()
load_cell_3.tare()
print("Load cells calibrated and ready.")
# Measure total weight using all load cells
def measure_total_weight():
"""Measure the total weight using all three load cells."""
weight1 = load_cell_1.get_grams(5) # Average of 10 readings for Load Cell 1
weight2 = load_cell_2.get_grams(5) # Average of 10 readings for Load Cell 2
weight3 = load_cell_3.get_grams(5) # Average of 10 readings for Load Cell 3
total_weight = weight1 + weight2 + weight3
return max(0, total_weight) # Ensure non-negative weight
# Calculate wait time
def calculate_wait_time(weight):
"""Calculate wait time based on the weight."""
estimated_people = int(weight / AVERAGE_WEIGHT)
wait_time = estimated_people * 2 # Assume 2 minutes per person
return wait_time
# Keypad scanning
def read_keypad():
"""Read input from the keypad."""
for row in rows:
row.value(1)
for col, col_pin in enumerate(cols):
if col_pin.value():
row.value(0)
return key_map[rows.index(row)][col]
row.value(0)
return None
# Wi-Fi connection
def connect_to_wifi():
"""Connect to Wi-Fi."""
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
print("Connecting to Wi-Fi...")
while not wlan.isconnected():
time.sleep(1)
print("Still connecting...")
print("Connected to Wi-Fi!")
print("Network config:", wlan.ifconfig())
# Publish message to MQTT
def mqtt_publish(client, topic, message):
"""Publish a message to an MQTT topic."""
try:
client.publish(topic, message)
print(f"Published to {topic}: {message}")
except Exception as e:
print(f"Failed to publish: {e}")
# Process keypad input
def process_keypad_input(client, input_code):
"""Process input from the keypad."""
global current_food
lcd.clear()
lcd.putstr(f"Input: {input_code}")
if input_code.endswith("#"): # Add food
item_code = input_code[:-1]
if item_code in food_dict and food_dict[item_code] not in current_food:
current_food.append(food_dict[item_code])
mqtt_publish(client, FOOD_AVAILABLE_FEED, "\n".join(current_food))
elif input_code.endswith("*"): # Remove food
item_code = input_code[:-1]
if item_code in food_dict and food_dict[item_code] in current_food:
current_food.remove(food_dict[item_code])
mqtt_publish(client, FOOD_AVAILABLE_FEED, "\n".join(current_food))
# Real-time wait time monitoring
def update_wait_time(client):
"""Continuously update wait time."""
while True:
total_weight = measure_total_weight()
print("total weight = ",total_weight)
wait_time = calculate_wait_time(total_weight)
mqtt_publish(client, WAIT_TIME_FEED, str(wait_time))
mqtt_publish(client, WAIT_TIME_GRAPH, str(wait_time))
time.sleep(5) # Update wait time every 5 seconds
# Main Program
connect_to_wifi()
print("connection function completed")
setup_load_cells()
print("load cell function completed")
client = MQTTClient("pico", BROKER, user=ADAFRUIT_AIO_USERNAME, password=ADAFRUIT_AIO_KEY)
client.connect()
mqtt_publish(client, WAIT_TIME_FEED, str(0))
mqtt_publish(client, FOOD_AVAILABLE_FEED, "")
try:
lcd.putstr("System Ready!")
time.sleep(2)
lcd.clear()
entered_code = ""
# Start the wait time update loop in a separate thread
_thread.start_new_thread(update_wait_time, (client,))
while True:
# Process keypad input
key = read_keypad()
if key:
lcd.clear()
if key == "#": # Finalize input
lcd.putstr(f"Processing {entered_code}")
process_keypad_input(client, entered_code + "#")
entered_code = ""
elif key == "*": # Remove food
lcd.putstr(f"Processing {entered_code}")
process_keypad_input(client, entered_code + "*")
entered_code = ""
else: # Append key
entered_code += key
lcd.putstr(f"Code: {entered_code}")
except KeyboardInterrupt:
print("Program stopped.")
finally:
mqtt_publish(client, WAIT_TIME_FEED, str(0))
mqtt_publish(client, FOOD_AVAILABLE_FEED, "")
client.disconnect()