Sketch fails after running successfully first time

Hi,
I am writing a sketch to show an image of a train and then play its sound. The sketch uses RFID to trigger the image and sound.
The sketch runs without the sound successfully and when ready will look for a 2nd RFID tag to pass and successfully display the image.
I have added a DFMini Player for the sound which plays for the first tag but the sketch 'freezes' and I cannot work out why !
I am using a Mega with 3.5" TFT screen and a DF Mini Player:
Screen is 3.5" TFT LCD Display Module For Arduino & Mega 2560 Board Touch Panel 480x320 UK | eBay and DF Mini MP3 DF Player Module Module Music Audio FAST SHI O8F8 J9K C8H4 .
I have run sketches with the same connections for the image and for the sounds, all works OK. When I run the combined sketch I have the lock up problem and as stated it runs for one pass of the RFID tag and then runs the sketch to show the second image, lights the relevant LED and the freezes before playing the sound.
I know the sketch is slightly cumbersome with the LEDs and Serial Monitor but I use these to help guide me through the running sequence and fault find.

Code:

#include <SPI.h>             // f.k. for Arduino-1.5.2
#define USE_SDFAT
#include <SdFat.h>           // Use the SdFat library
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

#if SPI_DRIVER_SELECT != 2
#error edit SdFatConfig.h .  READ THE SKETCH INSTRUCTIONS
#endif

/*  Mega Connections for RFID
 *   RST - 43
 *   MOSO - 51
 *   MISO - 50
 *   SCK - 52
 *   SDA - 53
 */
SoftSpiDriver<12, 11, 13> softSpi; //Bit-Bang on the Shield pins SDFat.h v2
SdFat SD;
#define SD_CS SdSpiConfig(10, DEDICATED_SPI, SD_SCK_MHZ(0), &softSpi)

#include <MFRC522.h>  //include library code for RFID

const int SS_PIN = 53;  //define RFID pins
const int RST_PIN = 43;
MFRC522 mfrc522(SS_PIN, RST_PIN);   //create MFRC522 instance.

//  DF MiniPlayer setup
// Use pins 30 and 31 to communicate with DFPlayer Mini

static const uint8_t PIN_MP3_TX = 18; // Connects to module's RX
static const uint8_t PIN_MP3_RX = 19; // Connects to module's TX
SoftwareSerial softwareSerial(PIN_MP3_RX, PIN_MP3_TX);

// Create the Player object
DFRobotDFPlayerMini player;

//LED Setup
  const int redLEDpin = A8;    //  red LED attached to analog pin 8
  const int greenLEDpin = A9;  //  green LED attached to analog pin 7
  const int blueLEDpin = A10;  //  blue LED attahced to analog pin 10
  const int yellowLEDpin = A11;//  green LED attached to analog pin 11

#include <Adafruit_GFX.h>    // Hardware-specific library
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

#define NAMEMATCH ""         // "" matches any name
#define PALETTEDEPTH   8     // support 256-colour Palette

char namebuf[32] = "/";   //BMP files in root directory

File root;
int pathlen;

#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

void setup()
{
    uint16_t ID;
    Serial.begin(9600);
    Serial.print("Show BMP files on TFT with ID:0x");
    ID = tft.readID();
    Serial.println(ID, HEX);
    if (ID == 0x0D3D3) ID = 0x9481;
    tft.begin(ID);
    tft.fillScreen(WHITE);
    tft.setTextColor(0xFFFF, 0x0000);
    bool good = SD.begin(SD_CS);
    if (!good) 
    Serial.print(F("cannot start SD"));
    while (!Serial)
    delay(100);
    SPI.begin();          //initiate SPI bus
    mfrc522.PCD_Init();   //initiate MFRC522
//  Mini Player
    softwareSerial.begin(9600);// Start communication with DFPlayer Mini
    if (player.begin(softwareSerial, true, false)) //  true, false neede for mega, not uno
    Serial.println("OK");
// Set volume to maximum (0 to 30).
    player.volume(30);
    
    pinMode(redLEDpin, OUTPUT); //sets redLEDpin as OUTPUT 
    pinMode(greenLEDpin, OUTPUT);//sets greenLEDpin as OUTPUT
    pinMode(yellowLEDpin, OUTPUT);//sets greenLEDpin as OUTPUT
    pinMode(blueLEDpin, OUTPUT);//sets greenLEDpin as OUTPUT

  {
  Serial.println("Put your RFID tag close to the reader...");
  Serial.println();
  }
    root = SD.open(namebuf);
    pathlen = strlen(namebuf);
  }
