I really hesitate to post this because I just know that I'm doing something stupid, but I would appreciate any input. I am have an Arduino Mega 2560 with an LCD shield. I am trying to make a sort of pseudo-alarm system with it. Enter 4 digit sequence of buttons, alarm sets, enter it again to get a message. Anyway. Everything was going nicely, I got it to store the password. Then I tried to make it do something with those numbers. It seems that after it breaks out of the while loop it goes straight to the top of the program (ie. it runs the setup() again). I don't know if I am doing something wrong with my while loop or if I am just missing something.
Step by step:
I run the program.
It displays the initial "Begin Alarm." (on the lcd)
It then starts accepting values and outputting them to the serial so I can see them.
Gets the 4 button sequence as I expected. Displays it on serial.
When I press a button the 5th time, it displays "Begin Alarm" again (on the lcd) and the whole thing repeats.
"Password Set" is never displayed.
Its like the Arduino is getting reset. Again, I am probably just doing something wrong, but I would appreciate any insight anyone could give me.
Full code is below
#include <Wire.h>
#include <LiquidCrystal.h> // include LCD library
/*--------------------------------------------------------------------------------------
Defines
--------------------------------------------------------------------------------------*/
// Pins in use
#define BUTTON_ADC_PIN A0 // A0 is the button ADC input
#define LCD_BACKLIGHT_PIN 10 // D10 controls LCD backlight
#define RIGHT_10BIT_ADC 0 // right
#define UP_10BIT_ADC 120 // up
#define DOWN_10BIT_ADC 280 // down
#define LEFT_10BIT_ADC 480 // left
#define SELECT_10BIT_ADC 720 // right
#define BUTTONHYSTERESIS 30 // hysteresis for valid button sensing window
//return values for ReadButtons()
#define BUTTON_NONE 0 //
#define BUTTON_RIGHT 1 //
#define BUTTON_UP 2 //
#define BUTTON_DOWN 3 //
#define BUTTON_LEFT 4 //
#define BUTTON_SELECT 5 //
//some example macros with friendly labels for LCD backlight/pin control, tested and can be swapped into the example code as you like
#define LCD_BACKLIGHT_OFF() digitalWrite( LCD_BACKLIGHT_PIN, LOW )
#define LCD_BACKLIGHT_ON() digitalWrite( LCD_BACKLIGHT_PIN, HIGH )
#define LCD_BACKLIGHT(state) { if( state ){digitalWrite( LCD_BACKLIGHT_PIN, HIGH );}else{digitalWrite( LCD_BACKLIGHT_PIN, LOW );} }
/*--------------------------------------------------------------------------------------
Variables
--------------------------------------------------------------------------------------*/
byte buttonJustPressed = false; //this will be true after a ReadButtons() call if triggered
byte buttonJustReleased = false; //this will be true after a ReadButtons() call if triggered
byte buttonWas = BUTTON_NONE; //used by ReadButtons() for detection of button events
int password[4]; //Where we will store the passoword
/*--------------------------------------------------------------------------------------
Init the LCD library with the LCD pins to be used
--------------------------------------------------------------------------------------*/
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 ); //Pins for the freetronics 16x2 LCD shield. LCD: ( RS, E, LCD-D4, LCD-D5, LCD-D6, LCD-D7 )
//------------------------------------------------------------------------------------
void setup()
{
//button adc input
pinMode( BUTTON_ADC_PIN, INPUT ); //ensure A0 is an input
digitalWrite( BUTTON_ADC_PIN, LOW ); //ensure pullup is off on A0
//lcd backlight control
digitalWrite( LCD_BACKLIGHT_PIN, HIGH ); //backlight control pin D3 is high (on)
pinMode( LCD_BACKLIGHT_PIN, OUTPUT ); //D3 is an output
//set up the LCD number of columns and rows:
lcd.begin( 16, 2 );
//Print some initial text to the LCD.
lcd.setCursor( 0, 0 ); //top left
// 1234567890123456
lcd.print( " Begin Alarm" );
lcd.setCursor( 0, 1 ); //bottom left
lcd.print( "Btn:" );
delay(1000);
Serial.begin(9600);
}
void loop()
{
byte button;
byte lastbutton = 0;
button = ReadButtons();
lcd.setCursor (0,0); //Top left
lcd.print ("Enter 4 button ");
button = ReadButtons();
lcd.setCursor(0,1);
lcd.print ("Password:");
button = ReadButtons();
int t = 0;
while (t <5)
{
button = ReadButtons();
if (button != lastbutton) //If the button has changed since last time
{
switch( button ) //Go into the switch
{
case BUTTON_NONE:
{
lastbutton = button;
break;
}
case BUTTON_RIGHT:
{
lcd.setCursor( 10, 1 );
lcd.print( "RIGHT " );
password[t] = button;
lastbutton = button;
t = t+1;
break;
}
case BUTTON_UP:
{
lcd.setCursor( 10, 1 );
lcd.print( "UP " );
password[t] = button;
lastbutton = button;
t = t+1;
break;
}
case BUTTON_DOWN:
{
lcd.setCursor( 10, 1 );
lcd.print( "DOWN " );
password[t] = button;
lastbutton = button;
t = t+1;
break;
}
case BUTTON_LEFT:
{
lcd.setCursor( 10, 1 );
lcd.print( "LEFT " );
password[t] = button;
lastbutton = button;
t = t+1;
break;
}
case BUTTON_SELECT:
{
lcd.setCursor( 10, 1 );
lcd.print( "SELECT-FLASH" );
password[t] = button;
lastbutton = button;
t = t+1;
break;
}
default:
{
break;
}
}
}
Serial.print (password[0]);
Serial.print (F(" "));
Serial.print (password[1]);
Serial.print (F(" "));
Serial.print (password[2]);
Serial.print (F(" "));
Serial.print (password[3]);
Serial.print (F(" "));
Serial.println (t);
}
// ------------------------- END GET PASSWORD --------------------------------
//----------------------------------------------------------------------------------------
lcd.setCursor(0,0);
lcd.print (F("Password Set "));
lcd.setCursor(0,1);
lcd.print (F(" "));
delay (5000);
}
/*--------------------------------------------------------------------------------------
ReadButtons()
Detect the button pressed and return the value
Uses global values buttonWas, buttonJustPressed, buttonJustReleased.
--------------------------------------------------------------------------------------*/
byte ReadButtons()
{
unsigned int buttonVoltage;
byte button = BUTTON_NONE; // return no button pressed if the below checks don't write to btn
//read the button ADC pin voltage
buttonVoltage = analogRead( BUTTON_ADC_PIN );
//sense if the voltage falls within valid voltage windows
if( buttonVoltage < ( RIGHT_10BIT_ADC + BUTTONHYSTERESIS ) )
{
button = BUTTON_RIGHT;
}
else if( buttonVoltage >= ( UP_10BIT_ADC - BUTTONHYSTERESIS )
&& buttonVoltage <= ( UP_10BIT_ADC + BUTTONHYSTERESIS ) )
{
button = BUTTON_UP;
}
else if( buttonVoltage >= ( DOWN_10BIT_ADC - BUTTONHYSTERESIS )
&& buttonVoltage <= ( DOWN_10BIT_ADC + BUTTONHYSTERESIS ) )
{
button = BUTTON_DOWN;
}
else if( buttonVoltage >= ( LEFT_10BIT_ADC - BUTTONHYSTERESIS )
&& buttonVoltage <= ( LEFT_10BIT_ADC + BUTTONHYSTERESIS ) )
{
button = BUTTON_LEFT;
}
else if( buttonVoltage >= ( SELECT_10BIT_ADC - BUTTONHYSTERESIS )
&& buttonVoltage <= ( SELECT_10BIT_ADC + BUTTONHYSTERESIS ) )
{
button = BUTTON_SELECT;
}
//handle button flags for just pressed and just released events
if( ( buttonWas == BUTTON_NONE ) && ( button != BUTTON_NONE ) )
{
//the button was just pressed, set buttonJustPressed, this can optionally be used to trigger a once-off action for a button press event
//it's the duty of the receiver to clear these flags if it wants to detect a new button change event
buttonJustPressed = true;
buttonJustReleased = false;
}
if( ( buttonWas != BUTTON_NONE ) && ( button == BUTTON_NONE ) )
{
buttonJustPressed = false;
buttonJustReleased = true;
}
//save the latest button value, for change event detection next time round
buttonWas = button;
return( button );
}
Thanks
Matt