Electronic Catan Board Program Crashing. Please Help

Hi there,

I have made a electronic Catan board game and am using a Arduino Mega to run the board. After completing the board and getting the code all working, I have found after playing the board with some friends that after an hour or so the graphics begin glitching and after a while the program crashes.
My suspicion is that I may have a memory leak in my code and as I am using progmem to store the graphics it begins affecting my repeating graphic before it ultimately crashes.

I will upload my code, it is rather large but I believe the issue is in the loop code or its functions that it calls. I have had to remove alot of the startup functions to reduce the code to this forum's character limit. I also had remove all but one frame of the dice roll animation.

A brief description: The board can support up to 6 players, each player has a button, a LED and a display. There is code in the loop to keep track of the active player. When the active player presses their button a dice roll graphic is played by calling the 'void buildUp' which displays 43 frames loaded in memory with progmem to display the rolling dice graphic. Then a random dice roll is called and displayed. Player finishes their turn and moves to next player.
After around an hour of play the dice roll graphic starts glitching, small at first then progressively worse until the graphic unrecognizable. But the dice roll graphic continues to work fine after the diceroll function completes. the loop also seems to still work fine for a while after it starts glitching but after a short while the loop function starts glitching and showing the wrong player LED and not keeping track of the player well, then the program will crash all together.

Alot of the code is dependent if the board is smlGame or lrgGame, which depends on how many players there are. I have used the board for a few small games and never had the issue until once we played a large game.

Any help in pointing in the right direction on what could be the problem is appreciated.
I am positive that there are many areas where I can improve the code in here, as I am still learning as I go. Any feedback here would be appreciated also.

If you would like to get a visual on the whole setup a link to my github page for it is here

#include <ezButton.h>
#include "FastLED.h"
#include <EEPROM.h>
#define NUM_LEDS 107
#define DATA_PIN 2
#define tileSize 3
#define smlTileRange 19
#define lrgTileRange 30
#define smlPortRange 9
#define lrgPortRange 11
bool lrgGame = false;
bool settler1Roll = true;
bool settler1Turn = false;
bool s2tradeLock = false;
bool gameStart = false;
bool plrSelected = false;
CRGB leds[NUM_LEDS];
CRGB smlCurrentTileColors[smlTileRange];
CRGB lrgCurrentTileColors[lrgTileRange];
CRGB smlCurrentPortColors[smlPortRange];
CRGB lrgCurrentPortColors[lrgPortRange];
byte smlEEPROMTileColors[smlTileRange];
byte lrgEEPROMTileColors[lrgTileRange];
byte smlEEPROMPortColors[smlPortRange];
byte lrgEEPROMPortColors[lrgPortRange];
byte desertTile1;
byte desertTile2;
byte settler1;
byte settler2;
byte settler1Buttcount;
byte plrCount = 0;
byte players[6] = {0,0,0,0,0,0};
byte plrLEDs[6] = {0,1,2,3,4,5};
byte rollCount[11];
byte totalRolls;
byte convertRoll[11];
byte convertResource[5];
byte offsetArray[11];
//byte smlStartTile;
//byte lrgStartTile;
byte gameNumber;
byte resourceCount[5];
byte smlValuesStartTile = 1;
byte lrgValuesStartTile = 1;
long diceOne;
long diceTwo;
const byte BUTTON_NUM = 6;
const byte BUTTON_1_PIN = 4;
const byte BUTTON_2_PIN = 5;
const byte BUTTON_3_PIN = 6;
const byte BUTTON_4_PIN = 7;
const byte BUTTON_5_PIN = 8;
const byte BUTTON_6_PIN = 9;

ezButton buttonArray[] = {
  ezButton(BUTTON_1_PIN), 
  ezButton(BUTTON_2_PIN), 
  ezButton(BUTTON_3_PIN), 
  ezButton(BUTTON_4_PIN), 
  ezButton(BUTTON_5_PIN),
  ezButton(BUTTON_6_PIN)
};
//                Brick,     Wood,       Wheat,       Ore,      Sheep,      Desert
CRGB all[7] = {CRGB::Red,CRGB::Green,CRGB::Orange,CRGB::Cyan,CRGB::White,CRGB::Black,CRGB::Purple};
const uint32_t smlTileResource[]PROGMEM = {CRGB::Red,CRGB::Red,CRGB::Red,CRGB::Cyan,CRGB::Cyan,CRGB::Cyan,CRGB::Green,CRGB::Green,CRGB::Green,CRGB::Green,CRGB::Orange,CRGB::Orange,CRGB::Orange,CRGB::Orange,CRGB::White,CRGB::White,CRGB::White,CRGB::White,CRGB::Black};
const uint32_t lrgTileResource[]PROGMEM = {CRGB::Red,CRGB::Red,CRGB::Red,CRGB::Red,CRGB::Red,CRGB::Cyan,CRGB::Cyan,CRGB::Cyan,CRGB::Cyan,CRGB::Cyan,CRGB::Green,CRGB::Green,CRGB::Green,CRGB::Green,CRGB::Green,CRGB::Green,CRGB::Orange,CRGB::Orange,CRGB::Orange,CRGB::Orange,CRGB::Orange,CRGB::Orange,CRGB::White,CRGB::White,CRGB::White,CRGB::White,CRGB::White,CRGB::White,CRGB::Black,CRGB::Black};
const uint32_t smlPortResource[]PROGMEM = {CRGB::Red,CRGB::Cyan,CRGB::Green,CRGB::Orange,CRGB::White,CRGB::Purple,CRGB::Purple,CRGB::Purple,CRGB::Purple};
const uint32_t lrgPortResource[]PROGMEM = {CRGB::Red,CRGB::Cyan,CRGB::Green,CRGB::Orange,CRGB::White,CRGB::White,CRGB::Purple,CRGB::Purple,CRGB::Purple,CRGB::Purple,CRGB::Purple};

