Getting a steady output on a 1602 LCD display

That is why C sucks. Even Basic is better!

That is why C sucks.

What is?

Even Basic is better!

So, get a PIC and use Basic.

Thank you Steinie44
I was just playing around a bit with your code snippet. Unfortunately it's still blinking and somehow the order in which it should show a 1 or a 0 doesn't match anymore with the input.

My bad!!! Had bits reversed. Try this:

void setup() {
  Serial.begin(9600);
  String Output = "0000000000000000";
  long x = 0b0101110101001100;
  //function to keep a 16 digit display
  Output = "";
 for (int i = 15; i >= 0; i--) {
   Output = Output + bitRead(x, i);
  }
  Serial.println(Output); //Change for LCD
}

void loop() {
}

If your LCD still flickers then you are overwriting the line too fast, or your LCD is bad.

steinie44:
That is why C sucks. Even Basic is better!

ROFL! LMFAO!
Would that be interpreter BASIC or compiled BASIC. I write the former from 1980 to 1982 when our shop got CB/80 along with CP/M. I wrote BASIC for people who HAD to have BASIC clear into 1999.

While BASIC sucks less than maybe RPG or COBOL (in some ways COBOL is better, but overall, YUCK) it is torture compared to C once you actually learn C or FORTH or PASCAL (which is "retentive") or a lot of languages made after 1970. It's no accident that M$ Visual Basic is more C than BASIC as are all later compiled BASIC's.

Take a break Steinie. Go for a walk. You've gone into emotional mode over what you don't even know.

Steinie44, thanks again,
this part is still blinking. The display itself is ok. It might be the issue, that it is refreshing to fast. The display it self shows the following:
11000000000001001 Row 0 Digits from left to right 0 to 14 blinking, digit 15 steady. The values update with change of state
of the output shift registers.
Wed 18.06 19:47 Row 1 is all steady even the lcd.print statement is in the main loop as is the function call for row 0.

I might have still misinterpreted the code snippet you gave me.
That's what I made of it

void printBinary16(unsigned int iIn){
  String output; 
  byte hiByte = highByte(iIn);
  byte loByte = lowByte(iIn);
  int binValue = word(hiByte, loByte);
  output = "";
  for(int i=15; i>=0; i--){
    output = output + bitRead(binValue, i);
  }
  lcd.print(output);
}

What happens if you just show "123456789" and nothing else in the setup, does the screen still flicker?
void setup()
{
/* fill in lcd.begin and other things */

lcd.print("123456789");
}

/* fill in lcd.begin and other things */

#include <ShiftLCD.h>

ShiftLCD lcd(9, 11, 10);                                                                                                                                 //initializing the LCD adapter pins
unsigned int lightOutput[17] = {1, 0, 0, 8, 0, 0, 64,0, 254, 512, 0, 2048,0, 0, 0, 0, 0};         //for testing
unsigned int outputL = 0;

void setup() {
  // put your setup code here, to run once:
  lcd.begin(16, 2);
}

void loop() {
  // put your main code here, to run repeatedly:
  for(int i=0; i<17; i++) {                                           //loop through the light output array
       outputL += lightOutput[i];                            //adding up the numbers
  }

  lcd.setCursor(0,0);                                               
  printBinary16(outputL);                                  //sending  the result to dislplay

}

//function to keep a 16 digit display
void printBinary16(unsigned int iIn){
  String output; 
  byte hiByte = highByte(iIn);
  byte loByte = lowByte(iIn);
  int binValue = word(hiByte, loByte);
  output = "";
  for(int i=15; i>=0; i--){
    output = output + bitRead(binValue, i);
  }
  lcd.print(output);
}

What happens if you just show "123456789" and nothing else in the setup, does the screen still flicker?

Any lcd.print("12345678whatever") comes out steady. The problem is only with the output value which is sent to the shift registers and to the lcd to show the current output status. In the process the array lightOutput[] collects integers corresponding with a binary to be sent to the shift registers like

shiftOut(dataPinOut, clockPinOut, MSBFIRST, (outputL >> 8)); //sending the date for the 
                                                               //second shift register
  shiftOut(dataPinOut, clockPinOut, MSBFIRST, outputL);        //sending the data for the
                                                               //first shift register
  digitalWrite(latchPinOut, HIGH);                  //setting the latch pin back to

My idea was to use the same variable "outputL" convert it to a binary and display it on LCD to have a visual check on the output.

Do you know what kind of shift register it's using?

Do you know what kind of shift register it's using?

