import machine
import utime
from machine import Pin, PWM, ADC, I2C
from i2c_lcd import I2cLcd
import neopixel
# --- PIN CONFIGURATION ---
i2c = I2C(0, sda=Pin(21), scl=Pin(22), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
pot = ADC(Pin(34))
ldr = ADC(Pin(35))
pot.atten(ADC.ATTN_11DB)
btn_lang = Pin(15, Pin.IN, Pin.PULL_UP)
sw_help = Pin(2, Pin.IN, Pin.PULL_DOWN)
path_led = Pin(19, Pin.OUT)
servo = PWM(Pin(18), freq=50)
buzzer = PWM(Pin(5))
np = neopixel.NeoPixel(Pin(4), 16)
row_pins = [13, 12, 14, 27]
col_pins = [26, 25, 33, 32]
rows = [Pin(pin, Pin.OUT) for pin in row_pins]
cols = [Pin(pin, Pin.IN, Pin.PULL_DOWN) for pin in col_pins]
keys = [['1', '2', '3', 'A'],['4', '5', '6', 'B'],['7', '8', '9', 'C'],['*', '0', '#', 'D']]
# --- HELPER FUNCTIONS ---
def read_keypad():
for r_idx, row_pin in enumerate(rows):
row_pin.on()
for c_idx, col_pin in enumerate(cols):
if col_pin.value() == 1:
utime.sleep(0.05)
row_pin.off()
return keys[r_idx][c_idx]
row_pin.off()
return None
def set_ring_color(r, g, b):
for i in range(16):
np[i] = (r, g, b)
np.write()
# --- INITIALIZATION ---
lang_mode = 0 # 0=English, 1=Malay, 2=Chinese
last_switch_state = 0
lcd.clear()
utime.sleep_ms(50)
lcd.putstr("EquiShop\nReady to scan!")
set_ring_color(0, 0, 0)
servo.duty(115)
utime.sleep(1)
# --- MAIN LOOP ---
while True:
# 1. KEYPAD ITEM LOOKUP
key = read_keypad()
if key:
lcd.clear()
utime.sleep_ms(50)
if key == '1':
if lang_mode == 0: item_msg = "BREAD: RM3.00"
elif lang_mode == 1: item_msg = "ROTI: RM3.00"
else: item_msg = "MIAN BAO: RM3.00"
lcd.putstr("Code 1 Entered")
lcd.move_to(0, 1)
lcd.putstr(item_msg)
set_ring_color(0, 255, 0)
utime.sleep(2)
elif key == '2':
if lang_mode == 0: item_msg = "MILK: RM4.50"
elif lang_mode == 1: item_msg = "SUSU: RM4.50"
else: item_msg = "NIU NAI: RM4.50"
lcd.putstr("Code 2 Entered")
lcd.move_to(0, 1)
lcd.putstr(item_msg)
set_ring_color(0, 0, 255)
utime.sleep(2)
# 2. LANGUAGE TOGGLE (English -> Malay -> Chinese)
if not btn_lang.value():
lang_mode = (lang_mode + 1) % 3
lcd.clear()
utime.sleep_ms(50)
if lang_mode == 0: lcd.putstr("English")
elif lang_mode == 1: lcd.putstr("Bahasa Melayu")
else: lcd.putstr("Zhong Wen")
utime.sleep(1)
# 3. PRODUCT SCANNER (POTENTIOMETER)
scan_val = pot.read()
lcd.move_to(0, 1)
if scan_val < 1300:
if lang_mode == 0: item = "BREAD RM3.00"
elif lang_mode == 1: item = "ROTI RM3.00"
else: item = "MIAN BAO RM3.00"
set_ring_color(0, 255, 0)
elif scan_val < 2800:
if lang_mode == 0: item = "PEANUTS (!!!)"
elif lang_mode == 1: item = "KACANG (!!!)"
else: item = "HUA SHENG (!!!)"
set_ring_color(255, 0, 0)
buzzer.freq(880); buzzer.duty(512); utime.sleep(0.1); buzzer.duty(0)
else:
if lang_mode == 0: item = "MILK RM4.50"
elif lang_mode == 1: item = "SUSU RM4.50"
else: item = "NIU NAI RM4.50"
set_ring_color(0, 0, 255)
lcd.putstr(item + " ")
# 4. EMERGENCY ASSISTANCE
current_state = sw_help.value()
if current_state == 1:
servo.duty(40)
if last_switch_state == 0:
print("ALERT: Help Flag Raised!")
last_switch_state = 1
else:
servo.duty(115)
if last_switch_state == 1:
print("Help Flag Down.")
last_switch_state = 0
# 5. NIGHT LIGHT
if ldr.read() > 2000:
path_led.on()
else:
path_led.off()
utime.sleep(0.1)