byte smlTileValuesArray[18] = {5,2,6,3,8,10,9,12,11,4,8,10,9,4,5,6,3,11};
//const byte smlValuesStartTileArray[] = {20,22,12,3,1,8};                           // Tile number (courner) to start the tile values sequence
//const byte smlValuesArray[] = {11,12,9,4,3,6,10,8,11,5,8,10,9,4,3,5,2,6,
//                                   9,10,8,12,6,5,3,11,3,4,6,4,11,9,2,8,10,5,
//                                   8,3,6,10,5,4,2,9,6,9,5,12,3,11,10,11,4,8,
//                                   6,2,5,3,4,9,10,8,5,11,8,10,6,3,4,9,12,11,
//                                   5,10,8,2,9,11,4,6,4,3,11,3,5,6,12,8,10,9,
//                                   8,4,11,10,11,3,12,5,9,6,9,2,4,5,10,6,3,8};
byte lrgTileValuesArray[28] = {2,5,4,6,3,9,8,11,11,10,6,3,8,4,8,10,11,12,10,5,4,9,5,9,12,3,2,6};
//const byte lrgValuesStartTileArray[] = {28,30,18,3,1,13};                              // Tile number (courner) to start the tile values sequence
//const byte lrgValuesArray[] = {6,10,11,3,5,9,11,8,9,4,8,4,12,6,5,9,8,3,2,10,3,10,11,12,6,2,5,4,
//                                   11,11,8,10,9,4,9,6,5,5,3,3,9,6,10,6,8,12,2,12,4,4,3,11,5,8,10,2,
//                                   9,3,6,8,5,10,4,11,4,6,12,5,11,9,2,11,2,10,5,3,10,6,9,12,8,3,8,4,
//                                   4,5,2,6,12,11,10,3,10,2,3,8,9,5,6,12,4,8,4,9,8,11,9,5,3,11,10,6,
//                                   2,10,8,5,11,3,4,4,12,2,12,8,6,10,6,9,3,3,5,5,6,9,4,9,10,8,11,11,
//                                   4,8,3,8,12,9,6,10,3,5,10,2,11,2,9,11,5,12,6,4,11,4,10,5,8,6,3,9};

byte smlCurrentTileLEDs[57];
const byte smlTileLEDsArray[]PROGMEM = {   //Defines Tile order depending on start tile of Tile Values
  8,9,16, 10,11,15, 12,13,14, 24,25,26, 38,39,41, 55,56,60, 71,72,77, 69,70,78, 67,68,79, 49,50,63, 30,31,45, 18,19,29, 20,21,28, 22,23,27, 36,37,42, 53,54,61, 51,52,62, 32,33,44, 34,35,43,
  12,13,14, 24,25,26, 38,39,41, 55,56,60, 71,72,77, 69,70,78, 67,68,79, 49,50,63, 30,31,45, 18,19,29, 8,9,16, 10,11,15, 22,23,27, 36,37,42, 53,54,61, 51,52,62, 32,33,44, 20,21,28, 34,35,43,
  38,39,41, 55,56,60, 71,72,77, 69,70,78, 67,68,79, 49,50,63, 30,31,45, 18,19,29, 8,9,16, 10,11,15, 12,13,14, 24,25,26, 36,37,42, 53,54,61, 51,52,62, 32,33,44, 20,21,28, 22,23,27, 34,35,43,
  71,72,77, 69,70,78, 67,68,79, 49,50,63, 30,31,45, 18,19,29, 8,9,16, 10,11,15, 12,13,14, 24,25,26, 38,39,41, 55,56,60, 53,54,61, 51,52,62, 32,33,44, 20,21,28, 22,23,27, 36,37,42, 34,35,43,
  67,68,79, 49,50,63, 30,31,45, 18,19,29, 8,9,16, 10,11,15, 12,13,14, 24,25,26, 38,39,41, 55,56,60, 71,72,77, 69,70,78, 51,52,62, 32,33,44, 20,21,28, 22,23,27, 36,37,42, 53,54,61, 34,35,43,
  30,31,45, 18,19,29, 8,9,16, 10,11,15, 12,13,14, 24,25,26, 38,39,41, 55,56,60, 71,72,77, 69,70,78, 67,68,79, 49,50,63, 32,33,44, 20,21,28, 22,23,27, 36,37,42, 53,54,61, 51,52,62, 34,35,43
  };

