I have just gotten my hands on an Arduino Diecimila that I have interfaced to an AMC2004AR 20X4 LCD display thru an LCD117 serial adapter. I modified some code I found online that basically displays a message until the Arduino senses that a button has been pushed. If it has, a different message is displayed.
The problem is that this routine causes the display to flash as it rewrites the message once a second. It also requires that the button be held down for at least 1 second to ensure proper opperation due to the delay statement.
Is there a way to do this so that the display doesn't flicker but remains a static message until the button is pushed and to be more responsive to the button push?
Code follows:
// *
// * ------------
// * Control a Serial LCD Display
// *
// * Arduino Diecimila
// * AMC2004AR 4x20 LCD
// *
// *
// * Further modified by JAK - 6/10/08
// *
// * ------------
// *
// *
// Pushbutton circuit:
// resistor from +5V to one end of S1
// jumper from resistor-switch node to I/O pin 12
// pushing button grounds I/O pin 12, which normally floats high
// Program Variables
int inputPin = 12; // choose the input pin (for a pushbutton)
int val = 0; // variable for reading the pin status
void loop()
{
clearLCD(); // clear screen
val = digitalRead(inputPin); // read input value
if (val == HIGH) // check if the input is HIGH
{
Serial.print(" This Device"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" Will Self-Destruct"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" In 30 Seconds"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" RUN!"); // print text to the current cursor position
delay(1000);
}
else
{
Serial.print(" Too Late:"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" BOOM!!!"); // print text to the current cursor position
delay(2000);
}
}
Clearing the display is what's causing it to flicker, so avoid clearing the LCD when you don't need to.
void loop()
{
// print your initial message
clearLCD(); // clear screen
Serial.print(" This Device"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" Will Self-Destruct"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" In 30 Seconds"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" RUN!"); // print text to the current cursor position
// loop here until the button is pressed
while (!digitalRead(inputPin))
;
delay(10); // wait for the button to finish bouncing
clearLCD();
Serial.print(" Too Late:"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" BOOM!!!"); // print text to the current cursor position
// loop here until the button is released
while (digitalRead(inputPin))
;
delay(2000);
}
Ben:
Thanks. I tried your code but it raised as many questions as it answered. As written, your code caused the display to be blank after upload. When I pushed the button, I got erattic results depending on how long I held down the button. My overall impression of the display results was that it was semi-working, only backwards. In other words, "Too Late BOOM" was the default display and, "This device..." appeared for 2 seconds when the button was pushed. I switched the negation signs (!) in the two while statements, recompiled and uploaded. I still started out with a blank screen, but when I pressed the button, I got the proper display for a button push, "Too Late BOOM". Upon releasing the button, I got the proper display, "This device...". After that first cycle, the display continues to work as expected. Either way, why do I start out with a blank screen? I would like the display to power up with the 1st message displayed.
I'm wondering if I/O pin 12 might do an inversion of its own. I verified with a voltmeter that the voltage at pin 12 is 5V when the button is not pushed and 0V when it is pushed.
I am also confused by the when statements themselves. I thought that a when statement would execute the code in the set of braces following the statement if the boolean statement in parenthesis evaluated to true and skip the code between the braces if the boolean evaluated false. You don't have a set of brace-bound code after your when statements, just a semi-colon. Does the while statement just loop on itself and do nothing until it fails? That would explain the seeming reversal of the negation statements.
Gee, I think I just answered my question while asking it.
Anyway, thanks for your help. Hope to hear back from you soon.
Jim
My while loops have the wrong arguments. Try removing the ! from the first loop and adding one to the second:
void loop()
{
// print your initial message
clearLCD(); // clear screen
Serial.print(" This Device"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" Will Self-Destruct"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" In 30 Seconds"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" RUN!"); // print text to the current cursor position
// loop here until the button is pressed while (digitalRead(inputPin))
;
delay(10); // wait for the button to finish bouncing
clearLCD();
Serial.print(" Too Late:"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" BOOM!!!"); // print text to the current cursor position
// loop here until the button is released while (!digitalRead(inputPin))
;
delay(2000);
}
and see if that makes a difference. The while loops exist just to occupy the CPU until the condition in parentheses is met (i.e. they achieve a "wait here and do nothing until condition x occurs").
I still don't understand why initially got a blank LCD. Did you remember to include your setup() function?
Turns out I need some initial delay for the LCD. The following code works perfectly.
Thanks for your help.
Jim
// *
// * ------------
// * Control a Serial LCD Display
// *
// * Tested on a Matrix Orbital model LCD0821 display.
// * Other diplays will work but may have slightly different
// * command codes and hardware setups.
// *
// * Copyleft 2006 by djmatic
// *
// * Further modified by JAK - 6/10/08 (with help from Ben S)
// *
// * ------------
// *
// *
// Pushbutton circuit:
// resistor from +5V to one end of S1
// jumper from resistor-switch node to I/O pin 12
// pushing button grounds I/O pin 12, which normally floats high
// Declare your program variables here
int inputPin = 12; // choose the input pin (for a pushbutton)
int loopval = 0; // variable for checking for 1st iteration
// to avoid ganged delays
void loop()
{
// print your initial message
clearLCD();
if (loopval == 0) // initial delay, 1st loop only
delay(2000);
Serial.print(" This Device"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" Will Self-Destruct"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" In 30 Seconds"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" RUN!"); // print text to the current cursor position
loopval = 1; // no delay on subsequent loops
// loop here until the button is pressed
while (digitalRead(inputPin));
delay(10); // wait for the button to finish bouncing
clearLCD();
Serial.print(" Too Late:"); // print text to the current cursor position
newLine(); // carriage return - line feed
Serial.print(" BOOM!!!"); // print text to the current cursor position
delay(2000);
while (!digitalRead(inputPin)); // loop here until the button is released
}
// LCD FUNCTIONS
void clearLCD() { // clear the LCD
Serial.print("?f");
}
void newLine() { // start a new line
Serial.print("?n");
}