# Importar librerías
from machine import Pin, I2C, freq, time_pulse_us, ADC, Timer
from ssd1306 import SSD1306_I2C
from hx711 import HX711
import framebuf, sys
import utime
import time
# Definir pines de entrada y salida
SWITCH_A = 9
START_PIN = 8
STOP_PIN = 7
EMERG_PIN = 10
BUTTON_B = 3
SC_LOW = 13 # Sensor nivel bajo
SC_MEDIUM = 14 # Sensor nivel medio
SC_HIGH = 15 # Sensor nivel alto
LED_LOW = 16
LED_MEDIUM = 17
LED_HIGH = 18
LED_MOTOR = 19
LED_START = 20
# Inicializar pines de entrada y salida
led_low = Pin(LED_LOW, Pin.OUT)
led_medium = Pin(LED_MEDIUM, Pin.OUT)
led_high = Pin(LED_HIGH, Pin.OUT)
led_motor = Pin(LED_MOTOR, Pin.OUT)
led_start = Pin(LED_START, Pin.OUT)
emerg_switch = Pin(EMERG_PIN, Pin.IN, Pin.PULL_DOWN)
start = Pin(START_PIN, Pin.IN, Pin.PULL_DOWN)
stop = Pin(STOP_PIN, Pin.IN, Pin.PULL_DOWN)
switch_a = Pin(SWITCH_A, Pin.IN, Pin.PULL_DOWN)
button_b = Pin(BUTTON_B, Pin.IN, Pin.PULL_DOWN)
sc_low = Pin(SC_LOW, Pin.IN, Pin.PULL_DOWN)
sc_medium = Pin(SC_MEDIUM, Pin.IN, Pin.PULL_DOWN)
sc_high = Pin(SC_HIGH, Pin.IN, Pin.PULL_DOWN)
adc = ADC(Pin(28))
# Definir variables globales
WIDTH = 128 # Ancho pantalla OLED
HEIGHT = 64 # Alto pantalla OLED
DEBOUNCE_TIME = 0 # Variable para evitar antirrebotes al presionar los pulsadores
MIN_DEBOUNCE_TIME = 100 # Variable para eliminar el antirrebote
MODE = switch_a.value() # Modo de funcionamiento del sistema (0:manual, 1:automático)
MOTOR_DELAY = 1 # Variable para activar el timer que apaga el motor después de 15 segundos
START = False # Variable para que iniciar el sistema en modo automático
EMERG = emerg_switch.value()
LOW_LEVEL_IND = 0 # Variable para activar el timer que enciende y apaga cada 1.5 segundos el led rojo (nivel bajo)
# Inicialización de sensores y actuadores
hx = HX711(d_out=5, pd_sck=4) # Módulo HX711
i2c_dev = I2C(0, scl=Pin(1), sda=Pin(0), freq=200000) # Comunicación I2C
display = SSD1306_I2C(WIDTH, HEIGHT, i2c_dev) # Pantalla OLED
# Funciones de interrupción para los pulsadores e interruptores
# Se activan cuando el usuario presiona un pulsador o cambia la posición del interruptor
def emerg_callback(pin):
"""Función de interrupción para el interruptor de EMERGENCIA"""
global DEBOUNCE_TIME, MIN_DEBOUNCE_TIME, START, STOP, EMERG
if (time.ticks_ms()-DEBOUNCE_TIME>MIN_DEBOUNCE_TIME): # Evita el antirrebote
START = False # Detiene el sistema
EMERG = not EMERG # Cambia el estado de la variable (0<->1)
DEBOUNCE_TIME = time.ticks_ms()
def switch_a_callback(pin):
"""Función de interrupción para el interruptor A"""
global DEBOUNCE_TIME, MODE, switch_a, MIN_DEBOUNCE_TIME, START, led_motor
if (time.ticks_ms()-DEBOUNCE_TIME>MIN_DEBOUNCE_TIME): # Evita el antirrebote
MODE = not MODE # Cambia el modo de funcionamiento de sistema (manual<->automático)
START = False # Detiene el sistema
led_motor.value(0) # Apaga el motor
DEBOUNCE_TIME = time.ticks_ms()
def start_callback(pin):
"""Función de interrupción para el pulsador START"""
global DEBOUNCE_TIME, MIN_DEBOUNCE_TIME, START, led_start, STOP, EMERG
if (time.ticks_ms()-DEBOUNCE_TIME>MIN_DEBOUNCE_TIME): # Evita el antirrebote
START = True # Inicia el sistema
led_start.value(not EMERG) # Enciende el led si el interruptor de emergencia está abierto
DEBOUNCE_TIME = time.ticks_ms()
def stop_callback(pin):
"""Función de interrupción para el pulsador STOP"""
global DEBOUNCE_TIME, MIN_DEBOUNCE_TIME, START, STOP, EMERG
if (time.ticks_ms()-DEBOUNCE_TIME>MIN_DEBOUNCE_TIME): # Evita el antirrebote
START = False # Detiene el sistema
DEBOUNCE_TIME = time.ticks_ms()
def button_b_callback(pin):
"""Función de interrupción para el pulsador B"""
global led_motor, DEBOUNCE_TIME, MIN_DEBOUNCE_TIME, EMERG, START
if (time.ticks_ms()-DEBOUNCE_TIME>MIN_DEBOUNCE_TIME): # Evita el antirrebote
led_motor.value(not EMERG and START) # Enciende el motor si el interruptor de emergencia está abierto
# y el sistema está funcionando
DEBOUNCE_TIME = time.ticks_ms()
def low_level_timer(timer):
"""Temporizador que enciende y apaga el led rojo cada 1.5 segundos"""
global led_low
led_low.value(not led_low.value())
def motor_timer(timer):
"""Temporizador que apaga el motor después de 15 segundos"""
global led_motor
led_motor.value(0)
def get_distance():
"""Función para obtener los estados de los interruptores"""
# Apaga el pin trigger
trigger.low()
time.sleep_us(2)
# Envía un pulso de 10 microsegundos al pin trigger
trigger.high()
time.sleep_us(10)
trigger.low()
# Mide la duración del pin echo (microsegundos)
pulse_duration = time_pulse_us(echo, Pin.high)
# Calcula la distancia en centimetros
distance = pulse_duration*0.0343/2
return distance
# Define las funciones de interrupción para cada pulsador/interruptor
emerg_switch.irq(trigger=Pin.IRQ_RISING or Pin.IRQ_FALLING, handler=emerg_callback)
start.irq(trigger=Pin.IRQ_RISING, handler=start_callback)
stop.irq(trigger=Pin.IRQ_RISING, handler=stop_callback)
button_b.irq(trigger=Pin.IRQ_RISING, handler=button_b_callback)
switch_a.irq(trigger=Pin.IRQ_RISING or Pin.IRQ_FALLING, handler=switch_a_callback)
timer_led = Timer() # Define el temporizador para el led rojo (nivel bajo)
timer_motor = Timer() # Define el temporizador para apagar el motor
# Lazo infinito
while True:
if START and not EMERG: # Se ha presionado START y el interruptor de emergencia está apagado
print("ON")
# Lectura de los sensores
weight = round(hx.read()/420, 2) # Peso del café (Kg)
adc_value = round(adc.read_u16()/1311, 2) # Peso asignado por el usuario (Kg)
low_level = sc_low.value() # Sensor capacitivo nivel bajo
medium_level = sc_medium.value() # Sensor capacitivo nivel medio
high_level = sc_high.value() # Sensor capacitivo nivel alto
# Mostrar información en la pantalla
display.fill(0)
display.text("Molido "+str(weight)+"kg", 0, 0) # Muestra el peso medido del café
if led_motor.value():
display.text("Molienda en curso", 0, 24) # Muestra un mensaje si el motor está activado
# Activar LEDs de nivel
if all([not low_level, not medium_level, not high_level]): # Si todos los sensores de nivel están apagados
if not LOW_LEVEL_IND:
timer_led.init(period=1000, mode=Timer.PERIODIC, callback=low_level_timer) # Inicia el temporizador
LOW_LEVEL_IND = 1 # Variable para evitar iniciar el temporizador repetidamente
else:
timer_led.deinit() # Detiene el temporizador
led_low.value((not high_level and not medium_level and low_level) or (medium_level and low_level)) # Enciende/apaga el LED de nivel bajo
led_medium.value((not high_level and medium_level and low_level) or (high_level and medium_level and low_level)) # Enciende/apaga el LED de nivel medio
led_high.value(high_level and medium_level and low_level) # Enciende/apaga el LED de nivel alto
LOW_LEVEL_IND = 0 # Variable para evitar iniciar el temporizador repetidamente
if MODE: # Modo automático
print('A')
if all([not low_level, not medium_level, not high_level]): # Si todos los sensores de nivel están apagados
if MOTOR_DELAY and led_motor.value(): # Si el motor está encendido y el temporizador no se iniciado
timer_motor.init(period=15000, mode=Timer.ONE_SHOT, callback=motor_timer) # Inicia el temporizador
MOTOR_DELAY = 0 # Variable para evitar iniciar el temporizador repetidamente
else:
timer_motor.deinit() # Detiene el temporizador
led_motor.value(1) # Enciende el motor
MOTOR_DELAY = 1 # Variable para evitar iniciar el temporizador repetidamente
else: # Modo manual
print('M')
display.text("Objetivo "+str(adc_value)+"kg", 0, 12) # Muestra el peso asignado por el usuario
if weight>=adc_value: # Si el peso del café es mayor o igual al asignado por el usuario
led_motor.value(0) # Apaga el motor
display.text("COMPLETADO", 0, 24) # Muestra el mensaje en la pantalla
if all([not low_level, not medium_level, not high_level]): # Si todos los sensores de nivel están apagados
if MOTOR_DELAY and led_motor.value(): # Si el motor está encendido y el temporizador no se ha iniciado previamente
timer_motor.init(period=15000, mode=Timer.ONE_SHOT, callback=motor_timer) # Inicia el temporizador
MOTOR_DELAY = 0 # Variable para evitar iniciar el temporizador repetidamente
else:
timer_motor.deinit() # Detiene el temporizador
MOTOR_DELAY = 1 # Variable para evitar iniciar el temporizador repetidamente
display.show()
else: # Se ha presionado STOP o el interruptor de emergencia está activado
print("OFF")
MOTOR_DELAY = 1
LOW_LEVEL_IND = 0
timer_led.deinit()
timer_motor.deinit()
led_low.value(0)
led_medium.value(0)
led_high.value(0)
led_start.value(0)
led_motor.value(0)
display.fill(0)
display.show()
print("a")
time.sleep(0.1)
Loading
ssd1306
ssd1306