void loop()
  {
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }
  //Show UID on serial monitor
  Serial.print("UID tag :");

  String content = "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++)

    {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    content.concat(String(mfrc522.uid.uidByte[i], HEX));
  } 
  Serial.println();
  Serial.print("Message : ");
  content.toUpperCase();
  
  tft.setRotation(3);
  if (content.substring(1) == "49 0E 4F A2") //change here the UID of the card/cards that you want to give access
  {    
    Serial.println("Talyllyn.bmp");
    digitalWrite(redLEDpin, HIGH);
    showBMP("Talyllyn_400x267.bmp", 40, 0);
    tft.fillRoundRect(40, 267, 400, 50, 5, RED);
    tft.setCursor(180, 285);
    tft.setTextSize(2);
    tft.setTextColor(GREEN);
    tft.println("Talyllyn");
    player.play(8);
    delay(3000);
    digitalWrite(redLEDpin, LOW);
  }
  else if (content.substring(1)=="61 2C 28 27")
  {    
    Serial.println("Dolgoch.bmp");    
    digitalWrite(greenLEDpin, HIGH);
    showBMP("Dolgoch_400x267.bmp", 40, 0);
    tft.fillRoundRect(40, 267, 400, 50, 5, GREEN);
    tft.setCursor(180, 285);
    tft.setTextSize(2);
    tft.setTextColor(BLUE);
    tft.println("Dolgoch");
    player.play(9);
   delay(3000);
   digitalWrite(greenLEDpin, LOW);
   
   }
   else if (content.substring(1)=="60 AB 66 1B")
  {    
    Serial.println("Sir Haydn");    
    digitalWrite(blueLEDpin, HIGH);
    showBMP("Sir_Haydn_400x267.bmp", 40, 0);
    tft.fillRoundRect(40, 267, 400, 50, 5, BLUE);
    tft.setCursor(180, 285);
    tft.setTextSize(2);
    tft.setTextColor(YELLOW);
    tft.println("Sir Haydn");
    player.play(10);
    delay(3000);
    digitalWrite(blueLEDpin, LOW); 
    
  }
  else
  {    
    Serial.println("Sir Henry");    
    digitalWrite(yellowLEDpin, HIGH);
    showBMP("Sir_Henry_400x267.bmp", 40, 0);
    tft.fillRoundRect(40, 267, 400, 50, 5, YELLOW);
    tft.setCursor(180, 285);
    tft.setTextSize(2);
    tft.setTextColor(RED);
    tft.println("Sir Henry");
    player.play(11);
    delay(3000);
    digitalWrite(yellowLEDpin, LOW);  
    
  }
      for(int i=0; i<150; i+=10){
  }
    tft.fillScreen(WHITE);  //resets screen to white after BMP loaded
    Serial.println("Put your RFID tag close to the reader...");
    
}

#define BMPIMAGEOFFSET 54

#define BUFFPIXEL      20  //  must be a divisor of 240

uint16_t read16(File& f) {
    uint16_t result;         // read little-endian
    f.read(&result, sizeof(result));
    return result;
}

uint32_t read32(File& f) {
    uint32_t result;
    f.read(&result, sizeof(result));
    return result;
}

