RFID-Leser: RC522 und Joy-IT 3.5" LCD - Display gleichzeitig betreiben

  • Hallo zusammen,


    bei meinem Raspberry Pi handelt es sich um die Version 3B


    ich versuche seit Monaten einen Stechuhr per Raspberry Pi zu bauen. Es soll ein RIFD: RC522-Leser und Joy-IT 3.5" LCD - Display gleichzeitig zu betrieben werden. (über ein Breadboard verkabelt)

    Ich habe den RC522-Chip erfolgreich installiert und er funktioniert tadellos.

    Sobald ich den Display installiere funktioniert zwar der Display aber der RFID-Leser nicht mehr. Ich habe viele Lösungen/Tutorials aus dem Internet vergebens ausprobiert. (Widerstände eingebaut, verschiedene Verkabelungen (Spi0.1 Spi1.0 Spi1.1) etc.) Dies ist mein erstes Raspberry-Projekt und bin leider am Ende meiner Ideen.

    Eine übliche Vorgehensweise/Konfiguration für 2 SPI geräte an einem Raspberry Pi hab ich leider nicht gefunden.


    Wäre schön wenn jemand einen Tipp für mich hätte. Mein aktueller Plan B ist einen kleinen HDMI-Display zu besorgen.


    Mit freundlichen Grüßen

    Hobbi

  • Hallo also ich kann dir aktuell nicht helfen aber damit man dir überhaupt helfen kann wäre z.b. ein Foto und welche Internetseiten du besucht hast doch hilfreich damit wir uns eine Vorstellungen machen können was du versuchst.


    Lars

  • Hallo Lars,


    für die Installation des RFID-Moduls bin ich folgedem Tutorial gefolgt: https://pimylifeup.com/raspberry-pi-rfid-rc522/

    für die Installation des Displays: habe ich die Offizielle Anleitung benutzt: https://joy-it.net/files/files…FT-Anleitung_04082020.pdf

    Ein Foto der Verkabelung kann ich erst gegen Abend hochladen.


    Meine Versuche zu dem Thema waren vonzufälligen Internetseiten die ich beim googeln gefunden habe. Quasi immer wenn ich was neues gelesen/entdeckt habe, wurde es ausprobiert. Ich hatte zb. versucht die Pin Belegung anzupassen, das der RFID-Leser auf andere Pins reagiert. allerdings war dadurch /dev/spidevX.X verschwunden

  • Hallo,

    Der LCD Display ist an den Pins 1-24 angeschlossen und der RFID-Reader an 34-40 und 1 (3.3 V).

    In der /boot/config.txt ist dtoverlay:1-3cs eingetragen und der Reader funktioniert.

    Der Reader reagiert auf spidev1.2

    Der Display funktioniert leider aktuell nicht.

    in /dev ist spidev1.0 spidev1.1 spidev1.2 zusehen. Der Display braucht spidev0.0

    verschiedene dtoverlayX.X kombinationen habe ich schon vergebens getestet.


    Wie bekomme ich spidev0.0 und die anderen gleichzeitig aktiviert?


    Vielen Dank

    Hobbi

  • /boot/overlay/README

    Kennt bei mir auch einen dtoverlay Eintrag für spi0-cs bzw. spi0-2cs. [und über raspi-config bzw. dtparam=spi=on wird auch spi0 aktiviert.]


    Wenn Du beide Geräte am spi1-2cs (oder 3cs) betreibst ist es eigentlich logisch, dass nur das Gerät, dessen Chip-Select aktiviert ist, funktioniert.


    Servus !

    RTFM = Read The Factory Manual, oder so

    Edited once, last by RTFM ().


  • Hallo,

    wie es aussieht blockiert der aktivierte SPI1.1 die Pins für den Display.

    Ich verwende spidev1.2 für den Reader. Wie kann ich Spi1.1 deaktvierten und spidev1.2 aktiv haben?

    Danke Hobbi

  • Ich sehe da in #7 kein spi1, sondern nur spi0

    Dabei scheitert die Initialisierung von GPIO Pin 17 am Gerät /devices/platform/soc/3f204000.spi/spi_master/spi 0/....,

    weil GPIO 17 bereits vom Gerät /devices/platform/soc/3f215080.spi verwendet wird.


    Das systemnahe Konfigurieren ist kein Trial & Error Karusell anhand veralteter Anleitungen.

    Jetzt tu einmal alles, was den RFID Reader betrifft, aus den Configs und Autostarts raus und bring zuerst das Display samt Touchscreen mit dem dtoverlay vom Hersteller zum Laufen (auf Bus 0, also spi0).


    Wenn das funktioniert initialisiere spi1 für den Reader und ändere das Python Scrip auf ein SPI Modul, das auch mehrere SPIs unterstützt (spi1).


    Servus !

    RTFM = Read The Factory Manual, oder so

  • Hallo, dies ist mein Python script. Ich habe die Zeile

    def __init__(self, bus=1, device=2, spd=1000000, pin_mode=10, pin_rst=-1, debugLevel='WARNING'):

    so angepasst das sie auf bus 1 und device 2 hört und passen die Kabel verbunden.


    In der boot/config.txt ist alles was den Reader betrifft auskommentiert. Der Display funktioniert.

    Sobald ich in der /boot/config.txt die Zeile: dtoverlay=spi1-3cs aktiviert. Funktioniert der Reader aber das Display nicht mehr


    #!/usr/bin/env python

    # -*- 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/>.

    #

    import RPi.GPIO as GPIO

    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=1, device=2, 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)


    gpioMode = GPIO.getmode()


    if gpioMode is None:

    GPIO.setmode(pin_mode)

    else:

    pin_mode = gpioMode


    if pin_rst == -1:

    if pin_mode == 11:

    pin_rst = 15

    else:

    pin_rst = 22


    GPIO.setup(pin_rst, GPIO.OUT)

    GPIO.output(pin_rst, 1)

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

    GPIO.cleanup()


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

  • Solange Du nicht 2 Busse

    /devices/platform/soc/xxxxxxxx.spi/spi_master/spi 0/

    /devices/platform/soc/xxxxxxxx.spi/spi_master/spi 1/

    initialisiert hast (das siehst Du auch unter <ls -al /dev/spi* > )

    ist jede weitere Zeile sinnlos. Zumindest für mich, zumal ich selbst nur Linux Anwender bin.

    Und mit den Pythonversionen 2 und 3 bist Du auch irgendwie auf Kriegsfuss. Genauso mit den Einrückungen im Python-Code.


    Servus !

    RTFM = Read The Factory Manual, oder so