TFT-Display and RFID block each other

Hello :slight_smile:

I am not completely sure whether this is the correct topic for this post, so please feel free to rearrange it.

My project uses an RFID sensor and a TFT display on an Arduino Uno. I managed to bring both sensors to work in single scripts, but they don't work integrated into the same script, using the <MFRC522.h> library for the RFID and the <MCUFRIEND_kbv.h> library for the TFT display. I am relatively sure that this is caused by an overwriting since they communicate via the same port.

To solve this issue I tried to adjust the code from this project (Arduino MKR RFID Reader with TFT Display - Arduino Project Hub) to mine. The RFID works fine, however, the display still does not react (maybe I failed to assign the correct pins to my shield?). I posted the code below. I would be enormously grateful for every help or advice! Usually I really enjoy Arduino but this is becoming a bit frustrating. Please rescue me :wink:

All the best,
Emma

/*
 *  Application note: Simple RFID Terminal for ArduiTouch and Arduino MKR  
 *  Version 1.0
 *  Copyright (C) 2019  Hartmut Wendt  www.zihatec.de
*/   

 

/*______Import Libraries_______*/
#include <Arduino.h>
#include <SPI.h>
#include <MFRC522.h>

#include "Adafruit_ILI9341.h"
#include "Adafruit_GFX.h"   
#include <MCUFRIEND_kbv.h> 
#include <Fonts/FreeSansBold12pt7b.h>    // when you want other fonts
#include <Fonts/FreeSansBold24pt7b.h> 
/*______End of Libraries_______*/


#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define LCD_RST A4 // Can alternately just connect to Arduino's reset pin

#define RELAY A5   // optional relay output 


#define TEXTCOLOUR 0xEF2A
#define BACKCOLOUR 0x4CCE
#define LINECOLOUR 0x2168

// RFID
#define RST_PIN   9    // Configurable, see typical pin layout above
#define SS_PIN    10    // Configurable, see typical pin layout above

/*___Keylock spezific definitions___*/
byte bananabread_uid[] = {0x04, 0x25, 0xAD, 0x8A, 0x61, 0x3E, 0x80}; saving the ID just as it comes up in the variable "content" produced an error message
#define relay_on_time 30 // will set the relay on for 3s 

String BB_ID = "04 25 AD 8A 61 3E 80";
/*___End of Keylock spezific definitions___*/


Adafruit_ILI9341 tft = Adafruit_ILI9341(LCD_CS, LCD_CD); 
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance




//--------Definitions---------------

String content= "";
//boolean result = false;
int RELAYTMR = 0; // Timer for relay control
int card_check = false;
int red_check = false;



//---------------------SETUP----------------------------------------------
//------------------------------------------------------------------------

void setup() {
  
  Serial.begin(9600); //Use serial monitor for debugging

  pinMode(LCD_RD, OUTPUT); // define as output for backlight control
  pinMode(RELAY, OUTPUT);   // define as output for optional relay
  digitalWrite(RELAY, LOW); // LOW to turn relay off   

  Serial.println("Init TFT ...");
  tft.begin();
  tft.setRotation(1);
  //digitalWrite(LCD_RD, HIGH);    // HIGH to turn backlight off - will hide the display during drawing
  //Serial.print("tftx ="); Serial.print(tft.width()); Serial.print(" tfty ="); Serial.println(tft.height());

  tft.fillScreen(BACKCOLOUR);
  tft.setTextColor(TEXTCOLOUR); 

  
  

  //-------------------RFID---------------------
  
  Serial.println("Init RFC522 module....");
  mfrc522.PCD_Init();  // Init MFRC522 module
  
  Serial.println("Ready to read a card");

  disp_standby();
}


void loop() {
  //--------Show Start display------------
  
  disp_standby();
  

  // only after successful transponder detection the reader will read the UID
  // PICC = proximity integrated circuit card = wireless chip card
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ) {
    store_rfid();
  }

// check current UID with blue_uid
  card_check = true;
  if (content != BB_ID) {
    card_check = false;
  }
  /*
   * 
   * The card check of the original code example:
   * 
   * for (int j=0; j<4; j++) {
    
      Serial.println(mfrc522.uid.uidByte[j]);
      if (mfrc522.uid.uidByte[j] != bananabread_uid[j]) {
        card_check = false;
    }
  }
   
   */

  //Check if ID matches recipe card: 
  if (card_check) 
  {
    disp_bb_start();
  } else {
     disp_standby();
  }
}






//-----------------FUNCTIONS------------------------------------------------


//write text function
void showmsgXY(int x, int y, int sz, int c, const GFXfont *f, const char *msg)
{  uint16_t x1, y1;  
   uint16_t wid, ht;  
   tft.setFont(f);  
   tft.setCursor(x, y);  
   tft.setTextColor(c);  
   tft.setTextSize(sz);  
   tft.print(msg);
}


