Sketch crashing (?) and repeating setup()

Hi

For some reason my Arduino sketch seems to be crashing and I've can't figure out what is going on. My suspicion is some kind of overflow - the error seems to occur at the bottom of the loop() routine. I'm reluctant to post the full code (it's around 2700 lines, and requires a number of hardware components... but can if someone thinks it will help).

In a nutshell with a simplistic view of the code...

void setup()
{
  // code

  // debug output to LCD "setup complete"
}

void loop()
{
  // debug output to LCD "loop start"

  // other code

  // debug output to LCD "loop end"
}

Output expected...

setup complete
loop start
loop end
loop start
loop end
...

What I actually get...

setup complete
loop start
loop end
setup complete
loop start
loop end
...

So for some reason is seems to crash at the bottom of the loop() routine and resets.

Anyone got any ideas what could cause this sort of behavior?

Appreciate any assistance.

In a nutshell with a simplistic view of the code...

I see nothing in that (clearly not your real) code that would cause the issues you are having, nor do I see any proof that the Arduino is resetting.

I'll bet that you can figure out what you need to do.

If the Arduino is not reseting then is there another explanation of why the setup() routine gets executed repeatedly?

Thanks.

If the Arduino is not reseting then is there another explanation of why the setup() routine gets executed repeatedly?

Show me something in the code you posted that proves that this is happening. Any little thing.

You could be running out of RAM, but without code, we're all just guessing.

What people are hinting at is to read the information for posters before posting and thus posting a useful
enquiry with all the information we need to work out whats happening. The code, all of the code in code tags.
And we need to know whats wired up and how and how its powered... Without that we are in the dark.

Usually reseting like this is either down to hardware issues or software issues. Thus we need to know
everything we can about both.

Ok I’ve cut down a version of the code which still fails. I’ve also tracked it down to a single line that causes it to fail… marked with XXXX. If I comment this line out the program works… uncomment it and I get the behavior described.

I’ll try post a schematic of the circuit… but in a nut shell a 20x4 LCD 44870 controller, and a 4x4 matrix keypad.

Now attached…

// Include the LCD library
#include <LiquidCrystal.h>



// Define the pin that turns the LCD backlight on/off.
#define LCDBacklightPin 13

 

// Define the pins for the keypad connections.
int rowPin[4] = {9,10,11,12};  
int colPin[4] = {5,6,7,8};

// Definition of global variables used throughout the program.

int GBL_userID = 0;                 // Currently logged in user.

boolean GBL_backLightIsOn = true;   // Whether the backlight is on/off.

unsigned long GBL_timePrevious = 0; // Last time we checked this user's time.

int i = 0; 

// Create a serial instance representing the LCD, used globally.
// SoftwareSerial LCD = SoftwareSerial(0, LCDPin); 

// LiquidCrystal lcd(RS, EN, D4, D5, D6, D7)
 
// Initialize the library with the numbers of the LCD interface pins
LiquidCrystal myLCD (1, 2, 3, 4, A1, A0);

// One time setup & initialisation.

void setup()
{

//  Serial.begin(9600);
 

  // Initialise the pin used for the LCD backlight.
  pinMode(LCDBacklightPin, OUTPUT);

  // set up the LCD's number of columns and rows: 
  myLCD.begin(20, 4);

  // Initialise the key pad.
  for (int i = 0; i <=3; i++)
    {
      pinMode(colPin[i], OUTPUT);
      digitalWrite(colPin[i], LOW);
      
      pinMode(rowPin[i], INPUT);
    }     

  lcdBacklight(true);

  lcdClear();
  lcdPosition(0,0);
  lcdWriteString("setup done");
  delay(1000);  
}



// Main program loop.

void loop()
{  
    lcdClear();
    lcdPosition(0,0);
    lcdWriteString("loop start");
    delay(1000);  
        
    // Prompt the user to log in.      
    T0_userLogin();
  
    lcdClear();
    lcdPosition(0,0);
    lcdWriteString("loop end");
    delay(1000);  
}

// The first time after powering up we force the Admin to log in.  This is to prevent someone disconnecting the power without being noticed.

// Routine to get a user from the login screen.  Will not return to caller until a user is found.

void T0_userLogin()
{
  char pin[5];

    // Display the login prompt
    
      lcdClear();  
      lcdPosition(0,0);
      lcdWriteString("input screen");

      delay(500);
    
  
    for (i = 0; i <= 5; i++)
      pin[i] = ' ';

    // Get the PIN number from the user.
    int result = getInput(2, 1, pin, 5, 5, true, 0, false);

//   char keyPressed = getKey(5000,false);

 
}



