from machine import Pin, ADC
from time import sleep, sleep_us, ticks_us, ticks_diff
# =====================================================
# LCD 16x2 SIN I2C - MODO 4 BITS
# =====================================================
LCD_RS = Pin(16, Pin.OUT)
LCD_E = Pin(17, Pin.OUT)
LCD_D4 = Pin(18, Pin.OUT)
LCD_D5 = Pin(19, Pin.OUT)
LCD_D6 = Pin(20, Pin.OUT)
LCD_D7 = Pin(21, Pin.OUT)
# =====================================================
# SENSOR ULTRASONICO HC-SR04
# =====================================================
TRIG = Pin(14, Pin.OUT)
ECHO = Pin(15, Pin.IN)
# =====================================================
# POTENCIOMETRO
# =====================================================
pot = ADC(26) # GP26 / ADC0
# =====================================================
# LEDS
# =====================================================
led1 = Pin(2, Pin.OUT)
led2 = Pin(3, Pin.OUT)
led3 = Pin(4, Pin.OUT)
led4 = Pin(5, Pin.OUT)
led5 = Pin(6, Pin.OUT)
led6 = Pin(7, Pin.OUT)
led7 = Pin(8, Pin.OUT)
led8 = Pin(9, Pin.OUT)
leds = [led1, led2, led3, led4, led5, led6, led7, led8]
# =====================================================
# FUNCIONES LCD
# =====================================================
def lcd_pulso_enable():
LCD_E.value(1)
sleep_us(2)
LCD_E.value(0)
sleep_us(50)
def lcd_enviar_nibble(data):
LCD_D4.value((data >> 0) & 1)
LCD_D5.value((data >> 1) & 1)
LCD_D6.value((data >> 2) & 1)
LCD_D7.value((data >> 3) & 1)
lcd_pulso_enable()
def lcd_enviar_byte(data, rs):
LCD_RS.value(rs)
lcd_enviar_nibble(data >> 4)
lcd_enviar_nibble(data & 0x0F)
def lcd_comando(cmd):
lcd_enviar_byte(cmd, 0)
sleep_us(100)
def lcd_caracter(char):
lcd_enviar_byte(ord(char), 1)
def lcd_limpiar():
lcd_comando(0x01)
sleep(0.002)
def lcd_gotoxy(col, fila):
if fila == 0:
direccion = 0x80 + col
else:
direccion = 0xC0 + col
lcd_comando(direccion)
def lcd_print(texto):
for c in texto:
lcd_caracter(c)
def lcd_init():
sleep(0.05)
LCD_RS.value(0)
LCD_E.value(0)
lcd_enviar_nibble(0x03)
sleep(0.005)
lcd_enviar_nibble(0x03)
sleep_us(150)
lcd_enviar_nibble(0x03)
sleep_us(150)
lcd_enviar_nibble(0x02)
lcd_comando(0x28) # 4 bits, 2 lineas
lcd_comando(0x0C) # display ON, cursor OFF
lcd_comando(0x06) # incremento automatico
lcd_limpiar()
# =====================================================
# FUNCIONES DEL SISTEMA
# =====================================================
def apagar_leds():
for led in leds:
led.value(0)
def medir_distancia():
TRIG.value(0)
sleep_us(2)
TRIG.value(1)
sleep_us(10)
TRIG.value(0)
timeout = 30000
inicio_espera = ticks_us()
while ECHO.value() == 0:
if ticks_diff(ticks_us(), inicio_espera) > timeout:
return 999.0
inicio_pulso = ticks_us()
while ECHO.value() == 1:
if ticks_diff(ticks_us(), inicio_pulso) > timeout:
return 999.0
fin_pulso = ticks_us()
duracion = ticks_diff(fin_pulso, inicio_pulso)
distancia = (duracion * 0.0343) / 2
return distancia
def leer_potenciometro():
valor = pot.read_u16()
porcentaje = int((valor * 100) / 65535)
return porcentaje
def controlar_leds(distancia):
apagar_leds()
if distancia > 19.8:
led5.value(1)
elif distancia > 16.4:
led6.value(1)
led7.value(1)
elif distancia > 9.6:
led1.value(1)
led7.value(1)
led8.value(1)
elif distancia > 8.0:
led1.value(1)
led3.value(1)
led4.value(1)
else:
led2.value(1)
def texto_leds(distancia):
if distancia > 19.8:
return "LED:5"
elif distancia > 16.4:
return "LED:6 7"
elif distancia > 9.6:
return "LED:1 7 8"
elif distancia > 8.0:
return "LED:1 3 4"
else:
return "LED:2"
def mostrar_lcd(distancia, pot_porcentaje):
lcd_limpiar()
lcd_gotoxy(0, 0)
lcd_print("D:{:.1f}cm P:{}%".format(distancia, pot_porcentaje))
lcd_gotoxy(0, 1)
lcd_print(texto_leds(distancia))
# =====================================================
# PROGRAMA PRINCIPAL
# =====================================================
lcd_init()
lcd_gotoxy(0, 0)
lcd_print("Sistema HC-SR04")
lcd_gotoxy(0, 1)
lcd_print("Raspberry Pico")
sleep(2)
while True:
distancia = medir_distancia()
pot_porcentaje = leer_potenciometro()
controlar_leds(distancia)
mostrar_lcd(distancia, pot_porcentaje)
sleep(0.3)