SPI, communication vers un écran TFT32" et un RC522

Bonjour, Je travaille sur un Raspberry Pi 3 Model B V1.2 monter sur mage raspbian buster full.

Pour la réalisation d’un projet en entreprise, je doit faire fonctionner un écran TFT32" Touch Shield ForRPI et un module RFID-RC522. les deux fonctionne très bien séparément, mais une fois assemblé sur la même carte… Leurs cohabitation me parait impossible ( je dis ça après de nombreux test évidemment). Je viens demander de l’aide, prouvez moi que j’ai tort s’il vous plais… Quand je lance la commande permettant de basculer vers l’écran « ./LCD32-show » le Raspberry configure sa nouvelle résolution d’écran, en redémarrant il désactive automatiquement le Spi, donc le RC-522 ne fonctionne plus. je ne pense pas que se soit le seul problème… Voila toute piste est la bien venue, merci !

hello,

tu peux pas utiliser le rfid sur I2C ?
sinon difficile sans le schéma du montage ni le programme de trouver le bug …

bonjour,
le Module n’est pas prévue pour une connexion en I2C.
ci-dessous le programme du RC522, ce programme fonctionne et ne présente aucun bug.

début de la procédure pour configurer le Module RC522 :

Activer le protocole SPI de la Raspberry Pi

Avant d’écrire le programme, activons le protocole SPI sur notre Raspberry Pi afin de pouvoir utiliser le module RFID.

Pour l’activer, il vous suffit de lancer la commande sudo raspi-config, sur votre raspberry, puis de choisir Interfacing Options, SPI, Yes et enfin Finish.

Installer la librairie pi-rc522

Dernière pré-requis, nous allons installer la librairie Python3 « pi-rc522 » qui permet de contrôler le lecteur RC522.

Nous allons utiliser Pip3, un gestionnaire de librairie pour Python.

Il vous suffit de lancer la commande :

sudo pip3 install pi-rc522
#------------------------------------début du programme----------------------------------------------------------------#
#!/usr/bin/env python3.5
#-- coding: utf-8 –

import RPi.GPIO as GPIO #Importe la bibliothèque pour contrôler les GPIOs
from pirc522 import RFID
import time

GPIO.setmode(GPIO.BOARD) #Définit le mode de numérotation (Board)
GPIO.setwarnings(False) #On désactive les messages d’alerte

rc522 = RFID() #On instancie la lib

print('En attente d’un badge (pour quitter, Ctrl + c): ') #On affiche un message demandant à l’utilisateur de passer son badge

#On va faire une boucle infinie pour lire en boucle
while True :
rc522.wait_for_tag() #On attnd qu’une puce RFID passe à portée
(error, tag_type) = rc522.request() #Quand une puce a été lue, on récupère ses infos

if not error : #Si on a pas d'erreur
    (error, uid) = rc522.anticoll() #On nettoie les possibles collisions, ça arrive si plusieurs cartes passent en même temps

    if not error : #Si on a réussi à nettoyer
        print('Vous avez passé le badge avec l\'id : {}'.format(uid)) #On affiche l'identifiant unique du badge RFID
        time.sleep(1) #On attend 1 seconde pour ne pas lire le tag des centaines de fois en quelques milli-secondes

#---------------------------------------------fin du programme -------------------------------------------------------------#
l’écran n’à pas de programme, pour le faire fonctionner il suffi de taper quelque ligne dans le terminal ( ligne présente si dessous )

Procédure :
-sudo raspi-config
-boot option -desktop /CLI -Desktop Autologin

  • git clone https://github.com/waveshare/LCD-show.git
  • cd LCD-show/
  • ./LCD32-show # cette commande va changer la résolution d’écran du Raspberry, il va ensuite redémarrer automatiquement pour effectuer la modification.
    merci pour la réponse précédente.

si j’ai bien compris tu utilises un écran 3.2 hdmi en SPI et un lecteur RFID aussi sur SPI.
le problème c’est que sur ce bus avec 2 esclaves ( l ecran et le rfid ) il faut gérer les communications et plus précisément arriver à distinguer auquel des esclaves on s’adresse ! en clair le programme pour le RFID ne précise pas à quel esclave il s’adresse .
Apparement il y a sur le raspberry plusieurs possiblité pour gérer ce problème:

  • sur le Rpi Master on leur donne un « SS » séparé; SS1, SSn
    dans le lien en source c’est le schéma du chapitre " Regular Independent Slave Configuration"

