/*
*
* All the resources for this project: http://randomnerdtutorials.com/
* Modified by Rui Santos
*
* Created by FILIPEFLOP
*
*/
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
void setup()
{
Serial.begin(9600); // Initiate a serial communication
SPI.begin(); // Initiate SPI bus
mfrc522.PCD_Init(); // Initiate MFRC522
Serial.println("Approximate your card to the reader...");
Serial.println();
}
void loop()
{
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
//Show UID on serial monitor
Serial.print("UID tag :");
String content= "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++)
{
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
Serial.println();
Serial.print("Message : ");
content.toUpperCase();
if (content.substring(1) == "BD 31 15 2B") //change here the UID of the card/cards that you want to give access
{
Serial.println("Authorized access");
Serial.println();
delay(3000);
}
else {
Serial.println(" Access denied");
delay(3000);
}
}
// Para já, apenas consigo pedir para passara o cartão, mas dá sempre erro de autentificação
// writeandread.py
from machine import Pin, SPI, I2C
from mfrc522 import MFRC522
from i2c_lcd import I2cLcd
import utime
# Configurações do SPI e do RC522
sck = Pin(18, Pin.OUT)
mosi = Pin(23, Pin.OUT)
miso = Pin(19, Pin.IN)
spi = SPI(1, baudrate=100000, polarity=0, phase=0, sck=sck, mosi=mosi, miso=miso)
sda = Pin(5, Pin.OUT)
# Configurações do I2C e do LCD
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
I2C_ADDR = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
def do_write_and_read():
rdr = MFRC522(spi, sda)
lcd.putstr("Aproxime o cartao")
print("Aproxime o cartao")
try:
while True:
(stat, tag_type) = rdr.request(rdr.REQIDL)
if stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll()
if stat == rdr.OK:
uid = "0x%02x%02x%02x%02x" % (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3])
print("Cartao detectado")
print(" - tag type: 0x%02x" % tag_type)
print(" - uid: %s" % uid)
lcd.clear()
lcd.putstr("Cartao detectado")
lcd.move_to(0, 1)
lcd.putstr("UID: %s" % uid)
if rdr.select_tag(raw_uid) == rdr.OK:
key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
if rdr.auth(rdr.AUTHENT1A, 7, key, raw_uid) == rdr.OK:
# Escolha da operação
x = int(input("Escolha: 1-Carregamento, 2-Consumo, 3-Saldo: "))
escolha(rdr, x)
if x == 1 or x == 2:
lcd.clear()
lcd.putstr("Operacao efetuada")
utime.sleep(2)
if x == 3:
saldo = rdr.read(7)
lcd.clear()
lcd.putstr("Saldo: {:.2f} EUR".format(saldo))
utime.sleep(2)
rdr.stop_crypto1()
else:
print("Erro de autenticacao")
lcd.clear()
lcd.putstr("Erro de autenticacao")
utime.sleep(2)
else:
print("Falha ao selecionar o cartao")
lcd.clear()
lcd.putstr("Falha ao selecionar")
utime.sleep(2)
utime.sleep(1)
except KeyboardInterrupt:
print("Bye")
lcd.clear()
lcd.putstr("Programa terminado")
utime.sleep(2)
# Execute a função principal
do_write_and_read()
// functions.py
from machine import Pin, SPI
bebidas = ["Agua", "Fino", "Shot", "Bebida Branca"]
bebidasabreviadas = ["a", "f", "s", "b"]
precos = [1.1, 1.2, 1.0, 3.5]
def filtro(bebida, quantidade):
txt = str(bebida)
letra = txt.lower()[0]
if letra == "á":
letra = "a"
for i in range(len(bebidas)):
if letra == bebidasabreviadas[i]:
custo = precos[i]
return custo * quantidade
return None
def debito(rdr, custo):
saldo = rdr.read(7)
saldo = int.from_bytes(saldo, 'little') / 100
if saldo - custo < 0:
print("Nao tem saldo suficiente")
return None
else:
saldonovo = saldo - custo
print("Saldo Disponivel: {:.2f} EUR".format(saldonovo))
saldonovo_bytes = int(saldonovo * 100).to_bytes(16, 'little')
rdr.write(7, saldonovo_bytes)
return saldonovo
def carregar(rdr, valor, PIN):
saldo = rdr.read(7)
saldo = int.from_bytes(saldo, 'little') / 100
if PIN == 1234:
saldo += valor
saldonovo_bytes = int(saldo * 100).to_bytes(16, 'little')
rdr.write(7, saldonovo_bytes)
print("Saldo Disponivel: {:.2f} EUR".format(saldo))
return saldo
else:
print("PIN incorreto")
return None
def lersaldo(rdr):
saldo_disponivel = rdr.read(7)
saldo_disponivel = int.from_bytes(saldo_disponivel, 'little') / 100
print("Saldo Disponivel: {:.2f} EUR".format(saldo_disponivel))
return saldo_disponivel
def escolha(rdr, lcd, x):
if x == 1:
lcd.clear()
lcd.putstr("Quanto carregar?")
valor = float(input("Quanto pretende carregar? "))
lcd.clear()
lcd.putstr("Codigo PIN")
PIN = int(input("Codigo de Confirmacao: "))
return carregar(rdr, valor, PIN)
elif x == 2:
lcd.clear()
lcd.putstr("Bebida: a, f, s, b")
bebida = str(input("Seleciona a Bebida: "))
lcd.clear()
lcd.putstr("Quantidade:")
quantidade = int(input("Seleciona a Quantidade: "))
custo = filtro(bebida, quantidade)
return debito(rdr, custo)
elif x == 3:
return lersaldo(rdr)
else:
print("Erro")
lcd.clear()
lcd.putstr("Selecione 1-3")
x = int(input("1 - Carregamentos, 2 - Consumo, 3 - Consulta de Saldo: "))
return escolha(rdr, lcd, x)
//Fiz com que apenas um cartão seja permitido, não dando erro de autentificação
//writeandread.py
from machine import Pin, SPI, I2C
from mfrc522 import MFRC522
from i2c_lcd import I2cLcd
import utime
from functions import escolha
# Configurações do SPI e do RC522
sck = Pin(18, Pin.OUT)
mosi = Pin(23, Pin.OUT)
miso = Pin(19, Pin.IN)
spi = SPI(1, baudrate=100000, polarity=0, phase=0, sck=sck, mosi=mosi, miso=miso)
sda = Pin(5, Pin.OUT)
# Configurações do I2C e do LCD
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
I2C_ADDR = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
# UIDs dos cartões permitidos
allowed_uids = ["0x8ec02423"]
def do_write_and_read():
rdr = MFRC522(spi, sda)
lcd.putstr("Aproxime o cartao")
print("Aproxime o cartao")
try:
while True:
(stat, tag_type) = rdr.request(rdr.REQIDL)
if stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll()
if stat == rdr.OK:
uid = "0x%02x%02x%02x%02x" % (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3])
print("Cartao detectado")
print(" - tag type: 0x%02x" % tag_type)
print(" - uid: %s" % uid)
lcd.clear()
lcd.putstr("Cartao detectado")
lcd.move_to(0, 1)
lcd.putstr("UID: %s" % uid)
if uid in allowed_uids:
if rdr.select_tag(raw_uid) == rdr.OK:
key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
# Autentica no bloco 7 usando a chave padrão
if rdr.auth(rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK: # Certifique-se de usar o bloco correto
# Escolha da operação
lcd.clear()
lcd.putstr("Escolha:")
lcd.move_to(0, 1)
lcd.putstr("1- Carregar")
utime.sleep(2)
lcd.clear()
lcd.putstr("2- Consumir")
utime.sleep(2)
lcd.clear()
lcd.putstr("3- Saldo")
utime.sleep(2)
x = int(input("Escolha: 1-Carregamento, 2-Consumo, 3-Saldo: "))
resultado = escolha(rdr, lcd, x)
if resultado is not None:
if x == 1 or x == 2:
lcd.clear()
lcd.putstr("Operacao efetuada")
utime.sleep(2)
if x == 3:
lcd.clear()
lcd.putstr("Saldo: {:.2f} EUR".format(resultado))
utime.sleep(2)
else:
lcd.clear()
lcd.putstr("Erro na operacao")
utime.sleep(2)
rdr.stop_crypto1()
else:
print("Erro de autenticacao")
lcd.clear()
lcd.putstr("Erro de autenticacao")
utime.sleep(2)
else:
print("Falha ao selecionar o cartao")
lcd.clear()
lcd.putstr("Falha ao selecionar")
utime.sleep(2)
else:
print("Cartao nao permitido")
lcd.clear()
lcd.putstr("Cartao nao permitido")
utime.sleep(2)
utime.sleep(1)
except KeyboardInterrupt:
print("Bye")
lcd.clear()
lcd.putstr("Programa terminado")
utime.sleep(2)
# Execute a função principal
do_write_and_read()
//functions.py
from machine import Pin, SPI
bebidas = ["Agua", "Fino", "Shot", "Bebida Branca"]
bebidasabreviadas = ["a", "f", "s", "b"]
precos = [1.1, 1.2, 1.0, 3.5]
def filtro(bebida, quantidade):
txt = str(bebida)
letra = txt.lower()[0]
if letra == "á":
letra = "a"
for i in range(len(bebidas)):
if letra == bebidasabreviadas[i]:
custo = precos[i]
return custo * quantidade
return None
def debito(rdr, custo):
saldo = rdr.read(8) # Certifique-se de ler do bloco correto
if saldo == rdr.ERROR:
print("Erro na leitura do saldo")
return None
saldo = int.from_bytes(saldo, 'little') / 100
print("Saldo atual: {:.2f} EUR".format(saldo))
if saldo - custo < 0:
print("Não tem saldo suficiente")
return None
else:
saldonovo = saldo - custo
print("Novo saldo: {:.2f} EUR".format(saldonovo))
saldonovo_bytes = int(saldonovo * 100).to_bytes(16, 'little')
if rdr.write(8, saldonovo_bytes) == rdr.OK: # Certifique-se de escrever no bloco correto
return saldonovo
else:
print("Erro na escrita do novo saldo")
return None
def carregar(rdr, valor, PIN):
saldo = rdr.read(8) # Certifique-se de ler do bloco correto
if saldo == rdr.ERROR:
print("Erro na leitura do saldo")
return None
saldo = int.from_bytes(saldo, 'little') / 100
if PIN == 1234:
saldo += valor
saldonovo_bytes = int(saldo * 100).to_bytes(16, 'little')
if rdr.write(8, saldonovo_bytes) == rdr.OK: # Certifique-se de escrever no bloco correto
print("Novo saldo: {:.2f} EUR".format(saldo))
return saldo
else:
print("Erro na escrita do novo saldo")
return None
else:
print("PIN incorreto")
return None
def lersaldo(rdr):
saldo_disponivel = rdr.read(8) # Certifique-se de ler do bloco correto
if saldo_disponivel == rdr.ERROR:
print("Erro na leitura do saldo")
return None
saldo_disponivel = int.from_bytes(saldo_disponivel, 'little') / 100
print("Saldo disponível: {:.2f} EUR".format(saldo_disponivel))
return saldo_disponivel
def escolha(rdr, lcd, x):
if x == 1:
lcd.clear()
lcd.putstr("Quanto carregar?")
valor = float(input("Quanto pretende carregar? "))
lcd.clear()
lcd.putstr("Código PIN")
PIN = int(input("Código de Confirmação: "))
return carregar(rdr, valor, PIN)
elif x == 2:
lcd.clear()
lcd.putstr("Bebida: a, f, s, b")
bebida = str(input("Seleciona a Bebida: "))
lcd.clear()
lcd.putstr("Quantidade:")
quantidade = int(input("Seleciona a Quantidade: "))
custo = filtro(bebida, quantidade)
return debito(rdr, custo)
elif x == 3:
return lersaldo(rdr)
else:
print("Erro")
lcd.clear()
lcd.putstr("Selecione 1-3")
x = int(input("1 - Carregamentos, 2 - Consumo, 3 - Consulta de Saldo: "))
return escolha(rdr, lcd, x)