First draft of a card terminal with keypad and
MFRC522 card reader together.
This commit is contained in:
parent
d90781c0f8
commit
77565de933
@ -2,7 +2,7 @@ import machine
|
||||
import utime
|
||||
|
||||
|
||||
class membrane:
|
||||
class Membrane:
|
||||
"""Class for interpreting input from a membran-like keypad,
|
||||
the default is a 4x4 matrix array membrane keypad.
|
||||
The layout of key bindings and size (i.e. 4x3 alternative)
|
||||
@ -244,7 +244,7 @@ class membrane:
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
membrane_keypad = membrane()
|
||||
membrane_keypad = Membrane()
|
||||
pin_size = 12
|
||||
|
||||
while len(membrane_keypad) < pin_size:
|
||||
|
202
src/systems/cardterm.py
Normal file
202
src/systems/cardterm.py
Normal file
@ -0,0 +1,202 @@
|
||||
import utime
|
||||
from machine import Pin, Timer, PWM
|
||||
from input.ukeypad import Membrane as KeyPad
|
||||
from radiotech.rfid.umfrc522 import UMFRC522 as MFRC522
|
||||
|
||||
class CardTermRC522:
|
||||
@classmethod
|
||||
def led_pulse(cls, led_pwm, led_timer, period=1000, half=False):
|
||||
led_pwm.freq(period)
|
||||
def inputblink(t):
|
||||
maxvalue = 2**17 if not half else 2**16
|
||||
halfvalue = 2**16 if not half else 2**15
|
||||
freq = (
|
||||
(utime.ticks_ms() % period) * (maxvalue//period)
|
||||
) % maxvalue
|
||||
duty = freq if freq < halfvalue else (maxvalue - freq)
|
||||
led_pwm.duty_u16(duty)
|
||||
led_timer.init(freq=period, callback=inputblink)
|
||||
@classmethod
|
||||
def callback_ok(cls, cardid, data):
|
||||
print("Status: OK")
|
||||
print(f"Card ID: {cardid}")
|
||||
print(f"Data: {data}")
|
||||
@classmethod
|
||||
def callback_nok(cls, cardid):
|
||||
print("Status: NOT OK")
|
||||
print(f"Card ID: {cardid}")
|
||||
|
||||
DEFAULT_KEY_PAD = (
|
||||
('1', '2', '3', 'A'),
|
||||
('4', '5', '6', 'B'),
|
||||
('7', '8', '9', 'C'),
|
||||
('F', '0', 'E', 'D')
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self, key_length=12, key_pad=DEFAULT_KEY_PAD, led_period=1000,
|
||||
led_inverted=False, pin_led_status=(16,15,14),
|
||||
pins_keypad_row=(2, 3, 4, 5), pins_keypad_col=(6, 7, 8, 9),
|
||||
pin_rc522_sck=10, pin_rc522_miso=11, pin_rc522_mosi=12,
|
||||
pin_rc522_cs=13, pin_rc522_rst=22, spi_device=1,
|
||||
time_wait_success=10, time_wait_failure=3):
|
||||
self._key_length = key_length
|
||||
self._key_pad = key_pad
|
||||
self._led_period = led_period
|
||||
self._led_inverted = led_inverted
|
||||
self._pin_led_status = pin_led_status[0]
|
||||
self._pin_led_ok = pin_led_status[1]
|
||||
self._pin_led_nok = pin_led_status[2]
|
||||
self._pins_keypad_row = pins_keypad_row
|
||||
self._pins_keypad_col = pins_keypad_col
|
||||
self._pin_rc522_sck = pin_rc522_sck
|
||||
self._pin_rc522_miso = pin_rc522_mosi
|
||||
self._pin_rc522_mosi = pin_rc522_miso
|
||||
self._pin_rc522_cs = pin_rc522_cs
|
||||
self._pin_rc522_rst = pin_rc522_rst
|
||||
self._spi_dev = spi_device
|
||||
self._time_wait_success = time_wait_success
|
||||
self._time_wait_failure = time_wait_failure
|
||||
self._setup()
|
||||
|
||||
@property
|
||||
def callback_success(self):
|
||||
return (self._callback_success, dict(self._callback_success_kwargs))
|
||||
@callback_success.setter
|
||||
def callback_success(self, callback, kwargs):
|
||||
self._callback_success = callback
|
||||
self._callback_success_kwargs = dict(kwargs)
|
||||
|
||||
@property
|
||||
def callback_failure(self):
|
||||
return (self._callback_failure, dict(self._callback_failure_kwargs))
|
||||
@callback_failure.setter
|
||||
def callback_failure(self, callback, kwargs):
|
||||
self._callback_failure = callback
|
||||
self._callback_failure_kwargs = dict(kwargs)
|
||||
|
||||
def _setup(self):
|
||||
val = self._led_inverted
|
||||
self._led_nok = Pin(self._pin_led_nok, Pin.OUT, value=val)
|
||||
self._pwm_nok = PWM(self._led_nok)
|
||||
self._timer_nok = Timer()
|
||||
|
||||
self._led_ok = Pin(self._pin_led_ok, Pin.OUT, value=val)
|
||||
self._pwm_ok = PWM(self._led_ok)
|
||||
self._timer_ok = Timer()
|
||||
|
||||
self._led_status = Pin(self._pin_led_status, Pin.OUT, value=val)
|
||||
self._pwm_status = PWM(self._led_status)
|
||||
self._timer_status = Timer()
|
||||
|
||||
self._reader = MFRC522(
|
||||
spi_dev=self._spi_dev, sck=self._pin_rc522_sck,
|
||||
mosi=self._pin_rc522_mosi, miso=self._pin_rc522_miso,
|
||||
cs=self._pin_rc522_cs, rst=self._pin_rc522_rst
|
||||
)
|
||||
self._keypad = KeyPad(characters=self._key_pad)
|
||||
|
||||
self._led_init()
|
||||
self.led_pulse(
|
||||
led_pwm=self._pwm_status, led_timer=self._timer_status,
|
||||
period=self._led_period*2, half=True
|
||||
)
|
||||
|
||||
self._callback_success = self.callback_ok
|
||||
self._callback_success_kwargs = {}
|
||||
self._callback_failure = self.callback_nok
|
||||
self._callback_failure_kwargs = {}
|
||||
|
||||
def _led_init(self):
|
||||
self._timer_nok.deinit()
|
||||
self._pwm_nok.freq(self._led_period)
|
||||
self._pwm_nok.duty_u16(2**16 if self._led_inverted else 0)
|
||||
self._timer_ok.deinit()
|
||||
self._pwm_ok.freq(self._led_period)
|
||||
self._pwm_ok.duty_u16(2**16 if self._led_inverted else 0)
|
||||
self._timer_status.deinit()
|
||||
self._pwm_status.freq(self._led_period)
|
||||
self._pwm_status.duty_u16(2**16 if self._led_inverted else 0)
|
||||
|
||||
def read_card(self):
|
||||
self._reader.clear_state()
|
||||
status, token = self._reader.request(self._reader.REQUEST_IDLE)
|
||||
if status == self._reader.STATUS_OK:
|
||||
status, serial_number = self._reader.select_near_token()
|
||||
if status == self._reader.STATUS_OK:
|
||||
card_id = MFRC522.id_to_string(serial_number)
|
||||
self._led_init()
|
||||
self.led_pulse(
|
||||
led_pwm=self._pwm_status, led_timer=self._timer_status,
|
||||
period=self._led_period
|
||||
)
|
||||
self._keypad.clear()
|
||||
while len(self._keypad) < self._key_length:
|
||||
utime.sleep(self._keypad.DEFAULT_BUFFER_TIME)
|
||||
key = self._keypad.pop_all()
|
||||
key_bytes = [
|
||||
int(f'{key[i]}{key[i+1]}',16)
|
||||
for i in range(0,len(key),2)
|
||||
]
|
||||
|
||||
data = []
|
||||
for sector in range(16):
|
||||
login_block = sector*4 + 3
|
||||
status = self._reader.authenticate(
|
||||
serial_number, login_block, key_bytes,
|
||||
self._reader.AUTH_MODE_A
|
||||
)
|
||||
if status != self._reader.STATUS_OK:
|
||||
continue
|
||||
try:
|
||||
sector_data = [
|
||||
[
|
||||
c
|
||||
for c in self._reader.read(
|
||||
sector*4 + sector_block
|
||||
)
|
||||
]
|
||||
for sector_block in range(4)
|
||||
]
|
||||
data.append(sector_data)
|
||||
except TypeError:
|
||||
data.clear()
|
||||
self._led_init()
|
||||
self.led_pulse(
|
||||
led_pwm=self._pwm_nok, led_timer=self._timer_nok,
|
||||
period=self._led_period//2
|
||||
)
|
||||
self._callback_failure_kwargs["cardid"] = card_id
|
||||
self._callback_failure(**self._callback_failure_kwargs)
|
||||
utime.sleep(self._time_wait_failure)
|
||||
self._led_init()
|
||||
self.led_pulse(
|
||||
led_pwm=self._pwm_status, period=self._led_period*2,
|
||||
led_timer=self._timer_status, half=True
|
||||
)
|
||||
del self._callback_failure_kwargs["cardid"]
|
||||
break
|
||||
else:
|
||||
self._led_init()
|
||||
self.led_pulse(
|
||||
led_pwm=self._pwm_ok, led_timer=self._timer_ok,
|
||||
period=self._led_period
|
||||
)
|
||||
self._callback_success_kwargs["cardid"] = card_id
|
||||
self._callback_success_kwargs["data"] = data
|
||||
self._callback_success(**self._callback_success_kwargs)
|
||||
utime.sleep(self._time_wait_success)
|
||||
self._led_init()
|
||||
self.led_pulse(
|
||||
led_pwm=self._pwm_status, led_timer=self._timer_status,
|
||||
period=self._led_period*2, half=True
|
||||
)
|
||||
del self._callback_success_kwargs["cardid"]
|
||||
del self._callback_success_kwargs["data"]
|
||||
def find_card_loop(self):
|
||||
while True:
|
||||
self.read_card()
|
||||
utime.sleep(1)
|
||||
|
||||
cardterm = CardTermRC522(led_inverted=True)
|
||||
cardterm.find_card_loop()
|
Loading…
Reference in New Issue
Block a user