from machine import Pin, SPI
from mfrc522 import MFRC522
import time
from neopixel import Neopixel
# =====================================================
# NeoPixel Setup
# =====================================================
pixel1 = Neopixel(17, 0, 6, "GRB")
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# Position of the bright pixel in the loading animation
head_index = 0
# Fade amount for blue loading animation
FADE_FACTOR = .875
# =====================================================
# BUTTON AND LED SETUP
# DISABLED FOR NOW
# Uncomment this section when the button is connected
# =====================================================
# Button connected between GP15 and GND
# button = Pin(15, Pin.IN, Pin.PULL_UP)
# Button LED connected to GP16
# button_led = Pin(16, Pin.OUT)
# Make sure button LED starts OFF
# button_led.value(0)
# =====================================================
# BUTTON TIMEOUT
# DISABLED FOR NOW
# Uncomment when the button is connected
# =====================================================
# Amount of time to wait for the button
# after a correct RFID card is detected
# BUTTON_TIMEOUT = 10 # seconds
# Stores the time when button waiting begins
# button_wait_start = 0
# =====================================================
# RFID SPI SETUP
# =====================================================
# MFRC522 connections:
#
# SCK -> GP10
# MOSI -> GP11
# MISO -> GP12
# SDA -> GP13
# RST -> GP14
spi = SPI(
1,
baudrate=1000000,
polarity=0,
phase=0,
sck=Pin(10),
mosi=Pin(11),
miso=Pin(12)
)
# =====================================================
# RFID READER
# =====================================================
rfid = MFRC522(
spi=spi,
gpio_rst=14,
gpio_cs=13
)
# =====================================================
# AUTHORISED RFID UID
# =====================================================
AUTHORISED_UID = "01 02 03 04"
# Stores the last RFID card detected
last_uid = ""
# =====================================================
# SYSTEM STATES
# =====================================================
WAITING = 0
AUTHORIZED = 1
UNAUTHORIZED = 2
# Button state disabled for now
# WAITING_FOR_BUTTON = 3
auth_state = WAITING
# =====================================================
# NEO PIXEL FUNCTIONS
# =====================================================
def set_ring(color):
"""
Set all NeoPixels to the same color.
"""
for i in range(16):
pixel1.set_pixel(i, color)
pixel1.show()
def clear_ring():
"""
Turn all NeoPixels off.
"""
for i in range(16):
pixel1.set_pixel(i, (0, 0, 0))
pixel1.show()
def waiting_animation():
"""
Blue rotating/loading animation.
"""
global head_index
for i in range(16):
# Calculate distance from moving head
distance = (head_index - i) % 16
# Calculate brightness
intensity = FADE_FACTOR ** distance
r = round(BLUE[0] * intensity)
g = round(BLUE[1] * intensity)
b = round(BLUE[2] * intensity)
pixel1.set_pixel(i, (r, g, b))
# Display animation
pixel1.show()
# Move animation forward
head_index = (head_index + 1) % 16
# Animation speed
time.sleep(0.05)
def authorized_animation():
"""
Correct RFID card.
Ring becomes solid green.
Button functionality is currently disabled.
"""
print("Displaying GREEN - Access Granted")
# Solid green ring
set_ring(GREEN)
# -------------------------------------------------
# BUTTON LED DISABLED
# Uncomment when button is connected
# -------------------------------------------------
# button_led.value(1)
print("Access Granted")
def unauthorized_animation():
"""
Wrong RFID card.
Blink red 5 times.
"""
print("Displaying RED - Access Denied")
for i in range(5):
# Red ON
set_ring(RED)
time.sleep(0.25)
# Red OFF
clear_ring()
time.sleep(0.25)
# =====================================================
# RFID HANDLER
# =====================================================
def handle_rfid():
global last_uid
global auth_state
rfid.init()
# Check for RFID card
status, _ = rfid.request(
rfid.REQIDL
)
if status == rfid.OK:
# Read UID
status, uid = rfid.anticoll()
if status == rfid.OK:
# -------------------------------------------------
# Wokwi Raspberry Pi Pico MFRC522 workaround
#
# Blue Card should be:
# 01 02 03 04
#
# But this MicroPython driver may read it as:
# 01 03 04 00
# -------------------------------------------------
if uid == [0x01, 0x03, 0x04, 0x00]:
uid_string = "01 02 03 04"
else:
uid_string = (
"%02X %02X %02X %02X"
% tuple(uid)
)
# -------------------------------------------------
# Only respond to a new card
# -------------------------------------------------
if uid_string != last_uid:
print("RFID Card Detected")
print("RFID UID:", uid_string)
# Save UID so the same card doesn't
# repeatedly trigger
last_uid = uid_string
# -------------------------------------------------
# Correct RFID card
# -------------------------------------------------
if uid_string == AUTHORISED_UID:
print("Authorised Card Detected")
auth_state = AUTHORIZED
# -------------------------------------------------
# Wrong RFID card
# -------------------------------------------------
else:
print("Unauthorised Card")
auth_state = UNAUTHORIZED
else:
print("Unable to read RFID UID")
else:
# No card currently present
last_uid = ""
# =====================================================
# STARTUP MESSAGE
# =====================================================
print()
print("====================================")
print("Raspberry Pi Pico Smart Access Control System")
print("====================================")
print()
print("System Ready")
print()
# =====================================================
# MAIN LOOP
# =====================================================
while True:
# =================================================
# WAITING FOR RFID
# =================================================
if auth_state == WAITING:
# -------------------------------------------------
# BUTTON LED DISABLED
# Uncomment when button is connected
# -------------------------------------------------
# button_led.value(0)
# Check for RFID
handle_rfid()
# Only run blue animation if no RFID
# was detected
if auth_state == WAITING:
waiting_animation()
# =================================================
# CORRECT RFID CARD
# =================================================
elif auth_state == AUTHORIZED:
# Make ring solid green
authorized_animation()
# -------------------------------------------------
# BUTTON TIMEOUT DISABLED
# Uncomment when button is connected
# -------------------------------------------------
# Start button timeout timer
# button_wait_start = time.ticks_ms()
# Move to button waiting state
# auth_state = WAITING_FOR_BUTTON
# -------------------------------------------------
# TEMPORARY BEHAVIOR WITHOUT BUTTON
# -------------------------------------------------
# Keep green for 1 second
time.sleep(1)
# Return to RFID waiting mode
auth_state = WAITING
# =================================================
# WRONG RFID CARD
# =================================================
elif auth_state == UNAUTHORIZED:
# Blink red 5 times
unauthorized_animation()
# Return to waiting mode
auth_state = WAITING
# =================================================
# WAITING FOR BUTTON
#
# DISABLED FOR NOW
#
# Uncomment this entire section when the button
# is physically connected.
# =================================================
# elif auth_state == WAITING_FOR_BUTTON:
# # -------------------------------------------------
# # Keep ring GREEN
# # -------------------------------------------------
# set_ring(GREEN)
# # -------------------------------------------------
# # Keep button