LCD screen flashes on and off ?

Hi all.

I have written the sketch below for my Weather Station, Which incorporates a DHT22, a BMP180, a LCD i2c 20,4, and a RTC.

My problem is this, the LCD screen flashes about every second, as thought it was resetting every second, but this command is not in my sketch, the readings are accurate, can anyone advise me of what i need to add to the sketch, to stop this annoying flashing?

I have scoured the Internet for solutions, to no avail.

Here is my Sketch

#include <Wire.h> 
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display
#include <DHT.h>
#include <DHT_U.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>

RTC_DS1307 RTC;
#define DHTPIN  4          // Pin which is connected to the DHT sensor.
#define DHTTYPE  DHT22     // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);  // Initialize DHT sensor for normal 16mhz Arduino
Adafruit_BMP085 bmp;
#define DS1307_ADDRESS 0x68
#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args)  write(args);
#else
#define printByte(args)  print(args,BYTE);
#endif
byte zero = 0x00; 
 
float hum;  //Stores humidity value
float temp; //Stores temperature value
uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0};

void setup()
{

lcd.init();              
lcd.backlight();
lcd.begin(20,4);

Wire.begin();
RTC.begin();
 
}

void loop()
{
  
hum = dht.readHumidity();
temp= dht.readTemperature();

// Read Temperature from DHT22.
  
lcd.begin(20,4);
lcd.setCursor(3,1);
lcd.print("Temp. : ");
lcd.print(temp);
lcd.print("");
lcd.print((char)223);
lcd.print("C");
    
// Read Humidity from DHT22.  

lcd.setCursor(4,2);
lcd.print("Hum. : ");
lcd.print(hum);
lcd.print(" %");

//read pressure from BMP180
 
lcd.setCursor(2,3);
lcd.print("Press. : ");
lcd.print(bmp.readPressure()/200);
lcd.print(" hPa");

DateTime now = RTC.now();

lcd.setCursor(0,0);
lcd.print(now.hour(), DEC);
lcd.print(':');
   
lcd.print(now.minute(), DEC);
lcd.print(':');
   
lcd.print(now.second(), DEC);
lcd.setCursor(11, 0);
   
lcd.print(now.day(), DEC);
lcd.print('/');
   
lcd.print(now.month(), DEC);
lcd.print('/');
   
lcd.print(now.year(), DEC);
lcd.print(' ');
lcd.setCursor(9,0);
lcd.print(":");
   
}
  lcd.begin(20, 4);

Why is that in loop() ?

Hi ukhelibob.

Many Thanks.

I must be blind, i do not know why it's there, but i must have put it there. I have removed it and all is ok now.

Again, many thanks.

Regards

Ray

Hi again.

Thanks to ukhelibob my sketch is now working ok, well almost ! I have monitored the Readout on my LCD (20,4) over 24 hours, the RTC is giving some curious readouts, Firstly it does not display the correct time (After 24 hours it is 8 minutes slow) the seconds display is strange, after each minute as incremented, the seconds display starts to go up in steps of 10 digits i.e. 19,29,39,49,59,69,79,99, the minute then increments again and the seconds display may appear to star at 10, then 11 etc to 59 seconds then the minute display increments again. I have off course tried to find the countermeasure to this on the Internet to no avail. I have tried several libraries from different sources, the readout stays the same, can anyone help? I am using an Arduino UNO R3 + a ZS-042 (DS3231) RTC board.

Regards

Ray

This is the current sketch -

#include <Wire.h> 
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display
#include <DHT.h>
#include <DHT_U.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>

RTC_DS1307 RTC;
#define DHTPIN  4          // Pin which is connected to the DHT sensor.
#define DHTTYPE  DHT22     // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);  // Initialize DHT sensor for normal 16mhz Arduino
Adafruit_BMP085 bmp;
#define DS1307_ADDRESS 0x68
#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args)  write(args);
#else
#define printByte(args)  print(args,BYTE);
#endif
byte zero = 0x00; 
 
float hum;  //Stores humidity value
float temp; //Stores temperature value
uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0};

void setup()
{

lcd.init();              
lcd.backlight();
lcd.begin(20,4);

Wire.begin();
RTC.begin();
 
}

void loop()
{
  
hum = dht.readHumidity();
temp= dht.readTemperature();

// Read Temperature from DHT22.
  

lcd.setCursor(3,1);
lcd.print("Temp. : ");
lcd.print(temp);
lcd.print("");
lcd.print((char)223);
lcd.print("C");
    
// Read Humidity from DHT22.  

lcd.setCursor(4,2);
lcd.print("Hum. : ");
lcd.print(hum);
lcd.print(" %");

//read pressure from BMP180
 
lcd.setCursor(2,3);
lcd.print("Press. : ");
lcd.print(bmp.readPressure()/200);
lcd.print(" hPa");

DateTime now = RTC.now();

lcd.setCursor(0,0);
lcd.print(now.hour(), DEC);
lcd.print(':');
   
lcd.print(now.minute(), DEC);
lcd.print(':');
   
lcd.print(now.second(), DEC);
lcd.setCursor(11, 0);
   
lcd.print(now.day(), DEC);
lcd.print('/');
   
lcd.print(now.month(), DEC);
lcd.print('/');
   
lcd.print(now.year(), DEC);
lcd.print(' ');
lcd.setCursor(9,0);
lcd.print(":");
   
}
lcd.print(now.second(), DEC);
lcd.setCursor(11, 0);