// Routine to get write a value to the LCD, and allow it to be edited via the keypad.

int getInput(int row, int col, char before[], int minChar, int maxChar, boolean hidden, int alpha, boolean CRReq)
{
   lcdCursor(true);  

    char keyPressed = getKey(5000, false);

    return 0;
}  

// Get a key from the keppad.
// If more than timeout milliseconds pass without a key being pressed then an error 'X' will be returned.

char getKey(int timeout, boolean switchBacklight)

{
    
//  return 'X';
  
  // Define the key values to be returned.
  char key [4][4] = {{'1', '2', '3', 'A'},
    	             {'4', '5', '6', 'B'},
		     {'7', '8', '9', 'C'},
	             {'*', '0', '#', 'D'}};

  // Keep track of the start time.
  long startTime = millis();
  
  // Difference between the start time and the current time.
  long duration;  

    while (true)
    {

      // Check to ensure the timeout value has not been reached.  If it has we stop and return 'X'.
      duration =  millis() - startTime;
    
      if (duration > timeout)
      {
        if(switchBacklight)
          {
            GBL_backLightIsOn = false;
            lcdBacklight(false);
          }

        return 'X';
      }

      // Scan the keypad looking for a key press.
      for (int i = 0; i <=3; i++)
        {
            digitalWrite(colPin[i], HIGH); 

	    for (int j = 0; j <=3; j++)
	    {
                          
                if (digitalRead(rowPin[j]) == HIGH)  // A key is being pressed. 
                    {
                        unsigned long before = millis();
                        
                        while (digitalRead(rowPin[j]) == HIGH); // Wait until the key is released.
                        
                        delay(50);  
                        
  	                if (!GBL_backLightIsOn)
                          {
                          GBL_backLightIsOn = true;  
                          lcdBacklight(true);
                          }
               
                        digitalWrite(colPin[i], LOW);
                        return key[j][i];  
                    }
	    }
            digitalWrite(colPin[i], LOW);
        }
    }
}


// ------------------- LCD control routines ----------------------------------------------------------


// Routine to position the cursor within the display.

void lcdPosition(int row, int col) 
{
  myLCD.setCursor(col, row);
}


// Routine to turn the cursor on/off. Replaced with debug code
void lcdCursor (boolean on)
{
  // The following line causes the sketch to fail. 
  
  lcdWriteString(" fails");  // XXXX
}

// Routine to write something to the LCD.
void lcdWriteString(char string[])
{
  myLCD.write(string);
}


// Routine to write a single ASCII character.
void lcdWriteByte(byte string)
{ 
  char myChar = string;
  myLCD.write(myChar);
}


// Routine to clear the LCD screen.
void lcdClear()
{
  myLCD.clear();
}


// Routine to turn the LCD backlight on/off.
void lcdBacklight(boolean on)
{ 
 
  if (on)
  {
    GBL_backLightIsOn = true;
    digitalWrite(LCDBacklightPin, HIGH);
  }
  else
  {
    GBL_backLightIsOn = false;

    digitalWrite(LCDBacklightPin, LOW);
  }
}

schematic.tiff (42.4 KB)

  char pin[5];
for (i = 0; i <= 5; i++)
      pin[i] = ' ';

BZZZT!

Code:
char pin[5];
Code:
for (i = 0; i <= 5; i++)
pin = ' ';
BZZZT!
[/quote]
THANK YOU VERY MUCH !!! ... Problem solved.
2700 lines... one character wrong... very unforgiving. Guess I must have been over writing something important !

for (int i = 0; i <=3; i++)
        {
            digitalWrite(colPin[i], HIGH);

You do this more or less everywhere, when the more natural (IMO) construct would be

for (int i = 0; i < sizeof (colPin) / sizeof (colPin [0]); i++)
        {
            digitalWrite(colPin[i], HIGH);

or similar.
For array access and for loops, I hardly ever use “<=”

In general, the code you’re using to process arrays is error prone and encourages errors of this sort. You should never hard-code the expected size of the array within the for loop. The size should only be defined in one place, which is where the array is defined. If the array is explicitly sized, define the size via a constant and use the constant as the constraint for the for loop:

const int PIN_COUNT = 5;
char pin[PIN_COUNT];

...

for (int i = 0; i < PIN_COUNT; i++)
{
  ....

If the array is implicitly sized, measure the size of the array after you have declared it:

int rowPin[] = {9,10,11,12};  
const int ROW_PIN_COUNT = size(rowPin) / sizeof(rowPin[0]);