byte lrgCurrentTileLEDs[90];
const byte lrgTileLEDsArray[]PROGMEM = {    //Defines Tile order depending on start tile of Tile Values
  8,9,16, 10,11,15, 12,13,14, 24,25,26, 38,39,41, 57,58,59, 73,74,76, 88,89,91, 100,101,102, 98,99,103, 96,97,104, 82,83,94, 65,66,80, 47,48,64, 30,31,45, 18,19,29, 20,21,28, 22,23,27, 36,37,42, 55,56,60, 71,72,77, 86,87,92, 84,85,93, 67,68,79, 49,50,63, 32,33,44, 34,35,43, 53,54,61, 69,70,78, 51,52,62,
  12,13,14, 24,25,26, 38,39,41, 57,58,59, 73,74,76, 88,89,91, 100,101,102, 98,99,103, 96,97,104, 82,83,94, 65,66,80, 47,48,64, 30,31,45, 18,19,29, 8,9,16, 10,11,15, 22,23,27, 36,37,42, 55,56,60, 71,72,77, 86,87,92, 84,85,93, 67,68,79, 49,50,63, 32,33,44, 20,21,28, 34,35,43, 53,54,61, 69,70,78, 51,52,62,
  57,58,59, 73,74,76, 88,89,91, 100,101,102, 98,99,103, 96,97,104, 82,83,94, 65,66,80, 47,48,64, 30,31,45, 18,19,29, 8,9,16, 10,11,15, 12,13,14, 24,25,26, 38,39,41, 55,56,60, 71,72,77, 86,87,92, 84,85,93, 67,68,79, 49,50,63, 32,33,44, 20,21,28, 22,23,27, 36,37,42, 53,54,61, 69,70,78, 51,52,62, 34,35,43,
  100,101,102, 98,99,103, 96,97,104, 82,83,94, 65,66,80, 47,48,64, 30,31,45, 18,19,29, 8,9,16, 10,11,15, 12,13,14, 24,25,26, 38,39,41, 57,58,59, 73,74,76, 88,89,91, 86,87,92, 84,85,93, 67,68,79, 49,50,63, 32,33,44, 20,21,28, 22,23,27, 36,37,42, 55,56,60, 71,72,77, 69,70,78, 51,52,62, 34,35,43, 53,54,61,
  96,97,104, 82,83,94, 65,66,80, 47,48,64, 30,31,45, 18,19,29, 8,9,16, 10,11,15, 12,13,14, 24,25,26, 38,39,41, 57,58,59, 73,74,76, 88,89,91, 100,101,102, 98,99,103, 84,85,93, 67,68,79, 49,50,63, 32,33,44, 20,21,28, 22,23,27, 36,37,42, 55,56,60, 71,72,77, 86,87,92, 69,70,78, 51,52,62, 34,35,43, 53,54,61,
  47,48,64, 30,31,45, 18,19,29, 8,9,16, 10,11,15, 12,13,14, 24,25,26, 38,39,41, 57,58,59, 73,74,76, 88,89,91, 100,101,102, 98,99,103, 96,97,104, 82,83,94, 65,66,80, 49,50,63, 32,33,44, 20,21,28, 22,23,27, 36,37,42, 55,56,60, 71,72,77, 86,87,92, 84,85,93, 67,68,79, 51,52,62, 34,35,43, 53,54,61, 69,70,78
  };
const byte lrgPortLEDs[]PROGMEM = {6,7,17,40,46,75,81,90,95,105,106};
const byte smlPortLEDs[]PROGMEM = {6,7,17,40,46,57,65,88,85};

bool arrayIncludeElement(int randArray[], int input, int range) {       //checks if random number is already used in an array, i think?
  for (int i = 0; i < range; i++) {   
    if (randArray[i] == input) {
      return true;
    }
  }
  return false;
}

//------------------------------------------------------int Buzzer-----------------------------------------------------

#include "pitches.h"
const int buzzer = 3;