uint8_t showBMP(char *nm, int x, int y)
{
    File bmpFile;
    int bmpWidth, bmpHeight;    // W+H in pixels
    uint8_t bmpDepth;           // Bit depth (currently must be 24, 16, 8, 4, 1)
    uint32_t bmpImageoffset;    // Start of image data in file
    uint32_t rowSize;           // Not always = bmpWidth; may have padding
    uint8_t sdbuffer[3 * BUFFPIXEL];    // pixel in buffer (R+G+B per pixel)
    uint16_t lcdbuffer[(1 << PALETTEDEPTH) + BUFFPIXEL], *palette = NULL;
    uint8_t bitmask, bitshift;
    boolean flip = true;        // BMP is stored bottom-to-top
    int w, h, row, col, lcdbufsiz = (1 << PALETTEDEPTH) + BUFFPIXEL, buffidx;
    uint32_t pos;               // seek position
    boolean is565 = false;      //

    uint16_t bmpID;
    uint16_t n;                 // blocks read
    uint8_t ret;

    if ((x >= tft.width()) || (y >= tft.height()))
        return 1;               // off screen

    bmpFile = SD.open(nm);      // Parse BMP header
    bmpID = read16(bmpFile);    // BMP signature
    (void) read32(bmpFile);     // Read & ignore file size
    (void) read32(bmpFile);     // Read & ignore creator bytes
    bmpImageoffset = read32(bmpFile);       // Start of image data
    (void) read32(bmpFile);     // Read & ignore DIB header size
    bmpWidth = read32(bmpFile);
    bmpHeight = read32(bmpFile);
    n = read16(bmpFile);        // # planes -- must be '1'
    bmpDepth = read16(bmpFile); // bits per pixel
    pos = read32(bmpFile);      // format
    if (bmpID != 0x4D42) ret = 2; // bad ID
    else if (n != 1) ret = 3;   // too many planes
    else if (pos != 0 && pos != 3) ret = 4; // format: 0 = uncompressed, 3 = 565
    else if (bmpDepth < 16 && bmpDepth > PALETTEDEPTH) ret = 5; // palette 
    else {
        bool first = true;
        is565 = (pos == 3);               // ?already in 16-bit format
        // BMP rows are padded (if needed) to 4-byte boundary
        rowSize = (bmpWidth * bmpDepth / 8 + 3) & ~3;
        if (bmpHeight < 0) {              // If negative, image is in top-down order.
            bmpHeight = -bmpHeight;
            flip = false;
        }

        w = bmpWidth;
        h = bmpHeight;
        if ((x + w) >= tft.width())       // Crop area to be loaded
            w = tft.width() - x;
        if ((y + h) >= tft.height())      //
            h = tft.height() - y;

        if (bmpDepth <= PALETTEDEPTH) {   // these modes have separate palette
            //bmpFile.seek(BMPIMAGEOFFSET); //palette is always @ 54
            bmpFile.seek(bmpImageoffset - (4<<bmpDepth)); //54 for regular, diff for colorsimportant
            bitmask = 0xFF;
            if (bmpDepth < 8)
                bitmask >>= bmpDepth;
            bitshift = 8 - bmpDepth;
            n = 1 << bmpDepth;
            lcdbufsiz -= n;
            palette = lcdbuffer + lcdbufsiz;
            for (col = 0; col < n; col++) {
                pos = read32(bmpFile);    //map palette to 5-6-5
                palette[col] = ((pos & 0x0000F8) >> 3) | ((pos & 0x00FC00) >> 5) | ((pos & 0xF80000) >> 8);
            }
        }

        // Set TFT address window to clipped image bounds
        tft.setAddrWindow(x, y, x + w - 1, y + h - 1);
        for (row = 0; row < h; row++) { // For each scanline...
            // Seek to start of scan line.  It might seem labor-
            // intensive to be doing this on every line, but this
            // method covers a lot of gritty details like cropping
            // and scanline padding.  Also, the seek only takes
            // place if the file position actually needs to change
            // (avoids a lot of cluster math in SD library).
            uint8_t r, g, b, *sdptr;
            int lcdidx, lcdleft;
            if (flip)   // Bitmap is stored bottom-to-top order (normal BMP)
                pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
            else        // Bitmap is stored top-to-bottom
                pos = bmpImageoffset + row * rowSize;
            if (bmpFile.position() != pos) { // Need seek?
                bmpFile.seek(pos);
                buffidx = sizeof(sdbuffer); // Force buffer reload
            }

            for (col = 0; col < w; ) {  //pixels in row
                lcdleft = w - col;
                if (lcdleft > lcdbufsiz) lcdleft = lcdbufsiz;
                for (lcdidx = 0; lcdidx < lcdleft; lcdidx++) { // buffer at a time
                    uint16_t color;
                    // Time to read more pixel data?
                    if (buffidx >= sizeof(sdbuffer)) { // Indeed
                        bmpFile.read(sdbuffer, sizeof(sdbuffer));
                        buffidx = 0; // Set index to beginning
                        r = 0;
                    }
                    switch (bmpDepth) {          // Convert pixel from BMP to TFT format
                        case 24:
                            b = sdbuffer[buffidx++];
                            g = sdbuffer[buffidx++];
                            r = sdbuffer[buffidx++];
                            color = tft.color565(r, g, b);
                            break;
                        case 16:
                            b = sdbuffer[buffidx++];
                            r = sdbuffer[buffidx++];
                            if (is565)
                                color = (r << 8) | (b);
                            else
                                color = (r << 9) | ((b & 0xE0) << 1) | (b & 0x1F);
                            break;
                        case 1:
                        case 4:
                        case 8:
                            if (r == 0)
                                b = sdbuffer[buffidx++], r = 8;
                            color = palette[(b >> bitshift) & bitmask];
                            r -= bmpDepth;
                            b <<= bmpDepth;
                            break;
                    }
                    lcdbuffer[lcdidx] = color;

                }
                tft.pushColors(lcdbuffer, lcdidx, first);
                first = false;
                col += lcdidx;
            }           // end cols
        }               // end rows
        tft.setAddrWindow(0, 0, tft.width() - 1, tft.height() - 1); //restore full screen
        ret = 0;        // good render
    }
    Serial.println();
    bmpFile.close();
    return (ret);
}

