Hi,
I am currently working on a project where I want to use an RFID reader and five SH1106 OLED displays together. These are the components I am using:
- Wemos D1 (not the mini one; clone)
- I2C Multiplexer TCA9548A
- 5xOLED SH1106
- RC522 RFID Reader
I managed to get the multiplexer to run with the displays just fine. Also I was able to run the RFID reader. But I can't manage to get both to run at the same time. When I comment out LINE A and BLOCK C in the following code, the displays work and when I comment out BLOCK B the RFID works. Here is my 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;
void loop() {
// --- BLOCK B ---
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 ---
}
with 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();
}
I guess it has something to do with how the SDA Ports are used. Do you have any idea on how I can get around this issue.
Thanks in advance!
P.S.: After switching I2C channels, I always have to reinit the display which makes it flicker (see LINE D). Is there a way I can avoid that, too?