16x2 LCD strange behavior - slow refresh page and gibberish

i have an arduino mega 2560 connected to “dfrobot” 16x2 LCD shield and i have issues:

  1. the display randomly get messed and display gibberish. it happens completely randomly, can be after a minute or after a day (or more) working fine …

  2. when i press a button its sometimes do more then it should and sometimes do other action then it was supposed to . the main problem is on DOWN button and sometimes on LEFT and RIGHT , UP is working fine.

3.the display sometimes refresh itself really slow…

i check for spikes or electrical issues since the project involved pumps solenoids and relays and for now haven’t found that this is the cause so i think maybe there are code mistakes (its my first “serious” arduino project).
the project is hydroponic controller and the code is pretty long. i attach only the parts which i see relevant to the LCD and be glad if someone could check the code … tips will be more then welcome . thanx

the LCD:
http://www.ebay.com/itm/New-1602-LCD-Board-Keypad-Shield-Blue-Backlight-For-Arduino-Duemilanove-Robot-/130729447956?hash=item1e70151214:g:UOsAAOSwuMFUkA~V

arduino_hydro_controller_2.2_-_with_humidity_no_i2c_no_web_SMS.ino (8.19 KB)

display_page.ino (7.93 KB)

ISR1.ino (834 Bytes)

post_buttons.ino (14.3 KB)

read_LCD_buttons.ino (525 Bytes)

i check for spikes or electrical issues since the project involved pumps solenoids and relays and for now haven't found that this is the cause so i think maybe there are code mistakes (its my first "serious" arduino project).

Temporarily replace your solenoids and relays with LEDs and see if your code functions properly.

Don

A quick look at the sketch suggests multiple problems, here are a few:

  1. The slow LCD update suggests the processor is busy handling Interrupts that are occuring fast and keeping it busy. There are 2 ISRs called up they do not have a handler thus the Interrupt Vector may be garbage or perhaps there are parts of the sketch that are not included in the post:
    attachInterrupt(digitalPinToInterrupt(2), pulseCounterIn, FALLING);
    attachInterrupt(digitalPinToInterrupt(3), pulseCounterOut, FALLING);
    Pins 2 and 3 are inputs, the sketch attempts to set them high, this activates a pullup to try to fix the logic state at the input but if wires are attached the pin it can still pickup noise. Since the code does not use these inputs perhaps they are flapping about and generating interrupts from crosstalk. Comment out these lines if you are not using them yet.

2.The sketch uses an ADC with different voltages indicating different buttons. I suspect button bounce is giving voltage readings that are bad/unstable. To get from one voltage to another the line transitions through other levels, switch bounce makes it transition many times. Multiple sample the ADC signal and only use the reading when it has stabilised within a certain noise/error band.

3.The sketch mentions a GSM shield. Typically these take huge gulps of current very briefly and emit strong RF signals that can upset nearby electronics. Is a GSM shield attached, if it is and it is not used in the sketch yet then disconnect it and see if the fault signature (the errors seen) changes?

Fix those and we’ll see what problems are left.

first thank you for checking my code , i rally appreciate it. now i do checks and i loaded to arduino previous sketch version without the input 2 and 3 interrupts and without the GSM function, only the main interrupt. i disconnected the GSM shield completely .

the problem still exist.

i was worried about the main interrupt too but i see that the slow operation of the LCD occur when i'm in "stop" mode (when i'm enter the settings page) and in this state all the interrupts are disabled.. in "run" mode the display working fine.

i do check again for the output of every button by serial output command and the values seems to be fine. . the main issue that interrupt me to work is the weird behavior of the buttons, specially the DOWN button and the annoying gibberish .

i will try to turn it on for a while without any pumps or solenoids connected and will see ..

rowboteer: Multiple sample the ADC signal and only use the reading when it has stabilized within a certain noise/error band.

do you have ready code for that ? i found some on the web but it didn't work

Something like this should work (caveat this is completely untested):

int read_LCD_buttons()    //READ_LCD_BUTTONS 
{

  if (adc_key_in > 950) return btnNONE; // Return straight away as no button is pressed

  int count = 0;
  int new_button = btnNONE;
  int old_button   = btnNONE;
  limit = 16;

  while( (count<8) && (limit>0) ) // Loop until we have 8 matching readings or loop count is 16
  {
    int adc_key_in = analogRead(BUTTONSinput);  // read the value from the analog pin
    delay(2); // Slow while loop down to let signal settle
    if (adc_key_in > 950) new_button = btnNONE;
    if (adc_key_in < 50)   new_button = btnRIGHT;;
    if (adc_key_in >= 50  && adc_key_in < 150) new_button = btnUP;
    if (adc_key_in >= 150 && adc_key_in < 350) new_button = btnDOWN;
    if (adc_key_in >= 350 && adc_key_in < 550) new_button = btnLEFT;
    if (adc_key_in >= 550 && adc_key_in < 750) new_button = btnSELECT; 

    if (new_button != oldbutton) {
      count = 0;
      old_button = new_button;
    }
    else count++;

    limit--; // Count down so we don't stay in the loop when value is very unstable
  }

  if (limit == 0) new_button = btnNONE; // We never got a stable ADC reading
  return new_button;
}

rowboteer:
Something like this should work (caveat this is completely untested):

int read_LCD_buttons()    //READ_LCD_BUTTONS 

{

if (adc_key_in > 950) return btnNONE; // Return straight away as no button is pressed

int count = 0;
 int new_button = btnNONE;
 int old_button   = btnNONE;
 limit = 16;

while( (count<8) && (limit>0) ) // Loop until we have 8 matching readings or loop count is 16
 {
   int adc_key_in = analogRead(BUTTONSinput);  // read the value from the analog pin
   delay(2); // Slow while loop down to let signal settle
   if (adc_key_in > 950) new_button = btnNONE;
   if (adc_key_in < 50)   new_button = btnRIGHT;;
   if (adc_key_in >= 50  && adc_key_in < 150) new_button = btnUP;
   if (adc_key_in >= 150 && adc_key_in < 350) new_button = btnDOWN;
   if (adc_key_in >= 350 && adc_key_in < 550) new_button = btnLEFT;
   if (adc_key_in >= 550 && adc_key_in < 750) new_button = btnSELECT;

if (new_button != oldbutton) {
     count = 0;
     old_button = new_button;
   }
   else count++;

limit–; // Count down so we don’t stay in the loop when value is very unstable
 }

if (limit == 0) new_button = btnNONE; // We never got a stable ADC reading
 return new_button;
}

hi , sorry for the long delay… , i use your change in sketch for the button bouncing and that really fixed the problem of the bush button behavior now its working fine so thank you very much !! .

for the LCD strange behavior , i disconnected all the motors,solenoids and relays from the system and the LCD looks fine for many hours so i guess its electrical noise issue after all , i also read that the LCD’s are really sensitive to noises in the system .

i guess i need to add RC snubber circuits . i added fly-back diode in each of the 4 pumps and on the solenoids , the problem continue … i not so familiar with noise and spike issues and not sure what type of capacitors and resistors to put , i read that there is a lot of options where to put them also , for start i guess i put it between the terminals of each motor pump .
apart for that , i’m trieng to find a good way to connect the LCD to the arduino . maybe twist pair cables … ?

is it a good idea ?