There are two 74HC595 taking care of the output.

Ok I saw your 1st post. Sounds like the Library code is not using the latch pin in the 74HC595. I think I would look for a different Library for that or a update.

Try this.

#include <ShiftLCD.h>

ShiftLCD lcd(9, 11, 10);                                                                                                                                 //initializing the LCD adapter pins
unsigned int lightOutput[17] = {1, 0, 0, 8, 0, 0, 64,0, 254, 512, 0, 2048,0, 0, 0, 0, 0};         //for testing
unsigned int outputL = 0;
unsigned int lastInt = 0;

void setup() {
  // put your setup code here, to run once:
  lcd.begin(16, 2);
}

void loop() {
  // put your main code here, to run repeatedly:
  outputL = 0;
  for(int i=0; i < 17; i++) 
  {                                           //loop through the light output array
       outputL += lightOutput[ i ];                            //adding up the numbers
  }                                             
  printBinary16(outputL);                                  //sending  the result to dislplay

}

void printBinary16(unsigned int iIn)
{
  if( iIn != lastInt)
  {
    lastInt =  iIn;
    byte hiByte = highByte(iIn);
    byte loByte = lowByte(iIn);
    int binValue = word(hiByte, loByte);

    for(int i=15; i>=0; i--)
    {
      lcd.setCursor(15-i, 0); // these might be backwards
      lcd.print( bitRead(binValue, i));
    }
  }
}

Thank you HazardsMind,
it is still doing the same thing. Looking at my main sketch and the snippet you just posted, I am checking actually twice if the incoming value has changed and only update the display value if the incoming value has changed which in my books should give a steady output.
Maybe Steinie44 is right and there is a problem in the lcd library. I guess I need to have a closer look at it.

With Serial.print() this would work but I dunno about lcd.print():

void printBinary16(unsigned int iIn)
{
  lcd.print( iIn, BIN );
}

Which begs the question of using a function to call a function.

    byte hiByte = highByte(iIn);
    byte loByte = lowByte(iIn);
    int binValue = word(hiByte, loByte);

is just another way of

    int binValue = iIn;

and why not just use iIn instead of binValue?

With Serial.print() this would work but I dunno about lcd.print():

lcd.print(value, BIN); works just fine, which however has the same problem of a blinking output.

Now the trick going through all the trouble of a bitwise output is that (value, BIN) is dropping the last digits if they are a 0. The trouble is that every 0 or 1 at it's place is standing for a status of a specific place which again is corresponding to the place in the binary number. This again doesn't work if the display moves to the left because the last digits are dropped while 0. The trouble is that only the Row 0 of the display is blinking and only if it has to print that binary number. Any other text is coming steady as is row 1 displaying date and time.

Ok I saw your 1st post. Sounds like the Library code is not using the latch pin in the 74HC595. I think I would look for a different Library for that or a update.

I had a good look through and it does use the latch pin. Again, the problem must be some where how the display deals with printing out a binary number.

It just got more of a mystery when I was running row 1 through kind of a roll over routine since I need to display a bit more information on the second row.

Row 1 is now displaying date and time in exchange with room temperature and photocell reading in lux. Soon as the display is showing temperature and photocell reading, row 0 displaying the binary number, becomes steady. There fore, while analog readings are never that stable, in row 1 only the readings jump a little to the variance in the reading it self. Soon as the display goes back in row 1 showing date and time, which is a steady display, the binary in row 0 starts blinking again.

Here the two functions displaying row 1:

