Stuck in loops

I have multiple RFID readers and an Override by HC-05. The override works perfectly once the button is pushed on the app. But my issue now is leaving the override, for some reason whenever the button is pushed on the app again the code goes back to the normal loop, runs through the loop once and goes straight back to the override section. If someone could please help me it would be greatly appreciated.

Here is my code below:

/**
* "Object Placement" Puzzle
*
* This puzzle requires the player to place one or more items in the
* correct location, at which point an RFID tag embedded in the object
* is detected by a sensor.
* When all sensors read the tag of the correct object, the puzzle is solved.
*
* Demonstrates:
* - SPI interface shared between several devices
* - RFID library
*/

// DEFINES
char data ='o';
int master = 2;
// Provides debugging information over serial connection if defined
#define DEBUG

// LIBRARIES
// Standard SPI library comes bundled with the Arduino IDE
#include <SPI.h>
// Download and install from https://github.com/miguelbalboa/rfid
#include <MFRC522.h>

// CONSTANTS
// The number of RFID readers
const byte numReaders = 10;
// Each reader has a unique Slave Select pin
const byte ssPins[] = {22,23,24,25,26,27,28,29,30,31};
// They'll share the same reset pin
const byte resetPin = 8;
// This pin will be driven LOW to release a lock when puzzle is solved
const byte lockPin = 9;
// The sequence of NFC tag IDs required to solve the puzzle
const String correctIDs[] = {"571baef2","871caef2","e71caef2","d76caef2","376daef2","776caef2","176caef2","5791aff2","e71baef2","b76baef2"};

// GLOBALS
// Initialise an array of MFRC522 instances representing each reader
MFRC522 mfrc522[numReaders];
// The tag IDs currently detected by each reader
String currentIDs[numReaders];


/**
 * Initialisation
 */
void setup() {
  pinMode(master, OUTPUT);
  digitalWrite(master, LOW);
  #ifdef DEBUG
  // Initialise serial communications channel with the PC
  Serial.begin(9600);
  Serial.println(F("Serial communication started"));
  #endif
  
  // Set the lock pin as output and secure the lock
  pinMode(lockPin, OUTPUT);
  digitalWrite(lockPin, LOW);
  
  // Initialise the SPI bus
  SPI.begin();

  for (uint8_t i=0; i<numReaders; i++) {
  
    // Initialise the reader
    // Note that SPI pins on the reader must always be connected to certain
    // Arduino pins (on an Uno, MOSI=> pin11, MISO=> pin12, SCK=>pin13)
    // The Slave Select (SS) pin and reset pin can be assigned to any pin
    mfrc522[i].PCD_Init(ssPins[i], resetPin);
    
    // Set the gain to max - not sure this makes any difference...
    // mfrc522[i].PCD_SetAntennaGain(MFRC522::PCD_RxGain::RxGain_max);
    
  #ifdef DEBUG
    // Dump some debug information to the serial monitor
    Serial.print(F("Reader #"));
    Serial.print(i);
    Serial.print(F(" initialised on pin "));
    Serial.print(String(ssPins[i]));
    Serial.print(F(". Antenna strength: "));
    Serial.print(mfrc522[i].PCD_GetAntennaGain());
    Serial.print(F(". Version : "));
    mfrc522[i].PCD_DumpVersionToSerial();
  #endif
    
    // Slight delay before activating next reader
    delay(50);
  }
  
  #ifdef DEBUG
  Serial.println(F("--- END SETUP ---"));
  #endif
}

/**
 * Main loop
 */
void loop() {
  if(Serial.available()>0){    
      data= Serial.read(); // reading the data received from the bluetooth module

      switch(data){

        case 'a': onOverride();break; // when a is pressed on the app on your smart phone

        case 'b': loop();break; // when b is pressed on the app on your smart phone
      }
}
  // Assume that the puzzle has been solved
  boolean puzzleSolved = true;

  // Assume that the tags have not changed since last reading
  boolean changedValue = false;

  // Loop through each reader
  for (uint8_t i=0; i<numReaders; i++) {

    // Initialise the sensor
    mfrc522[i].PCD_Init();
    
    // String to hold the ID detected by each sensor
    String readRFID = "";
    
    // If the sensor detects a tag and is able to read it
    if(mfrc522[i].PICC_IsNewCardPresent() && mfrc522[i].PICC_ReadCardSerial()) {
      // Extract the ID from the tag
      readRFID = dump_byte_array(mfrc522[i].uid.uidByte, mfrc522[i].uid.size);
    }
    
    // If the current reading is different from the last known reading
    if(readRFID != currentIDs[i]){
      // Set the flag to show that the puzzle state has changed
      changedValue = true;
      // Update the stored value for this sensor
      currentIDs[i] = readRFID;
    }
    
    // If the reading fails to match the correct ID for this sensor 
    if(currentIDs[i] != correctIDs[i]) {
      // The puzzle has not been solved
      puzzleSolved = false;
      digitalWrite(lockPin, LOW);
      digitalWrite(master ,LOW); 
    }

    // Halt PICC
    mfrc522[i].PICC_HaltA();
    // Stop encryption on PCD
    mfrc522[i].PCD_StopCrypto1(); 
  }

  #ifdef DEBUG
  // If the changedValue flag has been set, at least one sensor has changed
  if(changedValue){
    // Dump to serial the current state of all sensors
    for (uint8_t i=0; i<numReaders; i++) {
      Serial.print(F("Reader #"));
      Serial.print(String(i));
      Serial.print(F(" on Pin #"));
      Serial.print(String((ssPins[i])));
      Serial.print(F(" detected tag: "));
      Serial.println(currentIDs[i]);
    }
    Serial.println(F("---"));
  }
  #endif

  // If the puzzleSolved flag is set, all sensors detected the correct ID
  if(puzzleSolved){
    onSolve();
  }
 
  // Add a short delay before next polling sensors
  //delay(100); 
}

