from machine import Pin, PWM, SPI, I2C
from time import sleep, sleep_ms, sleep_us, ticks_ms, ticks_diff
# =====================================================
# LCD I2C 16x2
# SDA -> GP0
# SCL -> GP1
# =====================================================
I2C_ADDR = 0x27
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
LCD_BACKLIGHT = 0x08
LCD_ENABLE = 0x04
LCD_COMMAND = 0
LCD_CHARACTER = 1
def lcd_write_byte(data):
i2c.writeto(I2C_ADDR, bytes([data | LCD_BACKLIGHT]))
def lcd_pulse(data):
lcd_write_byte(data | LCD_ENABLE)
sleep_us(500)
lcd_write_byte(data & ~LCD_ENABLE)
sleep_us(500)
def lcd_send(data, mode):
high = data & 0xF0
low = (data << 4) & 0xF0
lcd_write_byte(high | mode)
lcd_pulse(high | mode)
lcd_write_byte(low | mode)
lcd_pulse(low | mode)
def lcd_cmd(command):
lcd_send(command, LCD_COMMAND)
def lcd_char(char):
lcd_send(ord(char), LCD_CHARACTER)
def lcd_print(text):
for char in text:
lcd_char(char)
def lcd_clear():
lcd_cmd(0x01)
sleep_ms(2)
def lcd_gotoxy(col, row):
if row == 0:
lcd_cmd(0x80 + col)
else:
lcd_cmd(0xC0 + col)
def lcd_print_line(row, text):
text = text[:16]
lcd_gotoxy(0, row)
lcd_print(text + " " * (16 - len(text)))
def lcd_init():
sleep_ms(50)
lcd_send(0x33, LCD_COMMAND)
lcd_send(0x32, LCD_COMMAND)
lcd_send(0x28, LCD_COMMAND)
lcd_send(0x0C, LCD_COMMAND)
lcd_send(0x06, LCD_COMMAND)
lcd_clear()
# =====================================================
# DRIVER MFRC522 PARA MICROPYTHON
# RFID:
# MISO -> GP16
# RST -> GP17
# SCK -> GP18
# MOSI -> GP19
# CS -> GP20
# =====================================================
class MFRC522:
OK = 0
NOTAGERR = 1
ERR = 2
REQIDL = 0x26
REQALL = 0x52
AUTHENT1A = 0x60
AUTHENT1B = 0x61
PICC_ANTICOLL = 0x93
PICC_SElECTTAG = 0x93
PICC_HALT = 0x50
PCD_IDLE = 0x00
PCD_AUTHENT = 0x0E
PCD_RECEIVE = 0x08
PCD_TRANSMIT = 0x04
PCD_TRANSCEIVE = 0x0C
PCD_RESETPHASE = 0x0F
PCD_CALCCRC = 0x03
CommandReg = 0x01
CommIEnReg = 0x02
DivIEnReg = 0x03
CommIrqReg = 0x04
DivIrqReg = 0x05
ErrorReg = 0x06
Status2Reg = 0x08
FIFODataReg = 0x09
FIFOLevelReg = 0x0A
ControlReg = 0x0C
BitFramingReg = 0x0D
ModeReg = 0x11
TxControlReg = 0x14
TxASKReg = 0x15
TModeReg = 0x2A
TPrescalerReg = 0x2B
TReloadRegH = 0x2C
TReloadRegL = 0x2D
def __init__(self, spi, cs, rst):
self.spi = spi
self.cs = cs
self.rst = rst
self.cs.init(Pin.OUT, value=1)
self.rst.init(Pin.OUT, value=0)
self.reset()
self.init()
def _wreg(self, reg, val):
self.cs.value(0)
self.spi.write(bytes([(reg << 1) & 0x7E, val]))
self.cs.value(1)
def _rreg(self, reg):
self.cs.value(0)
self.spi.write(bytes([((reg << 1) & 0x7E) | 0x80]))
val = self.spi.read(1)[0]
self.cs.value(1)
return val
def _sflags(self, reg, mask):
self._wreg(reg, self._rreg(reg) | mask)
def _cflags(self, reg, mask):
self._wreg(reg, self._rreg(reg) & (~mask))
def reset(self):
self.rst.value(0)
sleep_ms(50)
self.rst.value(1)
sleep_ms(50)
self._wreg(self.CommandReg, self.PCD_RESETPHASE)
sleep_ms(50)
def init(self):
self._wreg(self.TModeReg, 0x8D)
self._wreg(self.TPrescalerReg, 0x3E)
self._wreg(self.TReloadRegL, 30)
self._wreg(self.TReloadRegH, 0)
self._wreg(self.TxASKReg, 0x40)
self._wreg(self.ModeReg, 0x3D)
self.antenna_on()
def antenna_on(self):
if ~(self._rreg(self.TxControlReg) & 0x03):
self._sflags(self.TxControlReg, 0x03)
def _tocard(self, command, send):
recv = []
bits = 0
status = self.ERR
if command == self.PCD_AUTHENT:
irq_en = 0x12
wait_irq = 0x10
elif command == self.PCD_TRANSCEIVE:
irq_en = 0x77
wait_irq = 0x30
else:
irq_en = 0x00
wait_irq = 0x00
self._wreg(self.CommIEnReg, irq_en | 0x80)
self._cflags(self.CommIrqReg, 0x80)
self._sflags(self.FIFOLevelReg, 0x80)
self._wreg(self.CommandReg, self.PCD_IDLE)
for c in send:
self._wreg(self.FIFODataReg, c)
self._wreg(self.CommandReg, command)
if command == self.PCD_TRANSCEIVE:
self._sflags(self.BitFramingReg, 0x80)
i = 2000
while True:
n = self._rreg(self.CommIrqReg)
i -= 1
if not ((i != 0) and not (n & 0x01) and not (n & wait_irq)):
break
self._cflags(self.BitFramingReg, 0x80)
if i:
if (self._rreg(self.ErrorReg) & 0x1B) == 0x00:
status = self.OK
if n & irq_en & 0x01:
status = self.NOTAGERR
if command == self.PCD_TRANSCEIVE:
n = self._rreg(self.FIFOLevelReg)
last_bits = self._rreg(self.ControlReg) & 0x07
if last_bits:
bits = (n - 1) * 8 + last_bits
else:
bits = n * 8
if n == 0:
n = 1
if n > 16:
n = 16
for _ in range(n):
recv.append(self._rreg(self.FIFODataReg))
else:
status = self.ERR
return status, recv, bits
def request(self, mode):
self._wreg(self.BitFramingReg, 0x07)
status, recv, bits = self._tocard(self.PCD_TRANSCEIVE, [mode])
if status != self.OK or bits != 0x10:
status = self.ERR
return status, bits
def anticoll(self):
self._wreg(self.BitFramingReg, 0x00)
serial_number = [self.PICC_ANTICOLL, 0x20]
status, recv, bits = self._tocard(self.PCD_TRANSCEIVE, serial_number)
if status == self.OK:
if len(recv) == 5:
checksum = 0
for i in range(4):
checksum ^= recv[i]
if checksum != recv[4]:
status = self.ERR
else:
status = self.ERR
return status, recv
# =====================================================
# PINES DEL SISTEMA
# =====================================================
PIN_SERVO = 2
LED_VERDE = Pin(4, Pin.OUT)
LED_AZUL = Pin(5, Pin.OUT)
LED_ROJO = Pin(6, Pin.OUT)
BUZZER = Pin(7, Pin.OUT)
servo = PWM(Pin(PIN_SERVO))
servo.freq(50)
# =====================================================
# RFID SPI
# =====================================================
spi = SPI(
0,
baudrate=1000000,
polarity=0,
phase=0,
sck=Pin(18),
mosi=Pin(19),
miso=Pin(16)
)
rfid = MFRC522(
spi=spi,
cs=Pin(20, Pin.OUT),
rst=Pin(17, Pin.OUT)
)
# =====================================================
# UID AUTORIZADO
# En Wokwi, la tarjeta azul card = 0 tiene UID 01:02:03:04
# =====================================================
UID_REGISTRADO = [0x01, 0x02, 0x03, 0x04]
ultima_uid = None
ultimo_evento = 0
# =====================================================
# FUNCIONES DEL SISTEMA
# =====================================================
def mover_servo(angulo):
if angulo < 0:
angulo = 0
if angulo > 180:
angulo = 180
pulso_us = 500 + int((angulo * 1900) / 180)
duty = int((pulso_us * 65535) / 20000)
servo.duty_u16(duty)
print("Servo:", angulo, "grados")
def apagar_salidas():
LED_VERDE.value(0)
LED_AZUL.value(0)
LED_ROJO.value(0)
BUZZER.value(0)
def beep_error():
for i in range(3):
BUZZER.value(1)
sleep(0.15)
BUZZER.value(0)
sleep(0.12)
def pantalla_inicial():
lcd_clear()
lcd_print_line(0, "Acerque tarjeta")
lcd_print_line(1, "Esperando...")
def leer_uid():
status, tag_type = rfid.request(rfid.REQIDL)
if status == rfid.OK:
status, uid = rfid.anticoll()
if status == rfid.OK:
return uid[:4]
return None
def mostrar_uid(uid):
texto = ""
for b in uid:
texto += "{:02X} ".format(b)
print("UID:", texto)
def acceso_registrado():
apagar_salidas()
lcd_clear()
lcd_print_line(0, "Usuario")
lcd_print_line(1, "Registrado")
LED_VERDE.value(1)
LED_AZUL.value(1)
LED_ROJO.value(0)
mover_servo(90)
print("Usuario Registrado")
def acceso_denegado():
apagar_salidas()
lcd_clear()
lcd_print_line(0, "Usuario sin")
lcd_print_line(1, "Registro")
LED_VERDE.value(0)
LED_AZUL.value(0)
LED_ROJO.value(1)
mover_servo(0)
beep_error()
print("Usuario sin Registro")
# =====================================================
# INICIO
# =====================================================
lcd_init()
apagar_salidas()
mover_servo(0)
lcd_clear()
lcd_print_line(0, "Sistema RFID")
lcd_print_line(1, "Raspberry Pico")
sleep(2)
pantalla_inicial()
print("Sistema RFID iniciado")
print("UID autorizado: 01 02 03 04")
# =====================================================
# LOOP PRINCIPAL
# =====================================================
while True:
uid = leer_uid()
if uid is not None:
ahora = ticks_ms()
if uid != ultima_uid or ticks_diff(ahora, ultimo_evento) > 2500:
ultima_uid = uid
ultimo_evento = ahora
mostrar_uid(uid)
if uid == UID_REGISTRADO:
acceso_registrado()
else:
acceso_denegado()
else:
if ultima_uid is not None and ticks_diff(ticks_ms(), ultimo_evento) > 1500:
ultima_uid = None
apagar_salidas()
mover_servo(0)
pantalla_inicial()
sleep(0.1)
Loading
mfrc522
mfrc522