Hi All--
I have a contact open/closed monitoring project using the Adafruit Data Logger shield with an Arduino Uno and I am using a standard 16x2 44780 clone lcd as a display.
I am using the LiquidCrystal.h library.
The program is working fine, and reliably detects open/closed transitions (loop polling an input pin with switch debounce), time date stamps them from the RTC, records elapsed time in a state, and writes the data to the SD card on state change. Most of the time, the lcd display indicates what it is supposed to show, i.e. state and elapsed time.
Randomly, after certain state changes, the lcd display will go dark or display gibberish. The underlying program continues to work normally and all state changes are detected and logged. The problem is isolated to the display. I spent time chasing power supply stability, and grounding with no effect. I then started looking at timing issues.
I was using lcd.clear() after a state change in preparation for writing new data to the display. Instead of adding a delay after this command, I substituted lcd.begin(). The display has not gone blank or strange since this change. I don't know if it fixed a critical timing issue or if there is a reset of something that was getting corrupted by a power/grounding glitch.
Can anyone explain the key differences in the two commands and provide a link to the underlying code. Any ideas as to why lcd.begin() has fixed the erratic behaviour. I understand that lcd.clear() writes to each location and is relatively slow. I think that lcd.begin() resets r/s and enable, maybe clears the display ram and sets pointers. It certainly clears the screen like lcd.clear(). Is there any reason not to use lcd.begin() instead of lcd.clear() on all occasions. I've always used lcd.begin() just once in setup and now I wonder if there's any reason not to use in generally.
Thanks for any insights.
Is there any reason not to use lcd.begin() instead of lcd.clear() on all occasions?
I think you shouldn't be using either of them.
LCD begin is use to initialise the LCD. It probably does clear it but that is something you wouldn't normally know. It is a command normally just used once in the setup.
LCD clear does indeed clear the screen and is normally not used at all, which is a pretty good way of avoiding the slowness you mention.
You are right to use lcd.begin in the setup only. It may indeed fix your problem in the loop but nobody else does it that way, they do it by avoiding the problem. I submit the problem is entirely down to slack formatting, principally caused by output data being shorter than its predecessor etc.
One common error is not using leading zeros in time/date stamping. Occasionally you might have to supply a blank space after a number but that should be about all the "clearing" you need.
No comment about going dark. I can't imagine you have stuffed up the formatting that badly and i think something else is afoot.
Nick--
Thank you for the coding advice.
slack formatting, principally caused by output data being shorter than its predecessor etc.
I understand. I have been lazy, and used lcd.clear() rather than printing spaces in new statements when text is changing.
I will reformat the output and remove both lcd.clear and lcd.begin() from the loop to see if that fixes the going dark problem.
If it is a timing problem then I think it will be fixed, if "there is something else afoot" then it has to be something related to the display is getting corrupted during the loop, and reset by the use of lcd.begin().
cattledog:
If it is a timing problem then I think it will be fixed, if "there is something else afoot" then it has to be something related to the display is getting corrupted during the loop, and reset by the use of lcd.begin().
Timing problem........ That's interesting, and could explain a lot. I just update displays at one second intervals, but if you are updating in an uncontrolled loop, that could be the "something else" , maybe including the dark periods.
Problem Statement-- standard 16x2 parallel lcd primarily displays gibberish or sometimes goes dark during normally operating contact state monitoring data logging program. Program continues to operate normally while display is abnormal. I am not completely certain, but I believe that the display goes corrupt on a switch closure, but not when the switch is open or closed and all that is going on is the display of elapsed time. The switch (coil operated mechanical relay) is software debounced, but I believe that there is indeed hardware bounce in the switch.
Software Fixes--
lcd.begin () placed in the loop reliably eliminates the problem and must be resetting something which is corrupted.
I have reformatted the lcd.print statements to clear old data by printing spaces, and removed all calls outside of set up to lcd.clear() and lcd.begin(). with no change to the problem.
I have placed the display update in a separate if (millis() - last_update_millis >1000) loop (nested in the main loop) which caused the display to be updated only once a second with no change to the problem.
From the above results, I do not think that the root cause is a timing conflict between the display update and the other operations within the program. However, to further investigate this, I can eliminate the elapsed time update in the program, which can easily conflict with a state change, and only write to the display after there is a state change/RTC call and not much is going on.
I am currently back looking at hardware issues, focusing on the display ground (easier at this time than placing it on a separate power supply).
I have changed the state change input pin from INPUT_PULLUP to basic INPUT with a pull down resistor and switched 5v to the pin rather than grounding it thinking that might clean up the lcd ground with no effect.
I am currently testing with both the lcd VSS and R/W (pins 1 and 5) attached to an external ground, isolated from the Arduino. I'll run overnight, and see if there is any solution.
cattledog:
I am currently back looking at hardware issues, focusing on the display ground (easier at this time than placing it on a separate power supply).
You shouldn't need to have separate power to the display, have it entirely driven by Arduino and check for external nasties like relay coils and contact spikes.