from machine import Pin, I2C, ADC
from ssd1306 import SSD1306_I2C
import time
import dht
import random
# -------- OLED --------
i2c = I2C(1, scl=Pin(27), sda=Pin(26))
oled = SSD1306_I2C(128, 64, i2c)
# -------- Sensors --------
sensor = dht.DHT22(Pin(2))
ldr = ADC(28)
button = Pin(5, Pin.IN, Pin.PULL_UP)
# -------- Variables --------
screen = 0
last_switch = time.ticks_ms()
last_button = 0
ticker = "Welcome to Smart Kiosk "
scroll_x = 0
idle_mode = True
# -------- DRAW EYES --------
def draw_eyes(blink=False, offset=0):
oled.fill(0)
left_x = 30 + offset
right_x = 80 + offset
y = 25
# -------- OVAL FUNCTION --------
def draw_oval(cx, cy, w, h):
for x in range(-w//2, w//2):
for y1 in range(-h//2, h//2):
if (x*x)/(w*w/4) + (y1*y1)/(h*h/4) <= 1:
oled.pixel(cx + x, cy + y1, 1)
# -------- DRAW EYES --------
if blink:
draw_oval(left_x+10, y+10, 20, 4)
draw_oval(right_x+10, y+10, 20, 4)
else:
draw_oval(left_x+10, y+10, 20, 16)
draw_oval(right_x+10, y+10, 20, 16)
# -------- EYEBROWS --------
oled.line(left_x, y-2, left_x+20, y-6, 1)
oled.line(right_x, y-6, right_x+20, y-2, 1)
# -------- MOUTH --------
# Happy curved mouth (simple arc effect using pixels)
mouth_x = 50
mouth_y = 50
for i in range(0, 28):
curve = int((i - 14)**2 / 25) # parabola curve
oled.pixel(mouth_x + i, mouth_y + curve, 1)
oled.show()
# -------- WAKE-UP ANIMATION --------
def wakeup_animation():
# closed
oled.fill(0)
oled.fill_rect(30, 32, 20, 3, 1)
oled.fill_rect(80, 32, 20, 3, 1)
oled.show()
time.sleep(0.25)
# small open
oled.fill(0)
oled.fill_rect(30, 28, 20, 6, 1)
oled.fill_rect(80, 28, 20, 6, 1)
oled.show()
time.sleep(0.25)
# medium open
oled.fill(0)
oled.fill_rect(30, 26, 20, 10, 1)
oled.fill_rect(80, 26, 20, 10, 1)
oled.show()
time.sleep(0.25)
# fully open
oled.fill(0)
oled.fill_rect(30, 25, 20, 15, 1)
oled.fill_rect(80, 25, 20, 15, 1)
oled.fill_rect(36, 29, 6, 6, 0)
oled.fill_rect(86, 29, 6, 6, 0)
oled.show()
time.sleep(0.4)
# -------- MAIN LOOP --------
while True:
now = time.ticks_ms()
# -------- BUTTON --------
if button.value() == 0 and time.ticks_diff(now, last_button) > 300:
last_button = now
if idle_mode:
wakeup_animation() # 🔥 animation
idle_mode = False
else:
screen = (screen + 1) % 5
# -------- IDLE MODE (EYES) --------
if idle_mode:
offset = random.randint(-3, 3)
draw_eyes(False, offset)
time.sleep(0.3)
if random.randint(0, 5) == 0:
draw_eyes(True, offset)
time.sleep(0.2)
continue
# -------- AUTO SWITCH --------
if time.ticks_diff(now, last_switch) > 10000:
screen = (screen + 1) % 5
last_switch = now
# -------- LDR --------
light = ldr.read_u16()
mode = "Night" if light < 20000 else "Day"
oled.fill(0)
# -------- SCREEN 0 --------
if screen == 0:
oled.text("Smart Kiosk", 10, 10)
oled.text("Welcome!", 25, 30)
oled.text(mode, 0, 55)
# -------- SCREEN 1 --------
elif screen == 1:
t = time.localtime()
oled.text("Date:", 0, 10)
oled.text("{}/{}/{}".format(t[2], t[1], t[0]), 0, 20)
oled.text("Time:", 0, 35)
oled.text("{:02d}:{:02d}:{:02d}".format(t[3], t[4], t[5]), 0, 45)
# -------- SCREEN 2 --------
elif screen == 2:
try:
sensor.measure()
oled.text("Temp:{}C".format(sensor.temperature()), 0, 20)
oled.text("Hum:{}%".format(sensor.humidity()), 0, 35)
except:
oled.text("Sensor Error", 10, 30)
# -------- SCREEN 3 --------
elif screen == 3:
oled.text("Dept: ECE", 0, 10)
oled.text("Block: A", 0, 25)
oled.text("Room: 204", 0, 40)
# -------- SCREEN 4 (TICKER) --------
elif screen == 4:
oled.text("Notice:", 0, 0)
oled.text(ticker, -scroll_x, 40)
scroll_x += 2
if scroll_x > len(ticker) * 8:
scroll_x = 0
oled.show()
time.sleep(0.1)