-->
Page 1 of 1

I2C multiplexer and RFID reader don't work at the same time

PostPosted: Sun Feb 05, 2023 2:20 pm
by coolaturon
Hey there,

I am trying to use an RC522 RFID-Reader together with a TCA9548A i2C multiplexer to which I connected five SH1106 OLED displays. I am using a Wemos D1 (not the mini version). For the RFID I followed this tutorial : https://www.aranacorp.com/en/using-an-rfid-module-with-an-esp8266/

I connected the items in the following way:
Image

But I can only get the one or the other to work: When I comment out LINE A and BLOCK C the displays work. When I comment out BLOCK B the RFID reader works. When I comment out nothing, then neither works.
What am I doing wrong?

Another problem I have is that after switching the multiplexer, I always have to reinit the display (see LINE D). If I don't do that, the display wouldn't display anything. Maybe you also have any idea how to avoid this, because every reinit makes the display flicker once, which is ugly for my application.

Thanks in advance!

Main Code:
Code: Select all#include <Arduino.h>
#include <MFRC522.h>
#include <SPI.h>

#include <services/displayservice/DisplayService_h>

#include "SH1106Wire.h"

#define SS_PIN D4
#define RST_PIN D0

MFRC522 rfid(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;

// Init array that will store new NUID
byte nuidPICC[4];

DisplayService displayService;

/**
   Helper routine to dump a byte array as hex values to Serial.
*/
void printHex(byte *buffer, byte bufferSize) {
    for (byte i = 0; i < bufferSize; i++) {
        Serial.print(buffer[i] < 0x10 ? " 0" : " ");
        Serial.print(buffer[i], HEX);
    }
}

/**
   Helper routine to dump a byte array as dec values to Serial.
*/
void printDec(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], DEC);
  }
}

void setup() {
    Serial.begin(115200);
    SPI.begin();
    rfid.PCD_Init(); // Init MFRC522 // <--- LINE A
}

int num = 0;
// --- BLOCK B ---
void loop() {
    for (int i = 2; i <= 6; i++) {
        SH1106Wire* display = displayService.display(i);
        display->clear();
        display->flipScreenVertically();
        display->setFont(ArialMT_Plain_24);
        display->setTextAlignment(TEXT_ALIGN_CENTER);
        display->drawString(64, 20, String(num));
        display->display();
    }
    num++;
// --- END BLOCK B ---

// --- BLOCK C ---
    // Reset the loop if no new card present on the sensor/reader. This saves
    // the entire process when idle.
    if (!rfid.PICC_IsNewCardPresent()) return;

    // Verify if the NUID has been readed
    if (!rfid.PICC_ReadCardSerial()) return;

    Serial.print(F("PICC type: "));
    MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
    Serial.println(rfid.PICC_GetTypeName(piccType));

    // Check is the PICC of Classic MIFARE type
    if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
        piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
        piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
        Serial.println(F("Your tag is not of type MIFARE Classic."));
        return;
    }

    if (rfid.uid.uidByte[0] != nuidPICC[0] ||
        rfid.uid.uidByte[1] != nuidPICC[1] ||
        rfid.uid.uidByte[2] != nuidPICC[2] ||
        rfid.uid.uidByte[3] != nuidPICC[3]) {
        Serial.println(F("A new card has been detected."));

        // Store NUID into nuidPICC array
        for (byte i = 0; i < 4; i++) {
            nuidPICC[i] = rfid.uid.uidByte[i];
        }

        Serial.println(F("The NUID tag is:"));
        Serial.print(F("In hex: "));
        printHex(rfid.uid.uidByte, rfid.uid.size);
        Serial.println();
        Serial.print(F("In dec: "));
        printDec(rfid.uid.uidByte, rfid.uid.size);
        Serial.println();
    } else
        Serial.println(F("Card read previously."));

    // Halt PICC
    rfid.PICC_HaltA();

    // Stop encryption on PCD
    rfid.PCD_StopCrypto1();
  //--- END BLOCK C ---
}


DisplayService.cpp
Code: Select all#include <Wire.h>

#include "Arduino.h"
#include "DisplayService_h"
#include "SH1106Wire.h"

SH1106Wire displayInstance(0x3C, SDA, SCL);  // ADDRESS, SDA, SCL
uint8 activeDisplay = 0;

DisplayService::DisplayService() {}

SH1106Wire* DisplayService::display(uint8 displayNumber) {
    if (activeDisplay == displayNumber) {
        return &displayInstance;
    } else {
        this->changeDisplay(displayNumber);
        activeDisplay = displayNumber;
        displayInstance.init(); // <--- LINE D
        return &displayInstance;
    }
}

void DisplayService::changeDisplay(uint8 displayNumber) {
    Wire.beginTransmission(0x70);    // TCA9548A address
    Wire.write(1 << displayNumber);  // send byte to select bus
    Wire.endTransmission();
}


DisplayService_h
Code: Select all#ifndef DisplayService_h
#define DisplayService_h
#include "SH1106Wire.h"
class DisplayService {
   public:
    DisplayService();
    SH1106Wire* display(u_int8_t displayNumber);
   private:
    void changeDisplay(u_int8_t displayNumber);
};
#endif