Sketch doesn't run after reloading on Mega 2560

This sketch was completed with the assistance from this forum and has run succesfully for quite a while. I needed the mega for another sketch and when I have tried reloading the original Mega it fails to verify, generally around the SD Card setup with the 'SoftSpiDriver<12, 11, 13>softSpi;' line. I have tried to reload all the libraries associated with the sketch and tried earlier versions of the SdFat library to no avail.

Link to earlier queries when I was building the sketch - Sketch fails after running successfully first time - #36 by BJM1309

Any ideas or assistance greatfully received.

Regards,

Brian

#include <SPI.h>             // f.k. for Arduino-1.5.2

#define USE_SDFAT

#include <SdFat.h>           // Use the SdFat library

#include "SoftwareSerial.h"

#include "DFPlayerMini_Fast.h"  //Use 'Fast' version, other versions cause problems

//  #if SPI_DRIVER_SELECT != 2

//  #error edit SdFatConfig.h .  READ THE SKETCH INSTRUCTIONS

//  #endif

//  SD Card Setup

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)

//  RFID Setup

/*  Mega Connections for RFID

 *   RST - 43,  *   MOSO - 51, *   MISO - 50, *   SCK - 52, *   SDA - 53

 */

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

//  TFT Setup

#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

//  DF MiniPlayer setup

// Use pins 18 and 19 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

DFPlayerMini_Fast player;

//  Array through structuring 'Card'

struct Card {

  const char * imageName;

  const char * fileName;

  byte    size;     // Number of bytes in the UID. 4, 7 or 10.

  byte    uidByte[10];

  int soundIndex;

};

Card knownCards[] = {

  { "Talyllyn", "Talyllyn_400x267.bmp", 4, {0x49, 0x0E, 0x4F, 0xA2}, 0001},

  { "Dolgoch",  "Dolgoch_400x267.bmp", 4, {0x61, 0x2C, 0x28, 0x27}, 0002},

  { "Sir Haydn", "Sir_Haydn_400x267.bmp", 4, {0x60, 0xAB, 0x66, 0x1B}, 0003},

  { "Sir Henry", "Sir_Henry_400x267.bmp", 4, {0x91, 0x6B, 0x0E, 0x26}, 0004},

  {  "Unknown", " ", 0, {" "}, },  // this is a catch all cards 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()

{

    uint16_t ID;

    Serial.begin(115200);

    ID = tft.readID();

    if (ID == 0x0D3D3) ID = 0x9481;

    tft.begin(ID);

    tft.setRotation(1);

    tft.fillScreen(BLACK);

    tft.setTextSize(2);

    tft.setTextColor(GREEN);

    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 needed for mega, not uno

       

//  Set volume to maximum (0 to 30).

    player.volume(25);

{

  Serial.println("Put your RFID tag close to the reader...");

  Serial.println();

  }

    root = SD.open(namebuf);

    pathlen = strlen(namebuf);

  }

  

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;  //  See notes

  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);




      showBMP(knownCards[cardIndex].fileName, 40, 0);

      tft.setCursor(180, 285);

      tft.println(knownCards[cardIndex].imageName);

      player.play(knownCards[cardIndex].soundIndex);

   

      tft.fillScreen(BLACK);  //resets screen to black 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

    }

    bmpFile.close();

    return (ret);

   

}

Please post the full error message, using code tags when you do

Have you set SPI_DRIVER_SELECT = 2 in the SdFatConfig.h file of the SdFat library? If the library was updated since you last successfully compiled the sketch, any changes you made would have been lost.

The "verify" (check mark button in the IDE toolbar) does not need a board present to compile, and only uses the selected board in the IDE toolbar.

Hi David,

Many thanks, so simple, works fine now changed to 2.

Kind regards and thanks again,

Brian

Brian

Best to put a comment about this in the header of your sketch, to remind yourself to make the change next time. Modifications to library files aren't commonly necessary, so it's something that needs a 'nudge'.