/**
 * Called when correct puzzle solution has been entered
 */
void onSolve(){

  #ifdef DEBUG
  // Print debugging message
  Serial.println(F("Puzzle Solved!"));
  #endif
  
  // Release the lock
  digitalWrite(lockPin, HIGH);
  digitalWrite(master, HIGH);
  delay(60000);  
  

    
}

void onOverride(){
  while(1==1){
    digitalWrite(lockPin, HIGH);
    digitalWrite(master, HIGH);
      if(Serial.available()>0){    

      data= Serial.read(); // reading the data received from the bluetooth module

      switch(data){

        case 'a': break; // when a is pressed on the app on your smart phone

        case 'b': loop();break; // when b is pressed on the app on your smart phone
      }
}
}
}

/**
 * Helper function to return a string ID from byte array
 */
String dump_byte_array(byte *buffer, byte bufferSize) {
  String read_rfid = "";
  for (byte i=0; i<bufferSize; i++) {
    read_rfid = read_rfid + String(buffer[i], HEX);
  }
  return read_rfid;
}

Why have you Serial.read() in different parts of your program? Just put it in a single function that is called at the start of loop() and use whatever data is received throughout that iteration of loop().

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

Also don't create infinite loops such as while(1==1). Just allow loop() to do the iteration.

...R

Ok so I have changed my code and removed the infinite loop and the extra Serial.read. The issue now it that whenever I hit the button, without the loop, the relay just turns on and then right back off.

Here is the new section of code below:

void onOverride(){
    digitalWrite(lockPin, HIGH);
    digitalWrite(master, HIGH);
      if(Serial.available()>0){    

      switch(data){

        case 'a': break; // when a is pressed on the app on your smart phone

        case 'b': loop();break; // when b is pressed on the app on your smart phone
      }
}
}

Zsapp1460: Here is the new section of code below:

Please post the complete program.

...R

You check if Serial is available, then don't do anything more? Usually you would read from Serial right after checking if there's something to read.

Case 'b' calls the loop() function. That's usually going to give you infinite recursion and very strange things will happen when it runs out of memory in a few milliseconds.

I understand that I am having a strange memory issue when I call loop, I just don’t understand how to fix that issue.

Here is the new complete code:

/**
* "Object Placement" Puzzle
*
* This puzzle requires the player to place one or more items in the
* correct location, at which point an RFID tag embedded in the object
* is detected by a sensor.
* When all sensors read the tag of the correct object, the puzzle is solved.
*
* Demonstrates:
* - SPI interface shared between several devices
* - RFID library
*/

// DEFINES
char data ='o';
int master = 2;
// Provides debugging information over serial connection if defined
#define DEBUG

// LIBRARIES
// Standard SPI library comes bundled with the Arduino IDE
#include <SPI.h>
// Download and install from https://github.com/miguelbalboa/rfid
#include <MFRC522.h>

// CONSTANTS
// The number of RFID readers
const byte numReaders = 10;
// Each reader has a unique Slave Select pin
const byte ssPins[] = {22,23,24,25,26,27,28,29,30,31};
// They'll share the same reset pin
const byte resetPin = 8;
// This pin will be driven LOW to release a lock when puzzle is solved
const byte lockPin = 9;
// The sequence of NFC tag IDs required to solve the puzzle
const String correctIDs[] = {"571baef2","871caef2","e71caef2","d76caef2","376daef2","776caef2","176caef2","5791aff2","e71baef2","b76baef2"};

// GLOBALS
// Initialise an array of MFRC522 instances representing each reader
MFRC522 mfrc522[numReaders];
// The tag IDs currently detected by each reader
String currentIDs[numReaders];


/**
 * Initialisation
 */
