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:
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:
#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
#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
#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