Dual RC522 on Orange PI

匿名 (未验证) 提交于 2019-12-03 01:05:01

问题:

My goal is to use dual RFID RC522 readers with Orange PI. So far, I have managed to make only one working. (reading google, armbian and orange pi forums). Here is what I have done so far:

Hardware connection:

single RC 522

Second reader uses shared pins, except SDA, it goes to pin 26 on orange PI

software:

Install python dev

 apt-get install python-dev 

Install orangepi_PC_gpio_pyH3 Library

  git clone https://github.com/duxingkei33/orangepi_PC_gpio_pyH3.git    cd orangepi_PC_gpio_pyH3    python setup.py install 

Install SPI-Py Library

git clone https://github.com/lthiery/SPI-Py.git  cd SPI-Py   python setup.py install 

Install MFRC522-python

 git clone https://github.com/rasplay/MFRC522-python.git 

The tricky part is, MFRC522-python is made to work with RASPBERRY PI on orange pi, one guy offered a solution by modifying MFRC522.py

    #import RPi.GPIO as GPIO import pyA20.gpio as GPIO import spi import signal  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,spd=1000000):     spi.openSPI(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):       print "Size: " + str(backData[0])       return  backData[0]     else:       return 0    def MFRC522_Auth(self, authMode, BlockAddr, Sectorkey, serNum):     buff = []     buff.append(authMode)     buff.append(BlockAddr)     i = 0     while(i < len(Sectorkey)):       buff.append(Sectorkey[i])       i = i + 1     i = 0     while(i < len(serNum)):       buff.append(serNum[i])       i = i +1     (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_AUTHENT,buff)     if not(status == self.MI_OK):       print "AUTH ERROR!!"     if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0:       print "AUTH ERROR(status2reg & 0x08) != 0"      return status    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 "Error while reading!"      print "Got data size: "+str(backLen)     i = 0     if len(backData) == 16:       print "Sector "+str(blockAddr)+" "+str(backData)    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      print str(backLen)+" backdata &0x0F == 0x0A "+str(backData[0]&0x0F)     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 "Error while writing"         if status == self.MI_OK:           print "Data writen"     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()    def GPIO_CLEEN(self):     GPIO.cleanup()  

4 lines are commented (109 - 111, 357) and first line is replaced to use pyA20.gpio instead of RPi.GPIO.

After that, I run read.py and it works like a charm.

import MFRC522 import signal  continue_reading = True MIFAREReader = MFRC522.MFRC522()  cardA = [5,74,28,185,234] cardB = [83,164,247,164,164] cardC = [20,38,121,207,132]  def end_read(signal, frame):   global continue_reading   continue_reading = False   print "Ctrl+C captured, ending read."   MIFAREReader.GPIO_CLEEN()  signal.signal(signal.SIGINT, end_read)  while continue_reading:   (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)   if status == MIFAREReader.MI_OK:     print "Card detected"   (status,backData) = MIFAREReader.MFRC522_Anticoll()   if status == MIFAREReader.MI_OK:     print "Card read UID: "+str(backData[0])+","+str(backData[1])+","+str(backData[2])+","+str(backData[3])+","+str(backData[4])     if  backData == cardA:       print "is Card A"     elif backData == cardB:       print "is Card B"     elif backData == cardC:       print "is Card C"     else:       print "wrong Card" 

That is the way to use the reader on ORANGE PI PC. I googled and read further, in order to use second reader I need to modify exact same lines that I commented in order it to work. It controls RC522 with that SDA PIN, chooses from which reader to read the data. I try to uncomment any of them, but errors appear. Looks like those use specific RPi.GPIO functions. My python knowledge is very basic. I try to find where exactly are described pins that are used, and failed. Tried just to replace that pin 24 with 26 in order to read data from second readed. So far no success.

回答1:

I have very similar setup and have had similar problems.

It seems I managed to solve them, just last night! :)

My project involves:

  • Orange pi zero
  • 12-13 RFID-RC522 modules (for now only 2)
  • SPI communication
  • since I will need lots of digital output pins I will use 12-13 shift register ICs (74HC595)

Approaches and problems:

  1. connect together SCK, MISO and MOSI pins, pull RST high, control each SS line separately by modifying MFRC522 class. Didn't work, maybe my timings were off, should connect logic analyzer and see.

  2. connect together SCK, MISO, MOSI AND SS pins, pull RST high, switch on/off Vcc or GND pins (power down all readers but one, read from that one, switch to next). Didn't work and presented very interesting situation. In some cases RFID module can read cards even with Vcc, or GND, or both pins DISCONNECTED!!! There is some significant leakage current from the signal pins. Here I tried demuxes, shift registers, line driver ICs, nothing worked.

  3. Finally, approach that DOES work. Connect together SCK, MISO, MOSI AND SS pins, control RST pin. RST when pulled low powers down module. Pull it up to power-on. So, initially all RST pins are pulled low, then one-by-one are pulled high, small delay to allow module to boot up (I use 200ms), call MFRC522_Init() (not sure if necessary in each cycle, doesn't hurt I guess), perform read, pull RST low, switch to next module. Nice side effect of this approach is low power consumption: 2 powered-down modules draw 3.6mA, 1 on - 1 off draw 18mA.

Hope this helps! :)



回答2:

It was been a while, i had learn a little, made two RC522 readers to work on ESP8266, but same scenario can be used on ORANCE PI, in my previous attempt I was trying to make them work in separate SPI interface, now I use one interface and control them with SS (SDA) signal, when is send LOW on it, reader is active for communication. That way can be used more than one and control them that way. Hope that help to someone who seek an answers here :)



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!