void setup() {
  pinMode(master, OUTPUT);
  digitalWrite(master, LOW);
  #ifdef DEBUG
  // Initialise serial communications channel with the PC
  Serial.begin(9600);
  Serial.println(F("Serial communication started"));
  #endif
  
  // Set the lock pin as output and secure the lock
  pinMode(lockPin, OUTPUT);
  digitalWrite(lockPin, LOW);
  
  // Initialise the SPI bus
  SPI.begin();

  for (uint8_t i=0; i<numReaders; i++) {
  
    // Initialise the reader
    // Note that SPI pins on the reader must always be connected to certain
    // Arduino pins (on an Uno, MOSI=> pin11, MISO=> pin12, SCK=>pin13)
    // The Slave Select (SS) pin and reset pin can be assigned to any pin
    mfrc522[i].PCD_Init(ssPins[i], resetPin);
    
    // Set the gain to max - not sure this makes any difference...
    // mfrc522[i].PCD_SetAntennaGain(MFRC522::PCD_RxGain::RxGain_max);
    
  #ifdef DEBUG
    // Dump some debug information to the serial monitor
    Serial.print(F("Reader #"));
    Serial.print(i);
    Serial.print(F(" initialised on pin "));
    Serial.print(String(ssPins[i]));
    Serial.print(F(". Antenna strength: "));
    Serial.print(mfrc522[i].PCD_GetAntennaGain());
    Serial.print(F(". Version : "));
    mfrc522[i].PCD_DumpVersionToSerial();
  #endif
    
    // Slight delay before activating next reader
    delay(50);
  }
  
  #ifdef DEBUG
  Serial.println(F("--- END SETUP ---"));
  #endif
}

/**
 * Main loop
 */
void loop() {
  if(Serial.available()>0){    
      data= Serial.read(); // reading the data received from the bluetooth module

      switch(data){

        case 'a': onOverride();break; // when a is pressed on the app on your smart phone

        case 'b': loop();break; // when b is pressed on the app on your smart phone
      }
}
  // Assume that the puzzle has been solved
  boolean puzzleSolved = true;

  // Assume that the tags have not changed since last reading
  boolean changedValue = false;

  // Loop through each reader
  for (uint8_t i=0; i<numReaders; i++) {

    // Initialise the sensor
    mfrc522[i].PCD_Init();
    
    // String to hold the ID detected by each sensor
    String readRFID = "";
    
    // If the sensor detects a tag and is able to read it
    if(mfrc522[i].PICC_IsNewCardPresent() && mfrc522[i].PICC_ReadCardSerial()) {
      // Extract the ID from the tag
      readRFID = dump_byte_array(mfrc522[i].uid.uidByte, mfrc522[i].uid.size);
    }
    
    // If the current reading is different from the last known reading
    if(readRFID != currentIDs[i]){
      // Set the flag to show that the puzzle state has changed
      changedValue = true;
      // Update the stored value for this sensor
      currentIDs[i] = readRFID;
    }
    
    // If the reading fails to match the correct ID for this sensor 
    if(currentIDs[i] != correctIDs[i]) {
      // The puzzle has not been solved
      puzzleSolved = false;
      digitalWrite(lockPin, LOW);
      digitalWrite(master ,LOW); 
    }

    // Halt PICC
    mfrc522[i].PICC_HaltA();
    // Stop encryption on PCD
    mfrc522[i].PCD_StopCrypto1(); 
  }

  #ifdef DEBUG
  // If the changedValue flag has been set, at least one sensor has changed
  if(changedValue){
    // Dump to serial the current state of all sensors
    for (uint8_t i=0; i<numReaders; i++) {
      Serial.print(F("Reader #"));
      Serial.print(String(i));
      Serial.print(F(" on Pin #"));
      Serial.print(String((ssPins[i])));
      Serial.print(F(" detected tag: "));
      Serial.println(currentIDs[i]);
    }
    Serial.println(F("---"));
  }
  #endif

  // If the puzzleSolved flag is set, all sensors detected the correct ID
  if(puzzleSolved){
    onSolve();
  }
 
  // Add a short delay before next polling sensors
  //delay(100); 
}

/**
 * Called when correct puzzle solution has been entered
 */
void onSolve(){

  #ifdef DEBUG
  // Print debugging message
  Serial.println(F("Puzzle Solved!"));
  #endif
  
  // Release the lock
  digitalWrite(lockPin, HIGH);
  digitalWrite(master, HIGH);
  delay(60000);  
  

    
}

void onOverride(){
    digitalWrite(lockPin, HIGH);
    digitalWrite(master, HIGH);
      if(Serial.available()>0){    

      switch(data){

        case 'a': break; // when a is pressed on the app on your smart phone

        case 'b': loop();break; // when b is pressed on the app on your smart phone
      }
}
}

/**
 * Helper function to return a string ID from byte array
 */
String dump_byte_array(byte *buffer, byte bufferSize) {
  String read_rfid = "";
  for (byte i=0; i<bufferSize; i++) {
    read_rfid = read_rfid + String(buffer[i], HEX);
  }
  return read_rfid;
}

The simple way to do that is "Don't call loop()". If you want to get back to loop() from your function, use ``` return; ```

Calling loop() from within your program is the equivalent of a snake eating its own tail. DON'T.

There is nothing strange about having memory issues - they are guaranteed.

...R