Files
rate_music/pico_2026/rate.py
2026-03-28 12:53:28 +01:00

154 lines
4.0 KiB
Python

from machine import Pin
import wifi_client
import time
# State Constants
STATE_USER_ID = 0
STATE_RATING = 1
# Global variables
CURRENT_STATE = STATE_USER_ID
USER_ID = 0
RATING = 0
BUTTON_SEND = None
RATE_BUTTONS = []
DISPLAY = None
# Helper to update display based on state
def refresh_display(message=None):
if not DISPLAY:
return
DISPLAY.fill(0)
if message:
# Show temporary message (Success, Error, Confirmed)
DISPLAY.text(message, 10, 30)
elif CURRENT_STATE == STATE_USER_ID:
# 1. User ID Mode
DISPLAY.text("Inchometer", 25, 0)
# Display binary representation: _ _ _ _ _
# Bit 4 is leftmost button, Bit 0 is rightmost
binary_str = ""
for i in range(5):
bit_pos = 4 - i
if USER_ID & (1 << bit_pos):
binary_str += "X "
else:
binary_str += "_ "
DISPLAY.text(binary_str.strip(), 30, 30)
elif CURRENT_STATE == STATE_RATING:
# 3. Rating Mode
DISPLAY.text("Select Rating", 10, 0)
if RATING == 0:
rating_text = "_"
else:
rating_text = str(RATING)
# Draw "big" text (simulated with scale if supported, or just centered)
# Standard ssd1306 doesn't have big fonts, so we just center it
DISPLAY.text(rating_text, 60, 30)
DISPLAY.show()
# initialize a specific Pin as Input with a pull-down resistor
def initialize_pin(pin_number:int):
button = Pin(pin_number, Pin.IN, Pin.PULL_DOWN)
return button
# activates send pin
def activate_sendPin() -> None:
BUTTON_SEND.irq(trigger=Pin.IRQ_RISING, handler=sendButton_pressed)
# deactivates send pin
def deactivate_sendPin() -> None:
BUTTON_SEND.irq(handler=None)
# rate button is pressed
def rate_button_pressed(pin:Pin) -> None:
global USER_ID, RATING, CURRENT_STATE, RATE_BUTTONS
# Find which button index was pressed
button_index = -1
for i, button in enumerate(RATE_BUTTONS):
if button == pin:
button_index = i
break
if button_index == -1:
return
if CURRENT_STATE == STATE_USER_ID:
bit_pos = len(RATE_BUTTONS) - 1 - button_index
USER_ID ^= (1 << bit_pos)
print(f"Current User ID: {USER_ID}")
elif CURRENT_STATE == STATE_RATING:
RATING = button_index + 1
print(f"Current Rating selected: {RATING}")
refresh_display()
activate_sendPin()
# Send/Confirm button is pressed
def sendButton_pressed(pin) -> None:
global CURRENT_STATE, USER_ID, RATING
deactivate_sendPin()
if CURRENT_STATE == STATE_USER_ID:
# 2. Confirmed ID display
refresh_display(f"Confirmed: {USER_ID}")
time.sleep(1)
CURRENT_STATE = STATE_RATING
refresh_display()
elif CURRENT_STATE == STATE_RATING:
if RATING == 0:
activate_sendPin()
return
# 4. Sending / Success / Error
refresh_display("Sending...")
success = wifi_client.send_request(USER_ID, RATING)
if success:
refresh_display("Success")
else:
refresh_display("Error")
time.sleep(5) # Display status for 5 seconds
# Reset for next rating
USER_ID = 0
RATING = 0
CURRENT_STATE = STATE_USER_ID
refresh_display()
# start the rating program
def start_rating(rate_button_pins:list, button_send_pin:int, oled_display=None) -> None:
global RATE_BUTTONS, BUTTON_SEND, DISPLAY
DISPLAY = oled_display
# initialize all pins as buttons and add them to the list
RATE_BUTTONS = []
for pin_num in rate_button_pins:
button = initialize_pin(pin_num)
button.irq(trigger=Pin.IRQ_RISING, handler=rate_button_pressed)
RATE_BUTTONS.append(button)
# initialize send button
BUTTON_SEND = initialize_pin(button_send_pin)
print("System started.")
refresh_display()
while True:
time.sleep(1)