# main.py — Alimentador simples (Pico W + MicroPython, Wokwi)
# Comportamento:
# - Só alimenta quando apertar o botão (GP18, PULL-DOWN, GP18->3V3 ao apertar)
# - Cada clique: servo abre/fecha em pulsos, LED aceso durante
# - Peso é simulado e soma até atingir TARGET_G
# - Se já está cheio, só informa e não alimenta
#
# Testado em MicroPython 1.24.x (Wokwi, Pico W)
import time
from machine import Pin, PWM
# ===== Config =====
SIMULATION = True # Wokwi
PIN_SERVO = 15
PIN_LED = 13
PIN_BTN = 18 # botão com PULL-DOWN (pressionado = 1)
TARGET_G = 150.0 # alvo (pote cheio)
GRAMS_PER_PULSE = 20.0 # quanto cai por pulso (simulado)
PULSE_OPEN_MS = 300
PULSE_REST_MS = 200
MAX_PULSES = 50
DEBOUNCE_MS = 40
# ===== Servo / LED =====
servo = PWM(Pin(PIN_SERVO)); servo.freq(50)
def servo_deg(deg):
us = int(500 + (deg/180.0)*2000) # 500–2500 us
servo.duty_u16(int((us/20000.0)*65535))
def open_pulse():
servo_deg(90)
time.sleep_ms(PULSE_OPEN_MS)
servo_deg(0)
time.sleep_ms(PULSE_REST_MS)
led = Pin(PIN_LED, Pin.OUT)
def led_on(): led.value(1)
def led_off(): led.value(0)
# ===== Botão (PULL-DOWN) =====
# Solto = 0, Pressionado = 1 (GP18 ligado ao 3V3 ao apertar)
btn = Pin(PIN_BTN, Pin.IN, Pin.PULL_DOWN)
def is_pressed():
return btn.value() == 1
# ===== Peso simulado =====
_bowl_g = 0.0
def read_grams():
return max(0.0, _bowl_g)
def add_food_sim():
global _bowl_g
_bowl_g += GRAMS_PER_PULSE
# ===== Alimentar até alvo =====
def feed_to_target():
if read_grams() >= TARGET_G:
print("Pote já está cheio (≥ alvo). Nada a fazer.")
return
print("Repondo ração...")
led_on()
pulses = 0
while read_grams() < TARGET_G and pulses < MAX_PULSES:
open_pulse()
add_food_sim()
pulses += 1
print(f" -> pulso {pulses}, peso = {read_grams():.1f} g")
led_off()
if read_grams() >= TARGET_G:
print(f"Pote cheio! Peso final: {read_grams():.1f} g")
else:
print(f"Parou por segurança. Peso: {read_grams():.1f} g")
# ===== Utilidades =====
def wait_release():
# espera o botão ser solto para não repetir ações
while is_pressed():
time.sleep_ms(5)
def blink(times=2, ms=120):
for _ in range(times):
led_on(); time.sleep_ms(ms)
led_off(); time.sleep_ms(ms)
# ===== Main loop =====
def main():
print("Iniciando alimentador (SIMULATION=True, botão=PULL-DOWN em GP18)")
servo_deg(0)
blink(2, 120) # prova de vida
print("Pronto. Aperte o botão (GP18 ↔ 3V3) para alimentar.")
prev = is_pressed()
last_dbg = time.ticks_ms()
while True:
cur = is_pressed()
# debug leve no console a cada ~0,6s
if time.ticks_diff(time.ticks_ms(), last_dbg) > 600:
last_dbg = time.ticks_ms()
print(f"[DBG] btn={'PRESSED' if cur else 'released'} | peso={read_grams():.1f} g")
# borda: solto -> pressionado (com debounce)
if (cur and not prev):
time.sleep_ms(DEBOUNCE_MS)
if is_pressed():
print(f"Cachorro chegou. Peso atual: {read_grams():.1f} g")
feed_to_target()
wait_release()
prev = cur
time.sleep_ms(20)
if __name__ == "__main__":
main()