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
|
import utime
|
||||||
|
|
||||||
|
|
||||||
class membrane:
|
class Membrane:
|
||||||
"""Class for interpreting input from a membran-like keypad,
|
"""Class for interpreting input from a membran-like keypad,
|
||||||
the default is a 4x4 matrix array membrane keypad.
|
the default is a 4x4 matrix array membrane keypad.
|
||||||
The layout of key bindings and size (i.e. 4x3 alternative)
|
The layout of key bindings and size (i.e. 4x3 alternative)
|
||||||
@ -244,7 +244,7 @@ class membrane:
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
membrane_keypad = membrane()
|
membrane_keypad = Membrane()
|
||||||
pin_size = 12
|
pin_size = 12
|
||||||
|
|
||||||
while len(membrane_keypad) < pin_size:
|
while len(membrane_keypad) < pin_size:
|
||||||
|
@ -636,7 +636,7 @@ if __name__ == "__main__":
|
|||||||
)
|
)
|
||||||
for sector_block in range(4)
|
for sector_block in range(4)
|
||||||
)
|
)
|
||||||
print(f"Sector {sector: 02d}: {sector_text}")
|
print(f"Sector {sector:02d}: {sector_text}")
|
||||||
except TypeError:
|
except TypeError:
|
||||||
break # When removing card, just skip
|
break # When removing card, just skip
|
||||||
else:
|
else:
|
||||||
|
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