Arduino Running out of memory after being on for so long

So I’m running an Arduino UNO that’s connected to a keypad controlling 8 magnetic locks. Each lock responds to a different code.

After a day or so, the mag locks will quit opening when the correct sequence is put into the keypad. Even quickly resetting the Arduino doesn’t fix the problem. However, when the arduino is powered off for a longer duration (10 seconds or so), everything will go back to working fine (for a while).

Using the power of google, I think I figured out that there may be a problem in my code that is making my Arduino pile up on memory and eventually run out of room to process new commands.

If that is the case, is there anything I can change to make it run more efficiently? I thought about just trying to make it reset stored data after every so long, but I think that’d be a last resort if I couldn’t find a way to make the code a little cleaner.

Thanks!

const byte relay1 = 4;
const byte relay2 = 5;
const byte relay3 = 6;
const byte relay4 = 7;
const byte relay5 = 8;
const byte relay6 = 9;
const byte relay7 = 10;
const byte relay8 = 11;

//#include <Wiegand.h>//library not actually used
//WIEGAND wg;

// Connect D0 to Pin 2 and D1 to Pin 3 on an Arduino UNO
const byte PinD0 = 2;
const byte PinD1 = 3;

const byte IntD0 = 0;
const byte IntD1 = 1;

volatile unsigned BitCount;
volatile byte Bits[26];
volatile unsigned long LastBitTime;

const byte storedPattern[9][26] =
{
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,1,1,1,0,1,1},//1469
  {1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,1,0,1,1,0},//6219
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,0,0,0},//2020
  {1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,1,0},//5123
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,1,0,0,1,0},//0617
  {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,1,0,1,1,1,1,0,0},//8670
  {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,1,0},//3313
  {1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,0,0,1,1,0,1,1},//7117
  {1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,1,1,1},//9731
};

byte matchPattern = 99;

void setup() {
  Serial.begin(9600);
  // wg.begin();
  pinMode(PinD0, INPUT_PULLUP);// Set D0 pin as input
  pinMode(PinD1, INPUT_PULLUP);// Set D1 pin as input
  attachInterrupt(IntD0, ReadD0, FALLING); // Hardware interrupt - high to low pulse
  attachInterrupt(IntD1, ReadD1, FALLING); // Hardware interrupt - high to low pulse
  //pinMode(2, INPUT_PULLUP);//duplicate
  //pinMode(3, INPUT_PULLUP);//duplicate
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  pinMode(relay5, OUTPUT);
  pinMode(relay6, OUTPUT);
  pinMode(relay7, OUTPUT);
  pinMode(relay8, OUTPUT);

  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
  digitalWrite(relay3, LOW);
  digitalWrite(relay4, LOW);
  digitalWrite(relay5, LOW);
  digitalWrite(relay6, LOW);
  digitalWrite(relay7, LOW);
  digitalWrite(relay8, LOW);
}

//interrupt service routines
void ReadD0() {
  if (BitCount < 100) {
    LastBitTime = millis();
    Bits[BitCount++] = 0;
  }
}

void ReadD1() {
  if (BitCount < 100) {
    LastBitTime = millis();
    Bits[BitCount++] = 1;
  }
}

void loop() {

  byte localBits[26];
  // Grab volatile variables with interrupts disabled
  noInterrupts();
  unsigned long interval = millis() - LastBitTime;
  unsigned count = BitCount;
  interrupts();

  // Process data when we have new bits, but not for a while.
  if (interval > 100 && count != 0)
  {
    noInterrupts();
    for (unsigned i = 0; i < count; i++) {
      localBits[i] = Bits[i];
    }
    BitCount = 0;
    interrupts();

    Serial.print(count);
    Serial.print(" bits: ");
    for (unsigned i = 0; i < count; i++) {
      Serial.print(localBits[i]);
      if (i % 8 == 7)
        Serial.write(' ');
    }
    Serial.println();

    //test for match with memcmp
    matchPattern = 99;//reset to no match
    for (byte i = 0; i <= 9; i++)
    {
      if ((memcmp(localBits, storedPattern[i], 26)) == 0)
      {
        matchPattern = i;
      }
    }

    Serial.print("Entered number matches ");
    switch (matchPattern)
    {
      case 0:
        Serial.println("1469");
        digitalWrite(relay1, HIGH);
        break;

      case 1:
        Serial.println("6219");
        digitalWrite(relay2, HIGH);
        break;

      case 2:
        Serial.println("2020");
        digitalWrite(relay3, HIGH);
        break;

      case 3:
        Serial.println("5123");
        digitalWrite(relay4, HIGH);
        break;

      case 4:
        Serial.println("0617");
        digitalWrite(relay5, HIGH);
        break;

      case 5:
        Serial.println("8670");
        digitalWrite(relay6, HIGH);
        break;

      case 6:
        Serial.println("3313");
        digitalWrite(relay7, HIGH);
        break;

      case 7:
        Serial.println("7117");
        digitalWrite(relay8, HIGH);
        break;

      case 8:
        Serial.println("9731");
        digitalWrite(relay1, LOW);
        digitalWrite(relay2, LOW);
        digitalWrite(relay3, LOW);
        digitalWrite(relay4, LOW);
        digitalWrite(relay5, LOW);
        digitalWrite(relay6, LOW);
        digitalWrite(relay7, LOW);
        digitalWrite(relay8, LOW);
        break;

      default:
        Serial.println("No Code Match");//case 99
        break;
    }
  } 
}

Maybe an idea for where your problem is ?

volatile byte Bits[[color=blue][b]26[/b][/color]];
....
   if (BitCount < [color=red]100[/color]) {
      ...
     Bits[[color=red]BitCount[/color]++] = 0;

Are you saying that's the problem? Should it be something like

if (BitCount > 100) { ...?

No he is pointing out that you try to cram as many as 100 bytes into an array that can only hold 26. Once you write past the end of that array you're in undefined behavior territory.

Delta_G: No he is pointing out that you try to cram as many as 100 bytes into an array that can only hold 26. Once you write past the end of that array you're in undefined behavior territory.

Ohh, so I should change the 100 to 26 bits?

Arrays start at 0 so your 26 values in the array is numbered 0 to 25.

"Ohh, so I should change the 100 to 26 bits?"

Whatever you do don't overwrite your array. That can mean making the array bigger or what you put in it smaller. Either way you need to pay attention to how big the array is and don't try to put more than that into it.

Delta_G: "Ohh, so I should change the 100 to 26 bits?"

Whatever you do don't overwrite your array. That can mean making the array bigger or what you put in it smaller. Either way you need to pay attention to how big the array is and don't try to put more than that into it.

Well I'm only using the 26 bits for a code. It just eventually quits reading the input. That's all I'm trying to fix.

Ok. I think we’ve got that and pointed you at the bug in your code. What is left unclear? If you only want to use 26 bytes then why do you have code to allow 100 through?

Delta_G: Ok. I think we've got that and pointed you at the bug in your code. What is left unclear? If you only want to use 26 bytes then why do you have code to allow 100 through?

That was just how the code was suggested to me earlier. And nobody gave me a yes or no answer to my previous question, so that was left unclear, hah.

What question? The "do I just change this line" question? I have you an answer that you either change that one or another one to either make the array larger or make sure your test doesn't allow you to overwrite it.

Do you know what those lines in your code are doing or is it all just magic to you right now? If that's the case then you should take some time to learn what you've got first.