I think that when the seconds get to 59 and roll over to 0, the 9 gets left over on the display. You need to overwrite that 9 by printing a leading 0 for single digit numbers or print a space after you print the seconds.

Hi groundFungus.

Many thanks for your reply.

Excuse my ignorance, but you have lost me somewhat, could you write here an example of what i should write, and where to write it, i do not fully understand what you are saying, i am still learning.

Regards

Ray

Let's say that the time is:
12:34:59
when the count rolls over it will go to:
12:35:0
but since old data on the display stays there unless overwritten the display reads:
12:35:09
12:35:19
12:35:29
...

the same sort of thing can happen when minutes and yours roll over.

The remedy is to make sure to overwrite old data. You can pad data so that the number of digits are always the same (add leading zeros or spaces) or print some spaces after you print seconds to wipe old data.

lcd.print(now.second(), DEC);
lcd.print("      ");  // six spaces
lcd.setCursor(11, 0);

Hi groundFungus.

Great, that's got rid of that problem. Although it all seems to be working fine now, it is incrementing properly, i have lost a digit on the minutes display, whereas it used to read 15:03:10, it now reads 15:3:10

Have i cocked up somewhere else?

Regards

Ray

Have i cocked up somewhere else?

Probably in the code that you have not posted

If you use leading zeros on single digit entries the data to the LCD will always b 8 digits and the old data will always be overwritten. No need for trailing spaces (as in my last post).

Here is a sketch that illustrates how to add the leading zeros.

// add leading zeros to a time output to LCD
// output will always be 8 digits.
// by C. Goulding

#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>

// create a struct with test data
struct dateTime
{
   byte hours;
   byte minutes;
   byte seconds;
};
 
dateTime now;  // test data
hd44780_I2Cexp lcd;

const int LCD_COLS = 16;
const int LCD_ROWS = 2;

void setup()
{
   Serial.begin(115200);
   lcd.begin(LCD_COLS, LCD_ROWS);
   
   // put in some dummy numbers for testing
   now.hours = 5;
   now.minutes = 5;
   now.seconds = 5;

   if(now.hours < 10)  // is hours a single digit number?
   {
    lcd.print("0"); // pad with leading zero for single digit
    lcd.print(now.hours);
   }
   else
   {
    lcd.print(now.hours);    
   }
   lcd.print(":");
   
   if(now.minutes < 10)
   {
    lcd.print("0");
    lcd.print(now.minutes);
   }
   else
   {
    lcd.print(now.minutes);    
   }
   lcd.print(":");

   if(now.seconds < 10)
   {
    lcd.print("0");
    lcd.print(now.seconds);
   }
   else
   {
    lcd.print(now.seconds);    
   }   
}

void loop()
{   
}

This is also a not quite right.

lcd.init();             
lcd.backlight();
lcd.begin(20,4);

Wire.begin();

You can't communicate with the LCD through the i/o expander backpack using API functions like backlight() until the Wire library is initialized and the LCD library is initialized.

Normally Wire.begin() should be called first to initialize the Wire library.
However, the LiquidCrystal_I2C library calls Wire.begin() in lcd.init() and lcd.begin()
So while it should be called before any other lcd API functions, with that library there is actually no need to call Wire.begin() at all.

The newer version of the LiquidCrystal_I2C library (which you must be using) uses lcd.init() and lcd.begin() to initalized the LCD.
There is no need to use both. I'd recommend using lcd.begin() as it is compatible the the LiquidCrystal API.

Also the LiquidCrystal_I2C library automatically turns on the backlight so it is on by default after calling begin()

So you could reduce those those 4 lines to:

lcd.begin(20,4); // initialize LCD and turn on backlight

--- bill

groundFungus:
Here is a sketch that illustrates how to add the leading zeros.

And also shows using the hd44780 library with auto i2c address location and auto configuration instead of using the LiquidCrystal_I2C library. :wink:

Some cores like Teensy and esp8266 include built in xxprintf() support formatting in the Print class.
That is nice since you can do this:

lcd.printf("%02d:%02d:%02d", now.hour(), now.minute(), now.second());

so much simpler....

--- bill

Hi all.

Many thanks so far for all your help. I have implemented all your suggestions, everything is now ok, except that the Time read out is still slow, the clock has lost 10 minutes in 48 hours, can anyone help me with this problem?

Regards

Ray