Enclose rfid reading

This commit is contained in:
2025-12-26 17:06:42 +01:00
parent 126a266321
commit d4aae20bd0
10 changed files with 98 additions and 31 deletions

0
rpi/hardware/__init__.py Normal file
View File

View File

63
rpi/hardware/rfid/main.py Normal file
View File

@@ -0,0 +1,63 @@
#!/usr/bin/env python3
from collections.abc import Callable
from threading import Thread
import threading
from serial import Serial
class RfidReader:
__serial : Serial = None
__thread : Thread | None = None
__listeners : list[Callable] = None
def __init__(self, port : str, baudrate: int):
self.__serial = Serial(port, baudrate)
self._run_event = threading.Event()
self.__listeners = []
def start(self) -> None:
self._run_event.set()
if self.__thread is None or not self.__thread.is_alive():
self.__thread = Thread(target=self.__read, daemon=True)
self.__thread.start()
def stop(self) -> None:
if self._run_event.is_set():
self._run_event.clear()
def subscribe(self, listener : Callable) -> None:
self.__listeners.append(listener)
def __notify(self, uid : int):
for listener in self.__listeners:
listener(uid)
def __read(self):
while self._run_event.is_set():
data = b""
while len(data) < 14 and self._run_event.is_set():
character = self.__serial.read(1)
if not character: continue
data += character
if len(data) >= 11:
hex_value = data[5:11].decode(errors='ignore')
try:
res = int(hex_value, 16)
self.__notify(res)
except ValueError:
print("Invalid hex:", hex_value)
else:
print("Received incomplete data:", data)
if __name__ == "__main__":
def callback(uid):
print("UID:", uid)
reader = RfidReader("/dev/serial0", 9600)
reader.subscribe(callback)
reader.start()

View File

View File

@@ -0,0 +1,122 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove - LCD RGB Backlight (http://www.seeedstudio.com/wiki/Grove_-_LCD_RGB_Backlight)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# History
# ------------------------------------------------
# Author Date Comments
# Initial Authoring
# Karan 7 Jan 16 Library updated to add a function to update the text without erasing the screen
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
#
# NOTE:
# Just supports setting the backlight colour, and
# putting a single string of text onto the display
# Doesn't support anything clever, cursors or anything
import time,sys
if sys.platform == 'uwp':
import winrt_smbus as smbus
bus = smbus.SMBus(1)
else:
import smbus
import RPi.GPIO as GPIO
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
# this device has two I2C addresses
DISPLAY_RGB_ADDR = 0x62
DISPLAY_TEXT_ADDR = 0x3e
# set backlight to (R,G,B) (values from 0..255 for each)
def setRGB(r,g,b):
bus.write_byte_data(DISPLAY_RGB_ADDR,0,0)
bus.write_byte_data(DISPLAY_RGB_ADDR,1,0)
bus.write_byte_data(DISPLAY_RGB_ADDR,0x08,0xaa)
bus.write_byte_data(DISPLAY_RGB_ADDR,4,r)
bus.write_byte_data(DISPLAY_RGB_ADDR,3,g)
bus.write_byte_data(DISPLAY_RGB_ADDR,2,b)
# send command to display (no need for external use)
def textCommand(cmd):
bus.write_byte_data(DISPLAY_TEXT_ADDR,0x80,cmd)
# set display text \n for second line(or auto wrap)
def setText(text):
textCommand(0x01) # clear display
time.sleep(.05)
textCommand(0x08 | 0x04) # display on, no cursor
textCommand(0x28) # 2 lines
time.sleep(.05)
count = 0
row = 0
for c in text:
if c == '\n' or count == 16:
count = 0
row += 1
if row == 2:
break
textCommand(0xc0)
if c == '\n':
continue
count += 1
bus.write_byte_data(DISPLAY_TEXT_ADDR,0x40,ord(c))
#Update the display without erasing the display
def setText_norefresh(text):
textCommand(0x02) # return home
time.sleep(.05)
textCommand(0x08 | 0x04) # display on, no cursor
textCommand(0x28) # 2 lines
time.sleep(.05)
count = 0
row = 0
while len(text) < 32: #clears the rest of the screen
text += ' '
for c in text:
if c == '\n' or count == 16:
count = 0
row += 1
if row == 2:
break
textCommand(0xc0)
if c == '\n':
continue
count += 1
bus.write_byte_data(DISPLAY_TEXT_ADDR,0x40,ord(c))
# Create a custom character (from array of row patterns)
def create_char(location, pattern):
"""
Writes a bit pattern to LCD CGRAM
Arguments:
location -- integer, one of 8 slots (0-7)
pattern -- byte array containing the bit pattern, like as found at
https://omerk.github.io/lcdchargen/
"""
location &= 0x07 # Make sure location is 0-7
textCommand(0x40 | (location << 3))
bus.write_i2c_block_data(DISPLAY_TEXT_ADDR, 0x40, pattern)
# example code
if __name__=="__main__":
setText("Hello world\nThis is an LCD chesscog-bck")
setRGB(0,128,64)
time.sleep(2)
for c in range(0,255):
setText_norefresh("Going to sleep in {}...".format(str(c)))
setRGB(c,255-c,0)
time.sleep(0.1)
setRGB(0,255,0)
setText("Bye bye, this should wrap onto next line")

17
rpi/hardware/timer/led.py Normal file
View File

@@ -0,0 +1,17 @@
import grovepi
import time
LED = 2 # Digital port D2
grovepi.pinMode(LED, "OUTPUT")
def on():
grovepi.digitalWrite(LED, 1)
def off():
grovepi.digitalWrite(LED, 0)
if __name__ == "__main__":
on()
time.sleep(1)
off()

View File

@@ -0,0 +1,47 @@
#!/usr/bin/env python3
from grove_rgb_lcd import *
import led
import sys
import select
whiteTime = 5 * 60
blackTime = 5 * 60
current = "white"
def compute_seconds(total_seconds):
return total_seconds % 60
def compute_minutes(total_seconds):
return total_seconds // 60
def update_timer(white_total_time, black_total_time):
white_minutes = compute_minutes(white_total_time)
white_seconds = compute_seconds(white_total_time)
black_minutes = compute_minutes(black_total_time)
black_seconds = compute_seconds(black_total_time)
setText(f"W {white_minutes:02d}:{white_seconds:02d}\nB {black_minutes:02d}:{black_seconds:02d}")
if __name__ == "__main__":
led.off()
led.on()
setRGB(255, 255, 255)
while whiteTime > 0 and blackTime > 0:
currentTime = 0
if current == "white":
whiteTime -= 1
else:
blackTime -= 1
update_timer(whiteTime, blackTime)
# wait up to 1 second for Enter
rlist, _, _ = select.select([sys.stdin], [], [], 1)
if rlist:
sys.stdin.readline() # consume Enter
current = "black" if current == "white" else "white"
led.off()