void displayDateTime(){
  lcd.setCursor(0, 0);             //set the corsor to line 1 pos 1
  lcd.print("               ");    //print 15 blanks to delete all
                                   //prior statements
  lcd.setCursor(0, 1);             //set cursor to row 2 pos 1
  lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(weekday_table[currentDay]))));
  lcd.print(" ");
  if(currentDoM < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
  lcd.print(currentDoM);
  lcd.write(pgm_read_byte(&char_table[4]));   //print dott
  if(currentMonth < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
  lcd.print(currentMonth);
  lcd.print(" ");
  if(currentHour < 10) lcd.write(pgm_read_byte(&char_table[2]));  
                                   //if the hour is less than 10
                                   //we print a 0 to keep 2 digits
  lcd.print(currentHour);          //print current time (hour)
  lcd.write(pgm_read_byte(&char_table[3]));   //print seperator
  if(currentMinute < 10) lcd.write(pgm_read_byte(&char_table[2]));  
                                   //if the minute is less than
                                   //10 print 0 to keep 2 digits
  lcd.print(currentMinute);        //print current time (minutes)
}

void displayTemp() {
  lcd.setCursor(0, 1);
  lcd.print("T ");
  lcd.print(temperatur1);
  lcd.print(" C");
  lcd.print(" ");
  lcd.print("L");
  lcd.print(map(sensorValue, 0, 1023, 0, 10000));
  lcd.print(" Lux");
}

and the function call in the main loop:

endTime = (millis() / 1000) - displayTimeSet;
  if(endTime <= (displayTimeSet + 15)) displayDateTime();
  if(endTime > (displayTimeSet + 15) && endTime <= (displayTimeSet + 30)) displayTemp();
  if(endTime > (displayTimeSet + 30)) displayTimeSet = millis() / 1000;

The code dealing with the blinking row 0 is still the same as last posted from HazardsMind.

The trouble is that only the Row 0 of the display is blinking and only if it has to print that binary number.

From what I have seen of your code you are not actually printing a binary number, rather a series of zeroes or ones.

As an experiment try testing whether each bit is a zero or a one and printing a character such as an 'A' regardless. Is the display steady or does it bink ? If it blinks then remove the loop testing the bit values and print some fixed text such as "10101010". If the display is steady then the problem is in your routine testing the bit values.

From what I have seen of your code you are not actually printing a binary number, rather a series of zeroes or ones.

Taking your advice and checking if it still blinks, taking out the loop comes up with the following:
replacing the lcd.print() in the function as follows:

void printBinary16(unsigned int iIn)  {
  ///////////1234567812345678
  lcd.print("0011100101010011");	
}

is still blinking.

And replacing it with characters

void printBinary16(unsigned int iIn)  {
  ///////////1234567812345678
  lcd.print("This is a test A");	
}

Is still blinking
And wanting it to know, reducing the amount of characters in the lcd.print() command like

void printBinary16(unsigned int iIn)  {
  ///////////1234567812345678
  lcd.print("Test");	
}

is still blinking.......

Put a 1 second delay in the function, and see if it still blinks

Printing a BIN will lose leading zeros, the high-order bits that are zero.

The blinking could be from trying to update the LCD too fast.
Too fast here may mean too fast for your eyes, not the LCD.

FWIW, this will only print every 1/2 sec or less as a test to see if update speed makes a difference.
If it works or even helps, try tuning tWait. Perhaps 250U or 200U won't be too fast.
Untested but tested Serial Monitor version is below:

void printBinary16(unsigned int iIn)
{
  static unsigned int  tNow; // using 2 byte time variables instead of 4 byte
  static unsigned int  tStart = 0U;
  static unsigned int  tWait = 500U; // you can tune the max print rate with tWait

  tNow = ( millis() & 0xFFFF ); // tNow is the low 16 bits of the current time
  if (( iIn != lastInt) && ( tNow - tStart >= tWait )) // data has changed AND tWait millis or more has passed
  {
    lastInt =  iIn;
    tStart = tNow; // able to print again in 1/4 second

    lcd.setCursor( 0, 0 ); 
    for(int i=15; i>=0; i--) // print in high bit down to low bit order
    {
      lcd.print( bitRead( iIn, i )); 
    }
  }
}

Tested, prints a new line about twice a second depending on data change but no faster than 2x per.
The lines still scroll pretty fast, let it fill Serial Monitor and focus on just the last one.
You can make it scroll faster by changing tWait to 1U and ( millis() >> 8 ) to millis().

void setup( void )
{
  Serial.begin( 9600 );
  Serial.println( "\ntesting\n" );
}

void loop( void )
{
  static unsigned int  data;
  
  data = (( millis() >> 8 ) & 0xFFFF ); // this changes every 256 millis
  printBinary16( data );
}

void printBinary16( unsigned int prntBits )
{
  static unsigned int  lastBits = 0U;
  static unsigned int  tNow; // using 2 byte time variables instead of 4 byte
  static unsigned int  tStart = 0U;
  static unsigned int  tWait = 500U; // you can tune the max print rate with tWait

  tNow = ( millis() & 0xFFFF ); // tNow is the low 16 bits of the current time
  if (( prntBits != lastBits ) && ( tNow - tStart >= tWait )) // data has changed AND tWait millis or more has passed
  {
    lastBits = prntBits;
    tStart = tNow; // able to print again in 1/4 second

    for( short i = 15; i >= 0; i-- ) // print in high bit down to low bit order
    {
      Serial.print( bitRead( prntBits, i )); 
    }
    Serial.println();
  }
}