from machine import Pin, I2C, ADC
import time
import random
# ── Inline I2C LCD driver ─────────────────────────────────────────────
class LCD:
def __init__(self, i2c, addr=0x27):
self.i2c = i2c
self.addr = addr
self._bl = 0x08
self._init()
def _write_byte(self, b):
self.i2c.writeto(self.addr, bytes([b | self._bl]))
def _pulse(self, b):
self._write_byte(b | 0x04)
time.sleep_us(1)
self._write_byte(b & ~0x04)
time.sleep_us(50)
def _send(self, b, mode=0):
self._pulse(mode | (b & 0xF0))
self._pulse(mode | ((b << 4) & 0xF0))
def _init(self):
time.sleep_ms(50)
for v in (0x30, 0x30, 0x30, 0x20):
self._pulse(v)
time.sleep_ms(5)
for cmd in (0x28, 0x0C, 0x06, 0x01):
self._send(cmd)
time.sleep_ms(2)
def clear(self):
self._send(0x01)
time.sleep_ms(2)
def move_to(self, col, row):
self._send(0x80 | (col + (0x40 if row else 0)))
def putstr(self, s):
for c in s:
self._send(ord(c), mode=0x01)
# ── Hardware setup ────────────────────────────────────────────────────
i2c0 = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
lcd1 = LCD(i2c0, addr=0x27)
i2c1 = I2C(1, sda=Pin(2), scl=Pin(3), freq=400000)
lcd2 = LCD(i2c1, addr=0x27)
# Joystick vertical axis (ADC)
vert = ADC(Pin(26))
# ── Thresholds (robust ranges) ────────────────────────────────────────
UP_THRESHOLD = 15000 # UP zone
CENTER_LOW = 20000
CENTER_HIGH = 45000
DOWN_THRESHOLD = 50000 # DOWN zone
def show_idle():
lcd1.clear()
lcd1.putstr(" CASINO DICE 1 ")
lcd1.move_to(0, 1)
lcd1.putstr(" Push Lever UP ")
lcd2.clear()
lcd2.putstr(" CASINO DICE 2 ")
lcd2.move_to(0, 1)
lcd2.putstr(" Push Lever UP ")
def show_result(d1, d2):
win = (d1 == d2)
result = " YOU WIN! " if win else " Try Again "
lcd1.clear()
lcd1.putstr("Dice1: [{}]".format(d1))
lcd1.move_to(0, 1)
lcd1.putstr(result)
lcd2.clear()
lcd2.putstr("Dice2: [{}]".format(d2))
lcd2.move_to(0, 1)
lcd2.putstr(result)
# ── Startup ───────────────────────────────────────────────────────────
show_idle()
was_up = False
# ── Main loop ─────────────────────────────────────────────────────────
while True:
val = vert.read_u16()
# print(val) # Uncomment if debugging
# Detect UP movement safely
is_up = val < UP_THRESHOLD
# Rising edge → trigger dice roll
if is_up and not was_up:
time.sleep_ms(50) # debounce
d1 = random.randint(1, 6)
d2 = random.randint(1, 6)
show_result(d1, d2)
# When lever returns to center → reset screen
if (CENTER_LOW < val < CENTER_HIGH) and was_up:
time.sleep_ms(300)
show_idle()
was_up = is_up
time.sleep_ms(50)