CARIA.2.2

Update for the final presentation
huge change with previous version
This commit is contained in:
ccunatbrule
2024-09-03 12:17:44 +02:00
parent ebcb596a4f
commit 2ddf2360e6
44 changed files with 7080 additions and 657 deletions

View File

@@ -1,21 +1,30 @@
import time,json, os, serial, threading, queue
import RPi.GPIO as GPIO
import time
import os
from datetime import datetime
class AlphaBot(object):
def __init__(self, in1=12, in2=13, ena=6, in3=20, in4=21, enb=26):
self.IN1 = in1
self.IN2 = in2
self.IN3 = in3
self.IN4 = in4
self.ENA = ena
self.ENB = enb
# Définition des broches module d'évitement d'obstacles
DAOUT_PIN = 19
AOUT_PIN = 16
def __init__(self):
self.LIDAR_MODULE = serial.Serial('/dev/ttyAMA0', 115200, timeout=1) # SERIAL
self.LIDAR_MODULE.write(b'\x42\x57\x02\x00\x00\x00\x01\x06')
self.RED_LIGHT = 17
self.OBSTACLE_PIN = 16
self.SERVO_PIN = 27
self.IN1 = 12
self.IN2 = 13
self.ENA = 6
self.IN3 = 20
self.IN4 = 21
self.ENB = 26
speed = 30
self.stop_event_obstacle = threading.Event()
self.stop_event_vitesse = threading.Event()
self.vitesse_queue = queue.Queue()
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(self.OBSTACLE_PIN, GPIO.IN, GPIO.PUD_UP)
GPIO.setup(self.SERVO_PIN, GPIO.OUT)
GPIO.setup(self.RED_LIGHT, GPIO.OUT)
GPIO.setup(self.IN1, GPIO.OUT)
GPIO.setup(self.IN2, GPIO.OUT)
GPIO.setup(self.IN3, GPIO.OUT)
@@ -24,52 +33,267 @@ class AlphaBot(object):
GPIO.setup(self.ENB, GPIO.OUT)
self.PWMA = GPIO.PWM(self.ENA, 500) # Utilisation d'une fréquence de 500 Hz pour le PWM
self.PWMB = GPIO.PWM(self.ENB, 500)
self.PWMSERVO = GPIO.PWM(self.SERVO_PIN, 50) # Utilisation d'une fréquence de 50 Hz pour le servo
self.PWMA.start(0) # Démarre avec un rapport cyclique de 0 (moteurs arrêtés)
self.PWMB.start(0)
self.PWMSERVO.start(0)
GPIO.output(self.RED_LIGHT, GPIO.HIGH)
def stop(self):
def ajuster_vitesse_selon_distance(self, distance, vitesse_max=70, vitesse_min=20):
if distance < 20: # Distance critique, arrêt
vitesse = 0
elif distance < 50: # Très proche, ralentir
vitesse = vitesse_min
else: # Vitesse normale
vitesse = vitesse_max * (distance / 100)
vitesse = max(vitesse_min, min(vitesse, vitesse_max))
return vitesse
def set_angle(self, angle):
if 0 <= angle <= 180:
pulse_width_ms = (angle / 180) * (2 - 1) + 1
duty_cycle = (pulse_width_ms / 20) * 100
self.PWMSERVO.ChangeDutyCycle(duty_cycle)
# Calcul du temps nécessaire pour atteindre l'angle donné
movement_time = (angle / 60) * 0.15 # 0.12 sec pour 60 degrés
time.sleep(movement_time)
else:
print("Angle hors de portée. Le rapport cyclique doit être compris entre 2,5 et 12,5.")
def blink_led(self, blink_duration=0.2):
self.blinking = True
while self.blinking: # Continue tant que blinking est True
GPIO.output(self.RED_LIGHT, GPIO.HIGH)
time.sleep(blink_duration)
GPIO.output(self.RED_LIGHT, GPIO.LOW)
time.sleep(blink_duration)
GPIO.output(self.RED_LIGHT, GPIO.LOW)
# Fonction pour les manœuvres non spécifiées
def maneuver_unspecified(self, duration):
GPIO.output(self.RED_LIGHT, GPIO.HIGH)
print("Manoeuvre non spécifiée")
time.sleep(duration)
def stop(self, duration):
GPIO.output(self.RED_LIGHT, GPIO.HIGH)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(0)
self.PWMB.ChangeDutyCycle(0)
print("Le robot est arreté")
def forward(self, speed):
GPIO.output(self.IN1, GPIO.HIGH)
print(f"Arrêt durant {duration} secondes")
time.sleep(duration)
GPIO.output(self.RED_LIGHT, GPIO.LOW)
def emergencystop(self):
# Lancer le clignotement dans un thread séparé
blink_thread = threading.Thread(target=self.blink_led)
blink_thread.start()
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(0)
self.PWMB.ChangeDutyCycle(0)
print("Arrêt d'urgence !")
time.sleep(0.1)
# Stopper le clignotement de la LED
self.blinking = False
blink_thread.join() # Attendre que le thread de clignotement se termine
# FORWARD MOVE
def forward(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print(f"Avancer durant {duration} secondes à une vitesse de", speed)
time.sleep(duration)
print("Le robot avance avec une vitesse de", speed)
def ramp_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 1.5)
print(f"Traitement pour prendre la rampe de gauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def fork_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 1.1)
print(f"Traitement pour prendre la fourche de gauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def ramp_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed * 1.5)
self.PWMB.ChangeDutyCycle(speed)
print(f"Traitement pour prendre la rampe de droite durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def backward(self, speed):
def fork_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 1.1)
print(f"Traitement pour prendre la fourche de droite durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def merge(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed * 0.8)
self.PWMB.ChangeDutyCycle(speed * 0.8)
print(f"Traitement pour fusionner dans le trafic durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
# BACKWARD MOVE
def backward(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print(f"Reculer durant {duration} secondes à une vitesse de", speed)
time.sleep(duration)
# LEFT MOVE
def left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print("Le robot recul avec une vitesse de", speed)
def left(self, speed):
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
print("Le robot tourne à guauche avec une vitesse de", speed)
def right(self, speed):
print(f"Tourner à guauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def turn_slight_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 0.1)
print(f"Traitement pour tourner légèrement à gauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def turn_sharp_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 1)
print(f"Traitement pour tourner brusquement à gauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def u_turn_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print(f"Traitement pour faire demi-tour à gauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration * 2)
def roundabout_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 0.5)
print(f"Traitement pour tourner à gauche au rond-point durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
# RIGHT MOVE
def right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print("Le robot tourne à droite avec une vitesse de", speed)
print(f"Tourner à droite durant {duration} secondes à une vitesse de", speed)
time.sleep(duration)
def turn_slight_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed * 0.1)
self.PWMB.ChangeDutyCycle(speed)
print(f"Traitement pour tourner légèrement à droite durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def turn_sharp_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 1)
print(f"Traitement pour tourner brusquement à droite durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def u_turn_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print(f"Traitement pour faire demi-tour à droite durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration * 2)
def roundabout_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed * 0.5)
self.PWMB.ChangeDutyCycle(speed)
print(f"Traitement pour tourner à droite au rond-point durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def setPWMA(self, value):
"""
@@ -94,26 +318,75 @@ class AlphaBot(object):
self.PWMA.ChangeDutyCycle(left)
self.PWMB.ChangeDutyCycle(right)
def objetrack_ir(self):
os.system('sudo python3 ~/AppControl/Infrared_Tracking_Objects.py')
# Fonction pour surveiller les obstacle en arrière-plan
def monitor_obstacle(self):
global emergency_stop
while not self.stop_event_obstacle.is_set():
DR_status = GPIO.input(self.OBSTACLE_PIN)
if DR_status == 0: # Obstacle détecté
self.emergencystop()
emergency_stop = True
while GPIO.input(self.OBSTACLE_PIN) == 0: # Attendre que l'obstacle soit dégagé
time.sleep(0.1)
print("Obstacle dégagé. Attente de 5 secondes avant de reprendre.")
emergency_stop = False
time.sleep(0.05) # Pause légère pour éviter la surcharge du CPU
def linetrack_ir(self):
os.system('sudo python3 ~/AppControl/Infrared_Line_Tracking.py')
def monitor_vitesse(self):
try:
while not self.stop_event_vitesse.is_set():
if self.LIDAR_MODULE.in_waiting >= 9:
if b'Y' == self.LIDAR_MODULE.read() and b'Y' == self.LIDAR_MODULE.read():
Dist_L = self.LIDAR_MODULE.read()
Dist_H = self.LIDAR_MODULE.read()
Dist_Total = (Dist_H[0] * 256) + Dist_L[0]
for i in range(0, 5):
self.LIDAR_MODULE.read() # Lecture et ignore des octets supplémentaires
print("Distance à l'avant du véhicule:", Dist_Total, "cm")
# Définir les paramètres de vitesse
vitesse_max = 50 # Vitesse maximale en unités (à ajuster)
distance_min = 10 # Distance minimale pour une vitesse de 0 (en cm)
# Ajuster la vitesse en fonction de la distance mesurée
if Dist_Total <= distance_min:
vitesse_ajustee = 0 # Arrêter si trop proche
elif Dist_Total > 100: # Distance maximale où la vitesse est maximale
vitesse_ajustee = vitesse_max
else:
# Calculer la vitesse en fonction de la distance
vitesse_ajustee = int(vitesse_max * (Dist_Total - distance_min) / (100 - distance_min))
# Mettre la vitesse ajustée dans la queue
self.vitesse_queue.put(vitesse_ajustee)
except Exception as e:
print(f"Erreur lors de la mesure de la vitesse: {e}")
# En cas d'erreur, vous pouvez décider de placer une valeur par défaut dans la queue
self.vitesse_queue.put(None)
def objetavoid_ir(self):
os.system('sudo python3 ~/AppControl/Infrared_Obstacle_Avoidance.py')
def cleanup(self):
GPIO.cleanup()
print("Nettoyage des GPIO effectué.")
def obstacleavoid_ultrason(self):
os.system('sudo python3 ~/AppControl/Ultrasonic_Obstacle_Avoidance.py')
def move_ultrason(self):
os.system('sudo python3 ~/AppControl/Ultrasonic_Ranging.py')
def control_ir(self):
os.system('sudo python3 ~/AppControl/Infrared_Remote_Control.py')
def face_ia(self):
os.system('sudo python3 ~/AppControl/visage_camera_raspberry.py')
def line_ia(self):
os.system('sudo python3 ~/AppControl/visage_camera_v2_raspberry.py')
def enregistrer_resultats(self, nom_script, fonctionnement_ok, status):
# Préparer les données à enregistrer
nouveau_resultat = {
'date': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
'nom': nom_script,
'fonctionnement_ok': fonctionnement_ok,
'status': status
}
# Chemin vers le fichier de logs
fichier_logs = './logs/resultats_tests.json'
# Charger les données existantes si le fichier existe
if os.path.exists(fichier_logs):
with open(fichier_logs, 'r') as f:
try:
resultats = json.load(f)
except json.JSONDecodeError:
resultats = []
else:
resultats = []
# Ajouter le nouveau résultat
resultats.append(nouveau_resultat)
# Enregistrer les résultats mis à jour dans le fichier JSON
with open(fichier_logs, 'w') as f:
json.dump(resultats, f, indent=4)
print("Résultats enregistrés avec succès.")

View File

@@ -0,0 +1,89 @@
# Code by Simon Monk https://github.com/simonmonk/
from joyit_mfrc522 import MFRC522
class SimpleMFRC522:
READER = None
KEY = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
BLOCK_ADDRS = [8, 9, 10]
def __init__(self):
self.READER = MFRC522()
def read(self):
id, text = self.read_no_block()
while not id:
id, text = self.read_no_block()
return id, text
def read_id(self):
id = self.read_id_no_block()
while not id:
id = self.read_id_no_block()
return id
def read_id_no_block(self):
(status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
if status != self.READER.MI_OK:
return None
(status, uid) = self.READER.MFRC522_Anticoll()
if status != self.READER.MI_OK:
return None
return self.uid_to_num(uid)
def read_no_block(self):
(status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
if status != self.READER.MI_OK:
return None, None
(status, uid) = self.READER.MFRC522_Anticoll()
if status != self.READER.MI_OK:
return None, None
id = self.uid_to_num(uid)
self.READER.MFRC522_SelectTag(uid)
status = self.READER.MFRC522_Auth(self.READER.PICC_AUTHENT1A, 11, self.KEY, uid)
data = []
text_read = ''
if status == self.READER.MI_OK:
for block_num in self.BLOCK_ADDRS:
block = self.READER.MFRC522_Read(block_num)
if block:
data += block
if data:
text_read = ''.join(chr(i) for i in data)
self.READER.MFRC522_StopCrypto1()
return id, text_read
def write(self, text):
id, text_in = self.write_no_block(text)
while not id:
id, text_in = self.write_no_block(text)
return id, text_in
def write_no_block(self, text):
(status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
if status != self.READER.MI_OK:
return None, None
(status, uid) = self.READER.MFRC522_Anticoll()
if status != self.READER.MI_OK:
return None, None
id = self.uid_to_num(uid)
self.READER.MFRC522_SelectTag(uid)
status = self.READER.MFRC522_Auth(self.READER.PICC_AUTHENT1A, 11, self.KEY, uid)
self.READER.MFRC522_Read(11)
if status == self.READER.MI_OK:
data = bytearray()
data.extend(bytearray(text.ljust(len(self.BLOCK_ADDRS) * 16).encode('ascii')))
i = 0
for block_num in self.BLOCK_ADDRS:
self.READER.MFRC522_Write(block_num, data[(i*16):(i+1)*16])
i += 1
self.READER.MFRC522_StopCrypto1()
return id, text[0:(len(self.BLOCK_ADDRS) * 16)]
def uid_to_num(self, uid):
n = 0
for i in range(0, 5):
n = n * 256 + uid[i]
return n

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,413 @@
#!/usr/bin/env python3
# -*- coding: utf8 -*-
#
# Copyright 2014,2018 Mario Gomez <mario.gomez@teubi.co>
#
# This file is part of MFRC522-Python
# MFRC522-Python is a simple Python implementation for
# the MFRC522 NFC Card Reader for the Raspberry Pi.
#
# MFRC522-Python is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# MFRC522-Python is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with MFRC522-Python. If not, see <http://www.gnu.org/licenses/>.
#
from gpiozero import DigitalOutputDevice
import spidev
import signal
import time
import logging
class MFRC522:
MAX_LEN = 16
PCD_IDLE = 0x00
PCD_AUTHENT = 0x0E
PCD_RECEIVE = 0x08
PCD_TRANSMIT = 0x04
PCD_TRANSCEIVE = 0x0C
PCD_RESETPHASE = 0x0F
PCD_CALCCRC = 0x03
PICC_REQIDL = 0x26
PICC_REQALL = 0x52
PICC_ANTICOLL = 0x93
PICC_SElECTTAG = 0x93
PICC_AUTHENT1A = 0x60
PICC_AUTHENT1B = 0x61
PICC_READ = 0x30
PICC_WRITE = 0xA0
PICC_DECREMENT = 0xC0
PICC_INCREMENT = 0xC1
PICC_RESTORE = 0xC2
PICC_TRANSFER = 0xB0
PICC_HALT = 0x50
MI_OK = 0
MI_NOTAGERR = 1
MI_ERR = 2
Reserved00 = 0x00
CommandReg = 0x01
CommIEnReg = 0x02
DivlEnReg = 0x03
CommIrqReg = 0x04
DivIrqReg = 0x05
ErrorReg = 0x06
Status1Reg = 0x07
Status2Reg = 0x08
FIFODataReg = 0x09
FIFOLevelReg = 0x0A
WaterLevelReg = 0x0B
ControlReg = 0x0C
BitFramingReg = 0x0D
CollReg = 0x0E
Reserved01 = 0x0F
Reserved10 = 0x10
ModeReg = 0x11
TxModeReg = 0x12
RxModeReg = 0x13
TxControlReg = 0x14
TxAutoReg = 0x15
TxSelReg = 0x16
RxSelReg = 0x17
RxThresholdReg = 0x18
DemodReg = 0x19
Reserved11 = 0x1A
Reserved12 = 0x1B
MifareReg = 0x1C
Reserved13 = 0x1D
Reserved14 = 0x1E
SerialSpeedReg = 0x1F
Reserved20 = 0x20
CRCResultRegM = 0x21
CRCResultRegL = 0x22
Reserved21 = 0x23
ModWidthReg = 0x24
Reserved22 = 0x25
RFCfgReg = 0x26
GsNReg = 0x27
CWGsPReg = 0x28
ModGsPReg = 0x29
TModeReg = 0x2A
TPrescalerReg = 0x2B
TReloadRegH = 0x2C
TReloadRegL = 0x2D
TCounterValueRegH = 0x2E
TCounterValueRegL = 0x2F
Reserved30 = 0x30
TestSel1Reg = 0x31
TestSel2Reg = 0x32
TestPinEnReg = 0x33
TestPinValueReg = 0x34
TestBusReg = 0x35
AutoTestReg = 0x36
VersionReg = 0x37
AnalogTestReg = 0x38
TestDAC1Reg = 0x39
TestDAC2Reg = 0x3A
TestADCReg = 0x3B
Reserved31 = 0x3C
Reserved32 = 0x3D
Reserved33 = 0x3E
Reserved34 = 0x3F
serNum = []
def __init__(self, bus=0, device=0, spd=1000000, pin_mode=10, pin_rst=-1, debugLevel='WARNING'):
self.spi = spidev.SpiDev()
self.spi.open(bus, device)
self.spi.max_speed_hz = spd
self.logger = logging.getLogger('mfrc522Logger')
self.logger.addHandler(logging.StreamHandler())
level = logging.getLevelName(debugLevel)
self.logger.setLevel(level)
if pin_rst == -1:
pin_rst = 15
self._RST = DigitalOutputDevice(pin_rst, initial_value=True)
self.MFRC522_Init()
def MFRC522_Reset(self):
self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE)
def Write_MFRC522(self, addr, val):
val = self.spi.xfer2([(addr << 1) & 0x7E, val])
def Read_MFRC522(self, addr):
val = self.spi.xfer2([((addr << 1) & 0x7E) | 0x80, 0])
return val[1]
def Close_MFRC522(self):
self.spi.close()
def SetBitMask(self, reg, mask):
tmp = self.Read_MFRC522(reg)
self.Write_MFRC522(reg, tmp | mask)
def ClearBitMask(self, reg, mask):
tmp = self.Read_MFRC522(reg)
self.Write_MFRC522(reg, tmp & (~mask))
def AntennaOn(self):
temp = self.Read_MFRC522(self.TxControlReg)
if (~(temp & 0x03)):
self.SetBitMask(self.TxControlReg, 0x03)
def AntennaOff(self):
self.ClearBitMask(self.TxControlReg, 0x03)
def MFRC522_ToCard(self, command, sendData):
backData = []
backLen = 0
status = self.MI_ERR
irqEn = 0x00
waitIRq = 0x00
lastBits = None
n = 0
if command == self.PCD_AUTHENT:
irqEn = 0x12
waitIRq = 0x10
if command == self.PCD_TRANSCEIVE:
irqEn = 0x77
waitIRq = 0x30
self.Write_MFRC522(self.CommIEnReg, irqEn | 0x80)
self.ClearBitMask(self.CommIrqReg, 0x80)
self.SetBitMask(self.FIFOLevelReg, 0x80)
self.Write_MFRC522(self.CommandReg, self.PCD_IDLE)
for i in range(len(sendData)):
self.Write_MFRC522(self.FIFODataReg, sendData[i])
self.Write_MFRC522(self.CommandReg, command)
if command == self.PCD_TRANSCEIVE:
self.SetBitMask(self.BitFramingReg, 0x80)
i = 2000
while True:
n = self.Read_MFRC522(self.CommIrqReg)
i -= 1
if ~((i != 0) and ~(n & 0x01) and ~(n & waitIRq)):
break
self.ClearBitMask(self.BitFramingReg, 0x80)
if i != 0:
if (self.Read_MFRC522(self.ErrorReg) & 0x1B) == 0x00:
status = self.MI_OK
if n & irqEn & 0x01:
status = self.MI_NOTAGERR
if command == self.PCD_TRANSCEIVE:
n = self.Read_MFRC522(self.FIFOLevelReg)
lastBits = self.Read_MFRC522(self.ControlReg) & 0x07
if lastBits != 0:
backLen = (n - 1) * 8 + lastBits
else:
backLen = n * 8
if n == 0:
n = 1
if n > self.MAX_LEN:
n = self.MAX_LEN
for i in range(n):
backData.append(self.Read_MFRC522(self.FIFODataReg))
else:
status = self.MI_ERR
return (status, backData, backLen)
def MFRC522_Request(self, reqMode):
status = None
backBits = None
TagType = []
self.Write_MFRC522(self.BitFramingReg, 0x07)
TagType.append(reqMode)
(status, backData, backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, TagType)
if ((status != self.MI_OK) | (backBits != 0x10)):
status = self.MI_ERR
return (status, backBits)
def MFRC522_Anticoll(self):
backData = []
serNumCheck = 0
serNum = []
self.Write_MFRC522(self.BitFramingReg, 0x00)
serNum.append(self.PICC_ANTICOLL)
serNum.append(0x20)
(status, backData, backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, serNum)
if (status == self.MI_OK):
i = 0
if len(backData) == 5:
for i in range(4):
serNumCheck = serNumCheck ^ backData[i]
if serNumCheck != backData[4]:
status = self.MI_ERR
else:
status = self.MI_ERR
return (status, backData)
def CalulateCRC(self, pIndata):
self.ClearBitMask(self.DivIrqReg, 0x04)
self.SetBitMask(self.FIFOLevelReg, 0x80)
for i in range(len(pIndata)):
self.Write_MFRC522(self.FIFODataReg, pIndata[i])
self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC)
i = 0xFF
while True:
n = self.Read_MFRC522(self.DivIrqReg)
i -= 1
if not ((i != 0) and not (n & 0x04)):
break
pOutData = []
pOutData.append(self.Read_MFRC522(self.CRCResultRegL))
pOutData.append(self.Read_MFRC522(self.CRCResultRegM))
return pOutData
def MFRC522_SelectTag(self, serNum):
backData = []
buf = []
buf.append(self.PICC_SElECTTAG)
buf.append(0x70)
for i in range(5):
buf.append(serNum[i])
pOut = self.CalulateCRC(buf)
buf.append(pOut[0])
buf.append(pOut[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf)
if (status == self.MI_OK) and (backLen == 0x18):
self.logger.debug("Size: " + str(backData[0]))
return backData[0]
else:
return 0
def MFRC522_Auth(self, authMode, BlockAddr, Sectorkey, serNum):
buff = []
# First byte should be the authMode (A or B)
buff.append(authMode)
# Second byte is the trailerBlock (usually 7)
buff.append(BlockAddr)
# Now we need to append the authKey which usually is 6 bytes of 0xFF
for i in range(len(Sectorkey)):
buff.append(Sectorkey[i])
# Next we append the first 4 bytes of the UID
for i in range(4):
buff.append(serNum[i])
# Now we start the authentication itself
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_AUTHENT, buff)
# Check if an error occurred
if not (status == self.MI_OK):
self.logger.error("AUTH ERROR!!")
if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0:
self.logger.error("AUTH ERROR(status2reg & 0x08) != 0")
# Return the status
return status
def MFRC522_StopCrypto1(self):
self.ClearBitMask(self.Status2Reg, 0x08)
def MFRC522_Read(self, blockAddr):
recvData = []
recvData.append(self.PICC_READ)
recvData.append(blockAddr)
pOut = self.CalulateCRC(recvData)
recvData.append(pOut[0])
recvData.append(pOut[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, recvData)
if not (status == self.MI_OK):
self.logger.error("Error while reading!")
if len(backData) == 16:
self.logger.debug("Sector " + str(blockAddr) + " " + str(backData))
return backData
else:
return None
def MFRC522_Write(self, blockAddr, writeData):
buff = []
buff.append(self.PICC_WRITE)
buff.append(blockAddr)
crc = self.CalulateCRC(buff)
buff.append(crc[0])
buff.append(crc[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buff)
if not (status == self.MI_OK) or not (backLen == 4) or not ((backData[0] & 0x0F) == 0x0A):
status = self.MI_ERR
self.logger.debug("%s backdata &0x0F == 0x0A %s" % (backLen, backData[0] & 0x0F))
if status == self.MI_OK:
buf = []
for i in range(16):
buf.append(writeData[i])
crc = self.CalulateCRC(buf)
buf.append(crc[0])
buf.append(crc[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf)
if not (status == self.MI_OK) or not (backLen == 4) or not ((backData[0] & 0x0F) == 0x0A):
self.logger.error("Error while writing")
if status == self.MI_OK:
self.logger.debug("Data written")
def MFRC522_DumpClassic1K(self, key, uid):
for i in range(64):
status = self.MFRC522_Auth(self.PICC_AUTHENT1A, i, key, uid)
# Check if authenticated
if status == self.MI_OK:
self.MFRC522_Read(i)
else:
self.logger.error("Authentication error")
def MFRC522_Init(self):
self.MFRC522_Reset()
self.Write_MFRC522(self.TModeReg, 0x8D)
self.Write_MFRC522(self.TPrescalerReg, 0x3E)
self.Write_MFRC522(self.TReloadRegL, 30)
self.Write_MFRC522(self.TReloadRegH, 0)
self.Write_MFRC522(self.TxAutoReg, 0x40)
self.Write_MFRC522(self.ModeReg, 0x3D)
self.AntennaOn()

View File

@@ -0,0 +1,4 @@
from .MFRC522 import MFRC522
from .SimpleMFRC522 import SimpleMFRC522
name = "joyit_mfrc522"