# dasai_mochi_oled.py - ESP32-C3-Mini with OLED Display
from machine import Pin, I2C, Timer
import time
import random
import ssd1306 # Make sure this is in your lib folder
# Hardware setup for ESP32-C3-Mini
LED_PIN = 2 # Onboard LED (active-low)
BTN_PIN = 9 # Boot button (GPIO9)
# I2C for OLED (adjust pins based on your wiring)
I2C_SCL = 10
I2C_SDA = 8
I2C_FREQ = 400000
# Initialize hardware
led = Pin(LED_PIN, Pin.OUT, value=1) # Start with LED off
button = Pin(BTN_PIN, Pin.IN, Pin.PULL_UP)
# Initialize I2C and OLED
i2c = I2C(0, scl=Pin(I2C_SCL), sda=Pin(I2C_SDA), freq=I2C_FREQ)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# Mochi states
STATE_IDLE = 0
STATE_HAPPY = 1
STATE_SAD = 2
STATE_SLEEPY = 3
current_state = STATE_IDLE
last_button_state = button.value()
# Mochi faces (using text characters)
FACES = {
STATE_IDLE: [
" _____ ",
" / \\ ",
" | O O | ",
" | ▿ | ",
" \\ _____ / "
],
STATE_HAPPY: [
" _____ ",
" / \\ ",
" | ◉ ◉ | ",
" | \\_/ | ",
" \\ ‾‾‾ / "
],
STATE_SAD: [
" _____ ",
" / \\ ",
" | ◔ ◔ | ",
" | ‾‿‾ | ",
" \\ ___ / "
],
STATE_SLEEPY: [
" _____ ",
" / \\ ",
" | – – | ",
" | ~~~~ | ",
" \\ ~~~ / "
]
}
def update_display():
"""Update OLED with current state and face"""
oled.fill(0)
# Display title
oled.text("DASAI MOCHI", 20, 0, 1)
# Display state name
oled.text(f"State: {state_name(current_state)}", 5, 15, 1)
# Display mochi face
face = FACES[current_state]
for y, line in enumerate(face):
oled.text(line, 5, 25 + y*8, 1)
# Display instructions
oled.text("Press BOOT button", 5, 55, 1)
oled.show()
def blink_pattern(timer):
"""LED patterns based on current state"""
global led
if current_state == STATE_IDLE:
led.value(not led.value()) # Slow blink
elif current_state == STATE_HAPPY:
led.value(0) # On
time.sleep_ms(100)
led.value(1) # Off
time.sleep_ms(100)
led.value(0) # Double blink
time.sleep_ms(100)
led.value(1)
elif current_state == STATE_SAD:
for _ in range(3):
led.value(0)
time.sleep_ms(300)
led.value(1)
time.sleep_ms(300)
elif current_state == STATE_SLEEPY:
led.value(0) # On for longer period
time.sleep_ms(800)
led.value(1)
time.sleep_ms(200)
def check_button():
"""Handle button press state changes"""
global current_state, last_button_state
current_btn = button.value()
if current_btn != last_button_state:
time.sleep_ms(20) # Debounce
if current_btn == 0: # Button pressed (active-low)
current_state = random.randint(1, 3) # Random emotion
print("Button pressed! Current state:", state_name(current_state))
update_display() # Update display on state change
last_button_state = current_btn
def state_name(state):
"""Get state display name"""
return {
STATE_IDLE: "IDLE",
STATE_HAPPY: "HAPPY",
STATE_SAD: "SAD",
STATE_SLEEPY: "SLEEPY"
}.get(state, "UNKNOWN")
# Initialize display
update_display()
# Create timer for LED patterns (every 1 second)
timer = Timer(0)
timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t: blink_pattern(t))
print("\n=== Dasai Mochi Activated ===")
print("Press BOOT button to change mood")
print("Current state: IDLE")
# Main loop
while True:
check_button()
time.sleep_ms(10) # Reduce CPU usage