int songofstorms[] = {
  NOTE_D4,4, NOTE_A4,4, NOTE_A4,4,
  REST,8, NOTE_E4,8, NOTE_B4,2,
  NOTE_F4,4, NOTE_C5,4, NOTE_C5,4,
  REST,8, NOTE_E4,8, NOTE_B4,2,
  NOTE_D4,4, NOTE_A4,4, NOTE_A4,4,
  REST,8, NOTE_E4,8, NOTE_B4,2,
  NOTE_F4,4, NOTE_C5,4, NOTE_C5,4,
  REST,8, NOTE_E4,8, NOTE_B4,2,
  NOTE_D4,8, NOTE_F4,8, NOTE_D5,2,
  
  NOTE_D4,8, NOTE_F4,8, NOTE_D5,2,
  NOTE_E5,-4, NOTE_F5,8, NOTE_E5,8, NOTE_E5,8,
  NOTE_E5,8, NOTE_C5,8, NOTE_A4,2,
  NOTE_A4,4, NOTE_D4,4, NOTE_F4,8, NOTE_G4,8,
  NOTE_A4,-2,
  NOTE_A4,4, NOTE_D4,4, NOTE_F4,8, NOTE_G4,8,
  NOTE_E4,-2,
  NOTE_D4,8, NOTE_F4,8, NOTE_D5,2,
  NOTE_D4,8, NOTE_F4,8, NOTE_D5,2,

  NOTE_E5,-4, NOTE_F5,8, NOTE_E5,8, NOTE_E5,8,
  NOTE_E5,8, NOTE_C5,8, NOTE_A4,2,
  NOTE_A4,4, NOTE_D4,4, NOTE_F4,8, NOTE_G4,8,
  NOTE_A4,2, NOTE_A4,4,
  NOTE_D4,1,
};
int tempo = 120;
int notes = sizeof(songofstorms) / sizeof(songofstorms[0]) / 2;
int wholenote = (60000 * 4) / tempo;
int divider = 0, noteDuration = 0;

//------------------------------------------------------int Display-----------------------------------------------------

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(128, 64, &Wire, -1);