Any suggestions gratefully received,
Brian

Which Arduino are you using?

Then why use SoftwareSerial when the Mega has 4 hardware UARTs ?

I missed that... indeed Hardware Serial would be much better

also the code is missing a mfrc522.PICC_HaltA();

Thanks for the comments. I don't know about the UARTS will have a look and try adding the mfrc comment.
Regards,
Brian

I have changed the DF Mini Player pins to 18/19 and have edited the code above. I originally found that as I have the TFT screen pluged directly into the MEGA there was little room for the pins to go to the DF player; I have now resolved this using 90 Deg pins.
Should I use Serial1.begin((600); ?
I have tried the mfrc comment at various places in the sketch to no avail, the initial problem still exists. Can you suggest where it should go.
I clearly need to do some more investigations into the UARTS which I am doing.
Thanks again,
Brian

Yes. apart from your finger problem when typing 9600

can you try this code (typed here - so mind typos)

#include <MFRC522.h>  //include library code for RFID
const int SS_PIN = 53;  //define RFID pins
const int RST_PIN = 43;
MFRC522 mfrc522(SS_PIN, RST_PIN);   //create MFRC522 instance.

struct Card {
  const char * imageName;
  const char * fileName;
  byte    size;     // Number of bytes in the UID. 4, 7 or 10.
  byte    uidByte[10];
};

Card knownCards[] = {
  { "Talyllyn", "Talyllyn_400x267.bmp", 4, {0x49, 0x0E, 0x4F, 0xA2}},
  { "Dolgoch",  "Dolgoch_400x267.bmp", 4, {0x61, 0x2C, 0x28, 0x27}},
  { "Sir Haydn", "Sir_Haydn_400x267.bmp", 4, {0x60, 0xAB, 0x66, 0x1B}},
  { "Sir Henry", "Sir_Henry_400x267.bmp", 0, {}}, // this is a catch all card when unknown card is presented
};
constexpr size_t knownCardsCount = (sizeof knownCards / sizeof * knownCards) - 1; // -1 because the very last one is a catch all card

void hexDump(byte *buffer, size_t bufferSize) {
  for (size_t i = 0; i < bufferSize; i++) {
    Serial.write(buffer[i] < 0x10 ? '0' : ' ');
    Serial.print(buffer[i], HEX);
    Serial.write(' ');
  }
}


void setup() {
  Serial.begin(115200); // Init Serial (open the Serial monitor at 115200 bauds)
  SPI.begin();          // Init SPI bus
  mfrc522.PCD_Init();   // Init MFRC522
  Serial.println(F("Ready, place RFID tag close to the reader."));
}

void loop() {
  if ( ! mfrc522.PICC_IsNewCardPresent()) return;
  if ( ! mfrc522.PICC_ReadCardSerial())   return;

  MFRC522::Uid currentCard = mfrc522.uid; // copy what we received

  mfrc522.PICC_HaltA();       // Halt PICC
  mfrc522.PCD_StopCrypto1();  // Stop encryption on PCD

  size_t cardIndex = 0;
  for (; cardIndex < knownCardsCount; cardIndex++)
    if (knownCards[cardIndex].size == currentCard.size)
      if (memcmp(knownCards[cardIndex].uidByte, currentCard.uidByte, currentCard.size) == 0) break; // found (see https://cplusplus.com/reference/cstring/memcmp/)

  //Show UID and image name on serial monitor (if not found, cardIndex is equal to knownCardsCount which is the last "catch all" card
  Serial.print(F("Tag: "));
  hexDump(currentCard.uidByte, currentCard.size);
  Serial.print(F("-> "));
  Serial.println(knownCards[cardIndex].imageName);
}

if it works you should be able to present cards and it will show you their ID and the image name.
describing the cards in a structure helps you collect in one place all the information needed and keeping the known cards in an array lets you use a for loop to do the checking rather than duplicating code.

if the display on screen would involve some colors or other stuff that is card specific, then you could code that as well in the struct.

Hi,
Many thanks. I was going to get around to cleaning up which would of resulted in arrays but got carried away with expanding the aim !
The sketch runs well. I will add the display and sound and see what happens. I will post back when finished.
Many thanks for your time and effort,
Regards,
Brian
ps - spelling impeccable ! Especially with the Welsh names from my narrow gauge railway !

that was copy/paste :slight_smile:

That's a good way to progress. start small with a working code and expand by adding new features

Hi,
Unfortunately, now I seem to be going round in circles and have hit a brick wall, my skills are not up to this !
I have tried to 'look up' the tag value to then serial print the image name, just as a start.
I am getting nowhere fast !
I have added an extra line to your code to attempt this but I keep getting errors for the line.
I think I follow the example that you quote at cpluscplus but cannot read the tag value to give me an output - ie show a particular image for a particular tag.
Will keep trying but any pointers gratefully received.
Regards,
Brian

Show your code

Hi,

I tried many variations and my notes are now a little confusing. I think I had a light bulb moment last night and will try again a bit later.

Thanks again,

Brian

Hi,
As stated above, I am just trying to read the tag ID and print a simple serial message. I had thought I understood what the programming meant but clearly I am miles away !
My code, I have just added a few lines in an attempt to work to what to 'lookup'.

#include <MFRC522.h>  //include library code for RFID
const int SS_PIN = 53;  //define RFID pins
const int RST_PIN = 43;
MFRC522 mfrc522(SS_PIN, RST_PIN);   //create MFRC522 instance.

struct Card {
  const char * imageName;
  const char * fileName;
  byte    size;     // Number of bytes in the UID. 4, 7 or 10.
  byte    uidByte[10];
};

Card knownCards[] = {
  { "Talyllyn", "Talyllyn_400x267.bmp", 4, {0x49, 0x0E, 0x4F, 0xA2}},
  { "Dolgoch",  "Dolgoch_400x267.bmp", 4, {0x61, 0x2C, 0x28, 0x27}},
  { "Sir Haydn", "Sir_Haydn_400x267.bmp", 4, {0x60, 0xAB, 0x66, 0x1B}},
  { "Sir Henry", "Sir_Henry_400x267.bmp", 4, {0x91, 0x6B, 0x0E, 0x26}}, // this is a catch all card when unknown card is presented
  { "Unknown", " ", 0, {" "}},
};
  constexpr size_t knownCardsCount = (sizeof knownCards / sizeof * knownCards) - 1; // -1 because the very last one is a catch all card

void hexDump(byte *buffer, size_t bufferSize) {
  for (size_t i = 0; i < bufferSize; i++) {
    Serial.write(buffer[i] < 0x10 ? '0' : ' ');
    Serial.print(buffer[i], HEX);
    Serial.write(' ');
  }
}


void setup() {
  Serial.begin(115200); // Init Serial (open the Serial monitor at 115200 bauds)
  SPI.begin();          // Init SPI bus
  mfrc522.PCD_Init();   // Init MFRC522
  Serial.println(F("Ready, place RFID tag close to the reader."));
}

void loop() {
  if ( ! mfrc522.PICC_IsNewCardPresent()) return;
  if ( ! mfrc522.PICC_ReadCardSerial())   return;

  MFRC522::Uid currentCard = mfrc522.uid; // copy what we received

  mfrc522.PICC_HaltA();       // Halt PICC
  mfrc522.PCD_StopCrypto1();  // Stop encryption on PCD

  size_t cardIndex = 0;
  for (; cardIndex < knownCardsCount; cardIndex++)
    if (knownCards[cardIndex].size == currentCard.size)
      if (memcmp(knownCards[cardIndex].uidByte, currentCard.uidByte, currentCard.size) == 0) break; // found (see https://cplusplus.com/reference/cstring/memcmp/)

  //Show UID and image name on serial monitor (if not found, cardIndex is equal to knownCardsCount which is the last "catch all" card
  Serial.print(F("Tag: "));
  hexDump(currentCard.uidByte, currentCard.size);
  Serial.print(F("-> "));
  Serial.println(knownCards[cardIndex].imageName);

  if (Card ([0][4]) == "0x49, 0x0E, 0x4F, 0xA2")
  {
       Serial.println("Hello");
    
    delay(3000); 
  }
    else if(Card ([1][4]) == "0x60, 0xAB, 0x66, 0x1B")
  {
    Serial.println("Goodbye");
    
    delay(3000); 
  }
}

Thanks again,
Brian

Does that code compile?

Go to the IDE preferences and crank up all warnings and verbosity.

This

if (Card ([0][4]) == "0x49, 0x0E, 0x4F, 0xA2")

makes no sense. To me. Yet. Card is a type, not a function or variable, so it is hard to see what you are going for there.

What do you want to test with that expression?

a7

I had earlier help as the first few posts reflect and my original sketch was very cleverly rewritten but unfortunately I do not fully understand the coding.
I am trying to read a tag and display an image on a TFT display. My current problem is that I do not understand the coding to trigger the event which my latest attempt was trying to achieve.
The code does not compile. I have tried various ways of achieving the aim but cannot get anything to work. Once I have the trigger I think I have the knowledge to get the image displayed, it did in my first sketch above but the sketch was very cumbersome.
Any points assistance very gratefully received.
Kind regards,
Brian

I had given you a nice sketch and now you do

:man_shrugging:
:cold_face:
:slight_smile:

in my sketch I had defined the known cards

and to check a card scan against those entries I was doing

  size_t cardIndex = 0;
  for (; cardIndex < knownCardsCount; cardIndex++)
    if (knownCards[cardIndex].size == currentCard.size)
      if (memcmp(knownCards[cardIndex].uidByte, currentCard.uidByte, currentCard.size) == 0) break; // found (see https://cplusplus.com/reference/cstring/memcmp/)

at the end of this for loop, cardIndex would either point at the card index that would have been recognised (for example index 1 for Dolgoch) or to the last entry of the array (Sir Henry) if the card was not a know card

so instead of doing this

which is not meaning anything useful and just guess work if you want to do something for the various cards and don't want to add that as a function pointer to a callback in the struct or extra information like what to print (I assume this is Chinese for you) then you can go the hard way

  if (cardIndex == 0)  { // Talyllyn
    Serial.println("Hello");
  }
  else if (cardIndex == 1)  { // Dolgoch
    Serial.println("Goodbye");
  }
  else if (cardIndex == 2)  { // Sir Haydn
    Serial.println("What time is it/");
  }
  else if (cardIndex == 3)  { // Sir Henry
    Serial.println("Gee, are you sure?");
  }
  else  { // Unknown card
    Serial.println("No cigar...");
  }
  delay(3000); // this is a bad idea, you want non blocking code to check the mfrc522 often

probably this is not needed at all,

A card is described by those attributes

my original code was showing you how to find the imageName to display,

instead of the name, you want to grab the file name of the bmp to show on screen ➜ use

knownCards[cardIndex].fileName

Hi,
Many thanks for your time. I am sorry I turned it something awful ! There was no intention to do so. I have been round and round trying to fully understand your coding and I spent a lot of time doing so.
Thanks for this input, hopefully I can more the sketch forward with offending anyone !
Will try again over the next few days.
Kind regards, will post if I have any misinterpretations.
Brian

I was pulling your leg. don't worry

When you don't understand the code, feel free to ask for explanations

[quote="BJM1309, post:15, topic:1231403"].
Hi,
This was the bit I didn't understand and I had overlooked the 'Struct' bit to for the array, hence my efforts to use the statement I had that caused so much consternation! This I need to follow fully which I currently do not.

size_t cardIndex = 0;
  for (; cardIndex < knownCardsCount; cardIndex++)
    if (knownCards[cardIndex].size == currentCard.size)
      if (memcmp(knownCards[cardIndex].uidByte, currentCard.uidByte, currentCard.size) == 0) break; // found (see https://cplusplus.com/reference/cstring/memcmp/)

I have added your last suggestion and all seems well, I will continue on to get to the point of displaying and activating the sound !
Thanks again,
Kind regards,
Brian