Arduino locks up

Hi,

I made a project using the following parts:

  • 1x Arduino Uno

  • 1x RFID-reader (MFRC522) Using this library

  • 5 RFID cards

  • 1x relay

  • 5 leds with corresponding resistors.

  • Every led corresponds to 1 RFID card.

  • Every RFID card can only be checked in once.

  • This Arduino is the Slave.

  • I use I2C to connect to the Master Arduino. It’s connected through a 10 meter cable to the Master. (CAT7 cable, highest quality, rated for military use). I didn’t use pullup resistors. I also didn’t connect grounds between Master and Slave.

  • The Arduino Master and Arduino Slave will be powered on at the same time.

I want to achieve the following:

  1. If someone holds 3 predefined cards at the RFID-reader it will light 3 leds up.
  2. It will then send the number 3 trough I2C to the Master Arduino. This number is inside “int laserteller”
  3. If someone holds the last 2 predefined cards at the RFID-reader it will light the two last leds up. It also will enable the relay.
  4. It will then send the number 5 trough I2C to the Master Arduino. This number is inside “int kaartteller”.
  5. It will blink all the leds and then turn all 5 leds off.

It works in 90% of the cases. In the last 10% the Arduino will lockup and become unresponsive. It doesn’t detect RFID cards anymore and it will not detect serial commands I enter.

  • Sometimes it locks up immediately after power on.
  • Sometimes it locks up 10 minutes (or any random minute) after being powered on.
#include <Wire.h>
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9




MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class

MFRC522::MIFARE_Key key;

// Init array that will store new NUID
byte nuidPICC[5];

byte goodCard0[10] = {0xea, 0xa5, 0x2b, 0x2b}; //9670
byte goodCard1[10] = {0x96, 0x72, 0x2a, 0x2b}; //1895
byte goodCard2[10] = {0x3a, 0x9d, 0x2c, 0x2b}; //5920
byte goodCard3[10] = {0x9c, 0xee, 0x2c, 0x2b}; //2092
byte goodCard4[10] = {0xf5, 0x80, 0x46, 0xa8}; //Blauwe druppel
byte goodCard5[10] = {0x96, 0x65, 0xe8, 0xa0}; //MASTERCARD

unsigned int kaartteller;
unsigned int laserteller;


boolean kaart0 = 0;
boolean kaart1 = 0;
boolean kaart2 = 0;
boolean kaart3 = 0;
boolean kaart4 = 0;

int relaytje = 8;

int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;
int led5 = 6;

void setup() {
  Serial.begin(9600);
  Serial.println("We zijn begonnen");

  //
  pinMode(relaytje, OUTPUT);
  digitalWrite(relaytje, HIGH);

  SPI.begin(); // Init SPI bus
  Wire.begin();
  rfid.PCD_Init(); // Init MFRC522

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);

}
void loop() {

  relay();

  // Look for new cards
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Verify if the NUID has been readed
  if ( ! rfid.PICC_ReadCardSerial())
    return;

  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);


  // Check is the PICC of Classic MIFARE type
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
      piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
      piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    //    Serial.println(F("Your tag is not of type MIFARE Classic."));
    return;
  }



  if (rfid.uid.uidByte[0] != nuidPICC[0] ||
      rfid.uid.uidByte[1] != nuidPICC[1] ||
      rfid.uid.uidByte[2] != nuidPICC[2] ||
      rfid.uid.uidByte[3] != nuidPICC[3] ||
      rfid.uid.uidByte[4] != nuidPICC[4] ) {


    // Store NUID into nuidPICC array
    for (byte i = 0; i < 5; i++) {
      nuidPICC[i] = rfid.uid.uidByte[i];

    }
    if ((memcmp(goodCard0, rfid.uid.uidByte, rfid.uid.size) == 0) && (kaart0 == 0))
    {
      kaartteller++;
      laserteller++;
      kaart0 = 1;
      digitalWrite(led1, HIGH);
    }
    if ((memcmp(goodCard1, rfid.uid.uidByte, rfid.uid.size) == 0) && (kaart1 == 0))
    {
      kaartteller++;
      laserteller++;
      kaart1 = 1;
      digitalWrite(led2, HIGH);
    }
    if ((memcmp(goodCard2, rfid.uid.uidByte, rfid.uid.size) == 0) && (kaart2 == 0))
    {
      kaartteller++;
      laserteller++;
      kaart2 = 1;
      digitalWrite(led3, HIGH);
    }
    if ((memcmp(goodCard3, rfid.uid.uidByte, rfid.uid.size) == 0) && (kaart3 == 0))
    {
      kaartteller++;

      kaart3 = 1;
      digitalWrite(led4, HIGH);
    }
    if ((memcmp(goodCard4, rfid.uid.uidByte, rfid.uid.size) == 0) && (kaart4 == 0))
    {
      kaartteller++;


      kaart4 = 1;
      digitalWrite(led5, HIGH);
    }
    if (memcmp(goodCard5, rfid.uid.uidByte, rfid.uid.size) == 0)
    {
      kaartteller = 5;
      laserteller = 3;

    }


  }

  // Halt PICC
  rfid.PICC_HaltA();

  // Stop encryption on PCD
  rfid.PCD_StopCrypto1();

}


void relay()
{

  if (laserteller == 3)
  {
    Wire.beginTransmission(8); // transmit to device #8
    Wire.write(laserteller);              // sends one byte
    Wire.endTransmission();    // stop transmitting
    //  Serial.println("jaaa");
    laserteller = 0;

  }


  if (kaartteller == 5)
  {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(relaytje, LOW);
    delay(3000);
    //   digitalWrite(relaytje, HIGH);
    laserteller = 0;


    for (byte i = 0; i < 5; i++) {
      nuidPICC[i] = 0;

    }


    delay(2000);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    delay(10);

    Wire.beginTransmission(8); // transmit to device #8
    Wire.write(kaartteller);              // sends one byte
    Wire.endTransmission();    // stop transmitting


    kaart0 = 0;
    kaart1 = 0;
    kaart2 = 0;
    kaart3 = 0;
    kaart4 = 0;
    kaartteller = 0;
  }
}

I moved “relay();” to the beginning of the loop because I thought at first that maybe this part was blocking the rest of the code. But that didn’t help either:

  // Look for new cards
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Verify if the NUID has been readed
  if ( ! rfid.PICC_ReadCardSerial())
    return;

What could be locking up my Arduino and how can I solve it?

Possible workaround if I cannot get it to stop locking up:

#1 Save the checked in cards into the EEPROM and use the watchdog to make sure the Arduino is working. After a potential reboot from the watchdog, load the data from the EEPROM.

Hi, I2C is supposed to be a PCB communication protocol, not a long distance system, 10metres is too long for it to operate reliably.

You need look at Serial RS232 communications, or RF.

Tom... :)

TomGeorge: Hi, I2C is supposed to be a PCB communication protocol, not a long distance system, 10metres is too long for it to operate reliably.

You need look at Serial RS232 communications, or RF.

Tom... :)

Hi Tom,

Thank you for replying. I also have read that I2C is for shorter distance after I had made the project. But since every time the data gets through correctly I thought that I could just leave it be. But do you think that the use of I2C in this scenario could be a reason for the lockups?

Lennyz1988: But do you think that the use of I2C in this scenario could be a reason for the lockups?

Yes.

There is even a library around that prevents issues with the I2C locking up the Arduino.