const unsigned char PROGMEM Dice0 [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char PROGMEM Dice1 [] = { };
const unsigned char PROGMEM Dice2 [] = { };
const unsigned char PROGMEM Dice3 [] = { };
const unsigned char PROGMEM Dice4 [] = { };
const unsigned char PROGMEM Dice5 [] = { };
const unsigned char PROGMEM Dice6 [] = { };
const unsigned char PROGMEM Dice7 [] = { };
const unsigned char PROGMEM Dice8 [] = { };
const unsigned char PROGMEM Dice9 [] = { };
const unsigned char PROGMEM Dice10 [] = { };
const unsigned char PROGMEM Dice11 [] = { };
const unsigned char PROGMEM Dice12 [] = { };
const unsigned char PROGMEM Dice13 [] = { };
const unsigned char PROGMEM Dice14 [] = { };
const unsigned char PROGMEM Dice15 [] = { };
const unsigned char PROGMEM Dice16 [] = { };
const unsigned char PROGMEM Dice17 [] = { };
const unsigned char PROGMEM Dice18 [] = { };
const unsigned char PROGMEM Dice19 [] = { };
const unsigned char PROGMEM Dice20 [] = { };
const unsigned char PROGMEM Dice21 [] = { };
const unsigned char PROGMEM Dice22 [] = { };
const unsigned char PROGMEM Dice23 [] = { };
const unsigned char PROGMEM Dice24 [] = { };
const unsigned char PROGMEM Dice25 [] = { };
const unsigned char PROGMEM Dice26 [] = { };
const unsigned char PROGMEM Dice27 [] = { };
const unsigned char PROGMEM Dice28 [] = { };
const unsigned char PROGMEM Dice29 [] = { };
const unsigned char PROGMEM Dice30 [] = { };
const unsigned char PROGMEM Dice31 [] = { };
const unsigned char PROGMEM Dice32 [] = { };
const unsigned char PROGMEM Dice33 [] = { };
const unsigned char PROGMEM Dice34 [] = { };
const unsigned char PROGMEM Dice35 [] = { };
const unsigned char PROGMEM Dice36 [] = { };
const unsigned char PROGMEM Dice37 [] = { };
const unsigned char PROGMEM Dice38 [] = { };
const unsigned char PROGMEM Dice39 [] = { };
const unsigned char PROGMEM Dice40 [] = { };
const unsigned char PROGMEM Dice41 [] = { };
const unsigned char PROGMEM Dice42 [] = { };
const unsigned char PROGMEM Dice43 [] = { };
const uint8_t *dice[44]  = {Dice0,Dice1,Dice2,Dice3,Dice4,Dice5,Dice6,Dice7,Dice8,Dice9,Dice10,Dice11,Dice12,Dice13,Dice14,Dice15,Dice16,Dice17,Dice18,Dice19,Dice20,Dice21,Dice22,Dice23,Dice24,Dice25,Dice26,Dice27,Dice28,Dice29,Dice30,Dice31,Dice32,Dice33,Dice34,Dice35,Dice36,Dice37,Dice38,Dice39,Dice40,Dice41,Dice42,Dice43};


const unsigned char PROGMEM robber [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x10, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x78, 0x00, 0x00, 0x00, 0x38, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3F, 0xC0, 0x00, 0x01, 0xF8, 0x00, 0x3F, 0xFF, 0x40, 0x1F, 0xB8, 0x00, 0x1F, 0xFF, 0xFF, 0xFE, 0x70, 0x00, 0xCF, 0xFF, 0xFD, 0x01, 0xF0, 0x00, 0xE7, 0xFF, 0xBF, 0xFF, 0xF0, 0x02, 0x73, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0x3E, 0xFF, 0xDF, 0xFD, 0xE0, 0x01, 0x8F, 0xFF, 0xE9, 0xED, 0xC0, 0x00, 0xE7, 0xFF, 0xF1, 0xF3, 0x80, 0x00, 0xF7, 0xFF, 0xFF, 0xFF, 0x80, 0x04, 0x7F, 0xFF, 0x16, 0x87, 0x00, 0x07, 0x1F, 0xFF, 0x00, 0x0E, 0x00, 0x03, 0x9F, 0xD4, 0x00, 0x1C, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x38, 0x00, 0x01, 0xFF, 0xA8, 0x00, 0xE0, 0x00, 0x00, 0xFF, 0x80, 0x03, 0x80, 0x00, 0x01, 0xFF, 0xE0, 0x1E, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x7C, 0x00, 0x00, 0x03, 0xFE, 0x03, 0xE0, 0x00, 0x00, 0x03, 0xF6, 0x1F, 0x80, 0x00, 0x00, 0x03, 0xF8, 0x7C, 0x00, 0x00, 0x00, 0x03, 0xE9, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xF3, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x03, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x03, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

//------------------------------------------------------beep-----------------------------------------------------
void beep(){
  tone(buzzer,NOTE_G4,35);
  delay(35);
  tone(buzzer,NOTE_G5,35);
  delay(35);
  tone(buzzer,NOTE_G6,35);
  delay(35);
  noTone(buzzer);
}

//------------------------------------------------------buildUp-----------------------------------------------------

void buildUp() {                                                        //rolling dice graphic
  for (int i=0; i<44; i++) {
    display.clearDisplay();
    display.drawBitmap(12, 17,dice[i],104,48, 1);
    display.display();
    delay(20);
    
  }
  delay(500);
}

//------------------------------------------------------rollDice-----------------------------------------------------

void rollDice() {
//Clear LEDs
  if (lrgGame == false) {
    for (int i = 0; i < smlTileRange; i++) {
      setTile(i+1, CRGB::Black, false);
    }
  }
  else {
    for (int i = 0; i < lrgTileRange; i++) {
      setTile(i+1, CRGB::Black, false);  
    }
  }

  randomSeed(analogRead(1));
  FastLED.show();
  delay(1000);
  buildUp();
  diceOne = random(1, 7);
  diceOne = random(1, 7);
  diceTwo = random(1, 7);
  diceTwo = random(1, 7);
  display.clearDisplay();
  display.setTextSize(2);      
  display.setTextColor(WHITE); // Draw text
  display.setCursor(0, 0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font
  display.print("ROLLED:"); 
  display.setCursor(85, 0);
  display.print(diceOne);
  display.setCursor(100, 0);
  display.print("&");
  display.setCursor(115, 0);
  display.println(diceTwo);
  int roll = diceOne + diceTwo;
  display.setTextSize(7);
  if (roll > 9) {
    display.setCursor(24, 16);
    display.print("1");
    display.setCursor(60, 16);
    display.print(roll-10);
    display.display();
  }
  else {
    display.setCursor(44, 16);
    display.println(roll);
    display.display();
  }
  delay(1000);

//If 7 is Rolled
  if (roll == 7) {
      display.setTextSize(2);
      display.clearDisplay();
      display.setCursor(4, 0);
      display.println("THE ROBBER");
      display.drawBitmap(0, 17, robber, 48, 48, 1);
      display.display();
      display.startscrollright(2,7);
  }
    
//Show only tiles with that roll
//SMALL GAME
  if (lrgGame == false) {
    if (roll == 7){  // Flash Board Red 3 times for robber                     //I might change for LED display
      for (int a = 0; a < 4; a++) {
        for (int i = 0; i < smlTileRange; i++) {
          setTile(i+1, CRGB::Red, false);
        }
        FastLED.show();
        delay(1000);
        if (a < 3) {
          for (int i = 0; i < smlTileRange; i++) {
            setTile(i+1, CRGB::Black, false);
          }
        }
        FastLED.show();
        delay(1000);
      }
    }
    else {          //Flash tiles equal to roll
      for (int a = 0; a < 4; a++) {
        int j = 0;                                        //Desert tile counter
        for (int i = 0; i < smlTileRange; i++) {
          if (smlCurrentTileColors[i] == all[5]) {        //If Desert tile found skip loop and add to desert tile counter
            i++;
            j++;
          }
          if (smlTileValuesArray[i-j] == roll) {                   //If values array [loop minus desert counter] is equal to roll, flash the loop tile (i)
            setTile(i+1, CRGB::White, false);
          }
        }
        FastLED.show();
        delay(1000);
        j = 0;
        if (a <3) {
          for (int i = 0; i < smlTileRange; i++) {
            if (smlCurrentTileColors[i] == all[5]) {
              i++;
              j++;
            }
            if (smlTileValuesArray[i-j] == roll){
              setTile(i+1, CRGB::Black, false);
            }
          }
        }
        FastLED.show();
        delay(1000);
      }
    }
    int j = 0;                                        //Desert tile counter
    for (int i = 0; i < smlTileRange; i++) {
      if (smlCurrentTileColors[i] == all[5]) {        //If Desert tile found skip loop and add to desert tile counter
        i++;
        j++;
      }
      if (smlTileValuesArray[i-j] == roll) {                   //If values array [loop minus desert counter] is equal to roll, add to resource counters
        if (smlCurrentTileColors[i] == all[0]){               //brick
          resourceCount[3]++;;
        }
        if (smlCurrentTileColors[i] == all[1]){               //wood
          resourceCount[2]++;
        }
        if (smlCurrentTileColors[i] == all[2]){               //wheat
          resourceCount[1]++;;
        }
        if (smlCurrentTileColors[i] == all[3]){               //ore
          resourceCount[4]++;;
        }
        if (smlCurrentTileColors[i] == all[4]){               //sheepies
          resourceCount[0]++;
        }
      }
    }
  }
    
  else {      //LARGE GAME
    if (roll == 7){  // Flash Board Red 3 times for robber                     //I might change for LED display
      for (int a = 0; a < 4; a++) {
        for (int i = 0; i < lrgTileRange; i++) {
          setTile(i+1, CRGB::Red, false);
        }
        FastLED.show();
        delay(1000);
        if (a < 3) {
          for (int i = 0; i < lrgTileRange; i++) {
            setTile(i+1, CRGB::Black, false);
          }
        }
        FastLED.show();
        delay(1000);
      }
    }
    else {          //Flash tiles equal to roll
      for (int a = 0; a < 4; a++) {
//        Serial.println("loop start");
        int j = 0;                                        //Desert tile counter
        for (int i = 0; i < lrgTileRange; i++) {
          if (lrgCurrentTileColors[i] == all[5]) {        //If Desert tile found skip loop and add to desert tile counter
            i++;
            j++;
          }
          if (lrgTileValuesArray[i-j] == roll) {                   //If values array [loop minus desert counter] is equal to roll, flash the loop tile (i)
            setTile(i+1, CRGB::White, false);
          }
        }
        FastLED.show();
        delay(1000);
        j = 0;
        if (a < 3) {
          for (int i = 0; i < lrgTileRange; i++) {
            if (lrgCurrentTileColors[i] == all[5]) {
              i++;
              j++;
            }
            if (lrgTileValuesArray[i-j] == roll){
              setTile(i+1, CRGB::Black, false);
            }
          }
        }
        FastLED.show();
        delay(1000);
      }
    }
    int j = 0;                                        //Desert tile counter
    for (int i = 0; i < lrgTileRange; i++) {
      if (lrgCurrentTileColors[i] == all[5]) {        //If Desert tile found skip loop and add to desert tile counter
        i++;
        j++;
      }
      if (lrgTileValuesArray[i-j] == roll) {                   //If values array [loop minus desert counter] is equal to roll, add to resource counters
        if (lrgCurrentTileColors[i] == all[0]){               //brick
          resourceCount[3]++;;
        }
        if (lrgCurrentTileColors[i] == all[1]){               //wood
          resourceCount[2]++;
        }
        if (lrgCurrentTileColors[i] == all[2]){               //wheat
          resourceCount[1]++;;
        }
        if (lrgCurrentTileColors[i] == all[3]){               //ore
          resourceCount[4]++;;
        }
        if (lrgCurrentTileColors[i] == all[4]){               //sheepies
          resourceCount[0]++;
        }
      }
    }
  }
  
  for (int i=0; i<=11; i++) {                         // Add roll to rollCount
    if (roll == i+2) {
      rollCount[i] ++;
//      Serial.print(rollCount[i]);
//      Serial.print(",");
    }
  }
//  Serial.println();
  totalRolls ++;
  
//  Serial.print("Sheep =");
//  Serial.println(resourceCount[0]);
//  Serial.print("Wheat =");
//  Serial.println(resourceCount[1]);
//  Serial.print("Wood =");
//  Serial.println(resourceCount[2]);
//  Serial.print("Brick =");
//  Serial.println(resourceCount[3]);
//  Serial.print("Ore =");
//  Serial.println(resourceCount[4]);
//  Serial.println("--------------");
}

//------------------------------------------------------tradeLock-----------------------------------------------------

void tradeLock() {
  display.clearDisplay();
  display.setTextSize(2);      
  display.setTextColor(WHITE);
  display.setCursor(6, 0);
  display.cp437(true);
  display.print("Settler 2");
  display.setTextSize(3);
  display.setCursor(20, 16);
  display.println("Trade");
  display.setCursor(20, 40);
  display.println("Locked");
  display.display();
}

//------------------------------------------------------ready2Roll-----------------------------------------------------

void ready2Roll() {
//  Serial.println("readyToRoll - Start");
  display.clearDisplay();      // Clear the buffer.
  display.setTextSize(2);      
  display.setTextColor(WHITE); // Draw text
  display.setCursor(6, 0);   // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font
  display.println("Settler 1");
  display.println("Ready to");                                              //will need centering
  display.setTextSize(4);
  display.setCursor(30, 32);
  display.println("ROLL");                                                  //will need centering
  display.display();
//  Serial.println("readyToRoll - End");
}

//------------------------------------------------------settlerPlus-----------------------------------------------------

int settlerPlus (int settler) {
  settler ++;
  for (settler; settler<7; settler++) {
    if (settler == 6) {
      settler = 0;
    }
//    if (players[settler] == 0) {
//    }
    if (players[settler] == 1) {
      break;
    }
  }
  return (settler);
}


//-----------------------------------------------------plrSelect------------------------------------------------------
void plrSelect() {
//  Serial.println("plrSelect - Start");
  int i;
  int r;
  while (1) {
    delay(100);
    r=random(0,7);  //find start position
    r=random(0,7);  //find start position
    if (players[r] == 1){
      i = r;
      break;
    }
  }
//  Serial.print("start poss = ");
//  Serial.println(r);
  int tt = 30; //green LED on timer
  display.clearDisplay(); // Clear the buffer.
  display.setTextSize(2);      
  display.setTextColor(WHITE); // Draw text
  display.setCursor(0,0);     // Start at top-left corner                  //will need centering?
  display.cp437(true);         // Use full 256 char 'Code Page 437' font
  display.setTextWrap(false);
  display.println(">>>>>>>>>>>>>>>>");
  display.println(" Spinning");
  display.setCursor(6,32);
  display.println("for First");
  display.println("  Player");
  display.display();
  display.startscrollright(0,1);
  delay(1000);
  plrSelected = true;

    //  Loop for number of initial rotations
  for (int l=0; l < 20; l++) {
    for (i; i<6; i++) {
      if (players[i] == 1) {
        leds[plrLEDs[i]] = CRGB::Green;
        tone(buzzer,NOTE_G6,35);
  //      Serial.print(i);
        FastLED.show();
        delay(tt);
        leds[plrLEDs[i]] = CRGB::Black;
        FastLED.show();
        delay(tt);
      }
    }
    i=0;
  }
  i = r;
  int a = 0;
  for (i; i<7; i++)  {                //  Loop with slow down multiplyer
    if (i == 6) {
      i=0;
    }
    if (players[i] == 1) {
      leds[plrLEDs[i]] = CRGB::Green;
      tone(buzzer,NOTE_G6,35);
      FastLED.show();
      delay(tt);
      leds[plrLEDs[i]] = CRGB::Black;
      FastLED.show();
      delay(30);
      tt *= 1.15;       //slow down time multiplier
      if (tt > 1500) {
//        a = i;
        break;
      }
    }
  }
  for (a; a < 3; a++) {
    delay(200);
    leds[plrLEDs[i]] = CRGB::Green;
    tone(buzzer,NOTE_D8,250);
    FastLED.show();
    delay(500);
    if (a < 2){
      leds[plrLEDs[i]] = CRGB::Black;
      FastLED.show();
      delay(250);   
    }
  }
//  Serial.print("s1 = ");
//  Serial.println(i);
  settler1 = i;
  int s2 = 0;
  for (int i = settler1; i < 6; i++) {                                  //Define Settler2 Player
    s2 += players[i];
    if (s2 == 4) {
      settler2 = i;
      break;
    }
    if (i == 5) {
      i = -1;
    }
  }
  display.stopscroll();
  if (lrgGame == true) {
    s2tradeLock = true;
  }
  delay(1000);
  ready2Roll();
//  Serial.println("plrSelect - End");
}

//------------------------------------------------------loop-----------------------------------------------------
void loop() {  
//  SETTLER 1
  buttonArray[settler1].loop();
  if (buttonArray[settler1].isPressed()) {
    beep();
    int t=0;
    unsigned long previousMillis = 0;
    while (t <= 10) {                                     // Check for 10 second hold for end game
      unsigned long currentMillis = millis();
      const int interval = 1000;
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        (t++);
      }
      if (t == 10) {
        endGameStats();
      }
      buttonArray[settler1].loop();
      if (buttonArray[settler1].isReleased()) {         //If Settler 1 releases button, Roll Dice
        break;
      }
    }
    if (settler1Roll == true) {                         //Roll dice if Settler 1 Roll = true
      rollDice();
      settler1Roll = false;
      settler1Turn = true;
    }
    else if (settler1Turn == true) {                    //or if Settler 1 has already rolled
      leds[settler1] = CRGB::Black;
      settler1 = settlerPlus(settler1);
      if (s2tradeLock == true) {                          //pass to settler 2 if tradelock on
        leds[settler1] = CRGB::Orange;
        leds[settler2] = CRGB::Green;
        settler1Turn = false;
        tradeLock();
      }
      else {                                          //or pass to next player if trade lock is off
        settler1Roll = true;
        settler1Turn = false;
        display.stopscroll();
        display.clearDisplay();
        FastLED.clear();
        FastLED.show();
        if (lrgGame == true) {
          s2tradeLock = true;
          leds[settler2] = CRGB::Orange;
        }
        ready2Roll();
        leds[settler1] = CRGB::Green;
      }
    }
    FastLED.show();
  }

  
//  SETTLER 2
  if (lrgGame == true) {
    buttonArray[settler2].loop();
    if (buttonArray[settler2].isPressed()) {                //settler 2 press button
      beep();
      leds[settler2] = CRGB::Black;
      settler2 = settlerPlus(settler2);
      if (settler1Roll == true or settler1Turn == true) {   //if settler 1 roll/turn just release tradelock
        s2tradeLock = false;
      }
      else {                                                //else pass turn to next player
        settler1Roll = true;
        ready2Roll();
        display.stopscroll();
        FastLED.clear();
        leds[settler1] = CRGB::Green;
        leds[settler2] = CRGB::Orange;
      }
      FastLED.show();
    }
  }
}

Hi, @bilbobigguns
Welcome to the forum.

Have you checked your power supply?
How are you powering the display?

Please post a copy of your schematic?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

String object creation and array boundary violations are the most common causes of crashes, and fortunately, you do not appear to be using Strings.

Please explain what you are doing with all the empty arrays assigned to PROGMEM. Are you trying to write to them?

You can save additional memory by use of the F macro, changing all .print() and .println() lines as follows:

display.println("ROLL");
to
display.println(F("ROLL"));

Memory leaks otherwise seem unlikely, but you can continuously monitor free memory usage with the following code. If it is less than 100 bytes or so, you are probably in trouble.

This can be included in your code, and takes up just a few bytes of memory:

//Arduino free memory .cpp
extern unsigned int __heap_start;
extern void *__brkval;

/*
   The free list structure as maintained by the
   avr-libc memory allocation routines.
*/
struct __freelist {
  size_t sz;
  struct __freelist *nx;
};

/* The head of the free list structure */
extern struct __freelist *__flp;
/* Calculates the size of the free list */
int freeListSize() {
  struct __freelist* current;
  int total = 0;
  for (current = __flp; current; current = current->nx) {
    total += 2; /* Add two bytes for the memory block's header  */
    total += (int) current->sz;
  }
  return total;
}

int freeMemory() {
  int free_memory;
  if ((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__heap_start);
  } else {
    free_memory = ((int)&free_memory) - ((int)__brkval);
    free_memory += freeListSize();
  }
  return free_memory;
}

Thanks Tom,

I haden't even considered the power supply. I never had any power issues before, I only get some slight dimming on the LEDS when they are all powered up.
I am using a 12v 2a to power everything. The oled displays (6) are being powered from the Megas 3.3v out and I have wired in a 12v to 5v converter off the same psu for the LEDs. I dont have a full schematic drawn up but have drawn a basic one here.

Hi, @bilbobigguns

quote="bilbobigguns, post:5, topic:1278855"]
I dont have a full schematic drawn up
[/quote]

It would be a good idea.

Do you have a DMM? (Digital MultiMeter)
To monitor the 5V supplies when this problem occurs.

How much current does the 106 LED draw.

Tom... :smiley: :+1: :+1: :coffee: :australia:

Thanks jreminton for your response.

The empty arrays are the diceroll frames I had to remove from the code in order to post on this forum, as I was exceeding the character limit. I left the first one in there to show an example of the rest.
Ill will try out this memory monitoring code and report back.

Yes, I do have a multimeter, Ill give this a try the next time I test. But it is difficult as I have to manually run the gate for an hour before the issue will occur.
If all the LEDs are on white (they are RGB) they will draw 30mA each for a total of 3a. But I only have this happening in one function when starting up the code, not during the gameplay. The most I have during the gameplay is occasions when they all flash red which is les than a third of that so no more than 1amp.