//start display for banana bread
void disp_bb_start()
{  showmsgXY(30, 50, 1,TEXTCOLOUR, &FreeSansBold12pt7b,"Let's make"); 
   tft.println();
   showmsgXY(30, 100, 1,TEXTCOLOUR, &FreeSansBold24pt7b, "Banana");
   tft.println();
   showmsgXY(120, 150, 1,TEXTCOLOUR, &FreeSansBold24pt7b, "Bread!");
   tft.println();
   showmsgXY(30, 200, 1,TEXTCOLOUR, &FreeSansBold12pt7b,"Select a button:"); 
}


//standby display
void disp_standby()
{  // draw circle
    tft.fillCircle(160,120,100,0x2168); 
    tft.fillCircle(160,120,93,BACKCOLOUR); 
  // draw line
    for (uint16_t a=0; a<5; a++)
    {    tft.drawFastHLine(100, 120+a, 120, TEXTCOLOUR);}
  //draw text
    showmsgXY(95, 100, 1,TEXTCOLOUR, &FreeSansBold24pt7b,"Home"); 
    tft.println();
    showmsgXY(105, 180, 1,TEXTCOLOUR, &FreeSansBold24pt7b, "Mate");
}


void store_rfid()
{   Serial.print("ID:");
    String content= "";  
    for (byte i = 0; i < mfrc522.uid.size; i++) {
      // Abstand zwischen HEX-Zahlen und fhrende Null bei Byte < 16
      content = content + (mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
      content = content + String(mfrc522.uid.uidByte[i] , HEX);            
    } 
    content.toUpperCase();
    Serial.println(content);
}

You do not use MCUFRIEND_kbv anywhere. Remove the include. It serves no purpose.
Likewise these are unused:

#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0

The link shows a Red ILI9341 SPI display. Use the full-fat constructor i.e. with LCD_RST argument.

Adafruit_ILI9341 tft = Adafruit_ILI9341(LCD_CS, LCD_CD, LCD_RST);

David.

Hello David,

Thank you very much for your fast reply. You are right - I just forgot to remove the library. Sorry, stupid mistake. I removed it, as well as the LCD_WR line. I do use the LCD_RD as output in the setup in the following line. However, I have no idea what exactly it does, it might be completely unnecessary.

 pinMode(LCD_RD, OUTPUT); // define as output for backlight control

As you suggested I changed the constructor line to

Adafruit_ILI9341 tft = Adafruit_ILI9341(LCD_CS, LCD_CD, LCD_RST, LCD_RD);

Unfortunately, the display is still black. I'm afraid, I am not using the library correctly. If you have more ideas, please let me know. Thank you anyway! :slight_smile:

Emma

Adafruit_ILI9341 has several constructors:

  Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK,
                   int8_t _RST = -1, int8_t _MISO = -1);
  Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _RST = -1);
#if !defined(ESP8266)
  Adafruit_ILI9341(SPIClass *spiClass, int8_t dc, int8_t cs = -1,
                   int8_t rst = -1);
#endif // end !ESP8266
  Adafruit_ILI9341(tftBusWidth busWidth, int8_t d0, int8_t wr, int8_t dc,
                   int8_t cs = -1, int8_t rst = -1, int8_t rd = -1);

It does not have a constructor that supports the LED pin. I suggest that you hard-wire the LED pin to 5V via a 33R resistor.

Your 4-argument constructor will be matched by the SW SPI version:

  Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK,
                   int8_t _RST = -1, int8_t _MISO = -1);

You want the HW SPI version:

 Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _RST = -1);

C++ is "clever" when matching constructor and method prototypes. The original code matches the HW SPI constructor. Because the _RST argument is missing, it uses a default value (-1)

David.

Thank you David :slight_smile:
I am quite new to Arduino, so I don't understand everything from your reply. I know what a constructor is and that it usually defines the pins that I plan to use. So far so good. Am I right in guessing that several constructors exist for different application purposes of the library (depending on which pins one intends to use)?

This question might be a bit stupid, but can I assign the arguments to any pin on the Uno board, or do I have to take care that I assign e.g. the MISO pin to 12 or ICSP-1? Then this might already explain why my screen does not react (so far I just assigned the pins to A0 until A4).

Which constructor function would you recommend for my purpose?

Thank you very much for your help! I'm quite lost otherwise :-[

But I'm learning and I guess that's part of the game :stuck_out_tongue:

It is always wise to start with the Software constructor. It should work with any pins.
However I recommend that you choose the hardware SPI pins.

The tutorial is for an MKR board which has 3.3V logic.

Your Uno has 5V logic. You must use level shifters with the Red ILI9341 SPI display.

David.