après pour trouver le device de chacun des esclaves c’est ds le repertoire /dev tu dois les trouver avec un :
ls /dev/*spi*

alors la suspense ! soit le simple fait de brancher sur des SS différents suffit mais j y crois pas, soit le plus probable, c’est qu’il faut passer par un import python d’un module type (https://pypi.org/project/spidev/ ) qui permet de désigner l’ esclave auquel on s’intéresse.( par son device /dev/?SPI?/ )
pas sur mais je suppose dans ton cas, tu dois pouvoir oublier l’écran (SS1) et modifier ton programme pour ne t’adresser qu’au RFID.(SS2)

Source :



PS: sinon il semble si j’en crois ce datasheet que le protocole I2C fonctionne avec le RC522 ( mais vu la jungle il y a peut être plusieurs modèles ! ) :

PPS : on doit aussi pouvoir utiliser le SPI0 pour l’ecran et le SPI1 pour le RFID si j’en crois ce post :

cette dernière solution semble être la plus simple a mettre en oeuvre ; en précisant le bus et peut être les pins (?) pour le spi1 lors de la création de l’objet RFID.

bonjour,
merci pour les différentes piste !
J’ai réussi ! à un détail près… Quand je démarre la Raspberry, le tactile fonctionne, au moment ou je lance le programme du rfid le code est lu mais le tactile ne fonctionne plus…

si tu postes le code que tu utilises quelqu’un pourra peut être t’aider …

voici le code du lecteur :
#!/usr/bin/env python

-- coding: utf8 --

Version modifiee de la librairie « ht(pp)://github.com/mxgxw/MFRC522-python »

import RPi.GPIO as GPIO
import MFRC522
import signal

continue_reading = True

Fonction qui arrete la lecture proprement

def end_read(signal,frame):
global continue_reading
print (« Lecture terminée »)
continue_reading = False
GPIO.cleanup()

signal.signal(signal.SIGINT, end_read)
MIFAREReader = MFRC522.MFRC522()

print (« Passer le tag RFID a lire »)

while continue_reading:

# Detecter les tags
(status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)

# Une carte est detectee
if status == MIFAREReader.MI_OK:
    print ("Carte detectee")

# Recuperation UID
(status,uid) = MIFAREReader.MFRC522_Anticoll()

if status == MIFAREReader.MI_OK:
    print ("UID de la carte : "+str(uid[0])+"."+str(uid[1])+"."+str(uid[2])+"."+str(uid[3]))

    # Clee d authentification par defaut
    key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
    
    # Selection du tag
    MIFAREReader.MFRC522_SelectTag(uid)

    # Authentification
    status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 8, key, uid)

    if status == MIFAREReader.MI_OK:
        MIFAREReader.MFRC522_Read(8)
        MIFAREReader.MFRC522_StopCrypto1()
    else:
        print ("Erreur d\'Authentification")

#----------------------------------------------------------------------------------------------------------------------------------#
voici sa bibliothèque :

#!/usr/bin/env python

-- coding: utf8 --

Version modifiee de la librairie https://github.com/mxgxw/MFRC522-python

from future import print_function
import RPi.GPIO as GPIO
import spi
import signal
import time

class MFRC522:
NRSTPD = 22
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, dev=’/dev/spidev1.0’, spd=1000000):
spi.openSPI(device=dev,speed=spd)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(22, GPIO.OUT)
GPIO.output(self.NRSTPD, 1)
self.MFRC522_Init()

def MFRC522_Reset(self):
self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE)

def Write_MFRC522(self, addr, val):
spi.transfer(((addr<<1)&0x7E,val))

def Read_MFRC522(self, addr):
val = spi.transfer((((addr<<1)&0x7E) | 0x80,0))
return val[1]

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
i = 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);  

while(i<len(sendData)):
  self.Write_MFRC522(self.FIFODataReg, sendData[i])
  i = i+1

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 = 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

      i = 0
      while i<n:
        backData.append(self.Read_MFRC522(self.FIFODataReg))
        i = i + 1;
  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:
    while i<4:
      serNumCheck = serNumCheck ^ backData[i]
      i = i + 1
    if serNumCheck != backData[i]:
      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);
i = 0
while i<len(pIndata):
self.Write_MFRC522(self.FIFODataReg, pIndata[i])
i = i + 1
self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC)
i = 0xFF
while True:
n = self.Read_MFRC522(self.DivIrqReg)
i = 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)
i = 0
while i<5:
buf.append(serNum[i])
i = i + 1
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):
  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
i = 0
while(i < len(Sectorkey)):
  buff.append(Sectorkey[i])
  i = i + 1
i = 0

# Next we append the first 4 bytes of the UID
while(i < 4):
  buff.append(serNum[i])
  i = i +1

# 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):
  print ("ERREUR AUTHENTIFICATION")
if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0:
  print ("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):
print (« Erreur durant la lecture »)
i = 0
if len(backData) == 16:
print (« Secteur « +str(blockAddr)+ » « +str(backData))
print(« Traduction en ASCII : « , end=’’)
c=0
while (c<16):
if(backData[c]!=0) :
try :
print (str(unichr(backData[c])),end= » »)
except :
print( » Contenu Illisible »)
c+=1
print("\n")

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

if status == self.MI_OK:
    i = 0
    buf = []
    while i < 16:
        buf.append(writeData[i])
        i = i + 1
    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):
        print ("Erreur durant l\'ecriture")
    if status == self.MI_OK:
        print ("Ecriture terminee")

def MFRC522_DumpClassic1K(self, key, uid):
i = 0
while i < 64:
status = self.MFRC522_Auth(self.PICC_AUTHENT1A, i, key, uid)
# Check if authenticated
if status == self.MI_OK:
self.MFRC522_Read(i)
else:
print (« Erreur d’Authentification »)
i = i+1

def MFRC522_Init(self):
GPIO.output(self.NRSTPD, 1)

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()

#----------------------------------------------------------------------------------------------------------------------------------#
l’écran n’a pas de programme il se sert de la bibliothèque : https://github.com/waveshare/LCD-show.git
j’utilise la commande : « ./LCD5-show » pour basculer vers mon écran
merci de votre aide :slight_smile:

J’ai enfin réussi… source : http://terminal28.blogspot.com/2016/05/enabling-spi1-on-raspberry-pi-bzero23.html
tout ce qu’il faut savoir se trouve sur le lien ci-dessus
merci pour tout.

Super ! on attend le tuto :wink: