LCD compatibility

Hello to the Forum.

I have been working on a project that uses an optical encoder and LCD to display a value from turning the encoder shaft.
So far my breadboard has been working Ok using a 16X2 LCD that uses the Hitachi chip (HD44780). So next was to use the LCD that was 12X1, a model made by Newhaven model NHD-0112BZ that I believe uses the SPLC780D chip. I have looked online and it appears this chip is compatible with the Hitachi chip but from what i am seeing it may not fully be.
Here is my code:

#include <LiquidCrystal.h>
LiquidCrystal lcd (4,5,6,7,8,9);
volatile float xcount = 0.0;
volatile int xdir = 12;
float x_axis;
float x_axis_dia;
int zero_pin = 10; //Zero x axis readout button pin
                    //if high or 1 then clear display
int R_D_pin = 11; //display radius or diameter
                    //if high or 1 then display diameter
// X axis interupt routine
void xstep() {
  if (digitalRead(xdir) == 1) {
    xcount++;
  }
  else {
    xcount--;
  }
}
void setup() {
  Serial.begin(9600);
  pinMode(zero_pin, INPUT);
  pinMode(R_D_pin, INPUT);
  lcd.begin(12,1);
  lcd.setCursor(0,0);
  
  attachInterrupt(digitalPinToInterrupt(2), xstep, RISING);
}

void loop() {
  float x_axis = xcount/5000.0;
  
    if (digitalRead(zero_pin) == 1) {
      xcount = 0.0;
      //Serial.println("H");
    }
    if (digitalRead(R_D_pin) == 1) {
     x_axis_dia = x_axis*2.0; //display diameter 
     lcd.setCursor(0,0);
     lcd.print("XD ");
    }
     else {
      x_axis_dia = x_axis;  //display radius
      lcd.setCursor(0,0);
      lcd.print("X ");
    }
  lcd.setCursor(3,0);
  lcd.print(x_axis_dia,5);
  //Serial.println(x_axis,5);
  
}

The display shows up with the characters X and XD plus number 0.0 however when I turn the encoder I am not seeing the full count like I was seeing on the 16X2 display which worked perfectly but not on this 12x1 display. Just the 0.0 and depending on the count 0.1 for example but none of the numbers before the .1 (not sure i explained that right but hope the idea comes through).
Any thoughts on what could be the issue between the displays? Oh I am using the Arduino Pro Mini 5 volt version.
Thanks,
Bruce

Try this encoder library - GitHub - enjoyneering/RotaryEncoder: This is small and fast Arduino library for Rotary Encoder with interrupts.

Most 16x1 displays that use an HD44780U controller are actually set up internally as 8x2 displays with row 0 displaying the 8 characters on the left side and row 1 displaying the 8 characters on the right side.

It looks like your 12 x1 display works in a similar manner.

I think your best shot is to use lcd.begin(6,2); and if that doesn't work then try lcd.begin(8,2);. Don't forget to reset your cursor after displaying the first 6 characters.

I can't see how using a different encoder library could possibly fix a display problem.

Don

I didn't say that my encoder lib will fix lcd problem.

His post contained only one question and that was about a display problem. If your reply was related to something else then you really should have mentioned that fact.

I did take a look at your library to make sure that it didn't in fact contain some kind of LCD code before I posted my comment.

By the way I just got a hold of some encoders and I will check out your library when I get a chance.

Don

Thanks for the thoughts on this display issue Don. I will test that out later today.

Thanks for the link on encoder library Enjoy. I think I have seen that already, very interesting.

Bruce

floresta:
His post contained only one question and that was about a display problem. If your reply was related to something else then you really should have mentioned that fact.

Don

Agree, my bad. More info about encoder lib -Lightweight Arduino Library for Rotary Encoder - Sensors - Arduino Forum

Ok so I tried Don's suggestion lcd.begin(6,2) and lcd.begin(8,2) both resulted in a blank display no characters displayed at all.
So now I have a LCD program that all it does is send to the display "LCD TEST" and it displays "LCD TE"
and the rest is missing "ST".
I have a second one of these displays and will try that next. It is possible I have a bad LCD which is very
disconcerting since they are new from Mouser!

Well, it looks like you have a 6x2 display.

If you get "LCD_TE" when you use lcd.begin(16, 2); try:

    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("LCD_TE");
    lcd.setCursor(0, 1);
    lcd.print("ST");

All the same, I would expect lcd.begin(6, 2); to work.

David.

David,
I tried what you suggested and that came back with a blank display no characters displayed.

OK so tried 2nd display and it does the same thing.
I am now wondering if these displays come up in 4 bit mode (default) or 8 bit mode and have to
be told to go to 4 bit.

Of course you have to tell them to change to 4-bit.
Most libraries only use 4-bit. They provide the init sequence to change to 4-bit.
8-bit is a waste of GPIO pins.

Well I am surprised the lcd.begin(6,2) didn't work since line 1 would be DDRAM addr 00-05 for 1 to 6 position and line 2 for 40-45 for 7 to 12 position. I have registered on the NewHaven forum and have asked the same question i asked here but not sure i will get a response back.
Only other thing I can think of is the timing is too fast (enable) and the LCD is not going into 4 bit mode but that is a wild guess on my part.

Tried adjusting delay values in LiquidCrystal library the .cpp file lines toggling the enable line. They were set at 1 , 1 and 100 and I went all the way to 4, 4, 300 but the display didn't change.
Guess its time to find another manufacturer of LCD's that still uses the HD44780.

Instead of tinkering with the library .cpp file you might want to just try using your LCD without a library. You can get some ideas by checking out the LCD Programming Examples link at Don's Collected Technical Information.

When dealing with LCD addressing be sure to differentiate between the rows of characters on your display and the lines of memory within the LCD controller. These terms are not interchangeable. To find out more about the memory addressing and how it relates to displayed character locations follow the LCD Addressing link at the same location.

Another thought: Why don't you just send a sequence of 80 displayable ASCII characters to your device and see what happens. The results should help you deal with the addressing problem. Don't forget to let it run for a while, there will be a delay after the first half of the display is populated before the characters appear on the second half.

#include <LiquidCrystal.h>

//LiquidCrystal lcd(rs,en,d4,d5,d6,d7);
  LiquidCrystal lcd(12, 11, 5, 4, 3, 2);       // put your pin numbers here

void setup()
  {
    lcd.begin(20, 4);                          // put your LCD parameters here
    for (char i=47; i<127; i++)                // send 80 consecutive displayable characters to the LCD
      {
        lcd.print(i);
        delay(100);                            // this delay allows you to observe the addressing sequence
      }
  }


void loop()
  {  
  }

Finally:

Guess its time to find another manufacturer of LCD's that still uses the HD44780.

Virtually all of the character mode LCDs available at the traditional hobbyist outlets are HD44780 compatible and will work with the LiquidCrystal library.

Don

Here is a link to a datasheet for the LCD you said you had (NHD-0112BZ) :
https://www.mouser.com/ds/2/291/NHD-0112BZ-FL-YBW-38803.pdf
Note that on page 5 you can see the address map for the display.
00, 01, 02, 03, 04, 05, 40, 41, 42, 43, 44, 45

Clearly it is a 6x2 display internally. This uses the same split line layout as the 16x1 displays that Don mentioned in post #2.

One thing that I didn't understand is your comment from post #7

Ok so I tried Don's suggestion lcd.begin(6,2) and lcd.begin(8,2) both resulted in a blank display no characters displayed at all.
So now I have a LCD program that all it does is send to the display "LCD TEST" and it displays "LCD TE"
and the rest is missing "ST".

You said begin(6,2) and begin(8,2) didn't work at all (blank display), but then you also said you had a display that only shows the first 6 letters, of a string that is longer than 6 lettters
Note that only showing the first 6 letters is the expected behavior.

My question is how did you initialize the library when it worked by showing only the first 6 letters of the string?
Were you using something other than begin(6,2) or begin(8,2) ?

Once you tell us that, we can probably get you going.

My hd44780 library (hd44780_pinIO class) may be of interest to you.
The hd44780 library supports automatic line wrapping.
This is very helpful for 16x1 displays like Don mentioned earlier as it can make a 16x1 display that is really a 8x2 display work like a 16x1 display.
With the hd44780 library and that type of 16x1 display you tell the library that the display is 8x2 and enable automatic line wrapping.
The library will wrap to the next line when the 9th character is sent but since the physical display shows 2 lines on a single line on the physical LCD display, you get the same behavior as if the display were really a 16x1.
i.e. you can print strings longer than 8 characters on the line and they show up as desired on the 16x1 display.

I'd be welling to bet that this works on your display as well.

But we need to know what you did to get the display working where you only saw the first 6 characters of a longer string- which is the normal/expected behavior.

--- bill

To get the display to show those first 6 characters I used lcd.begin(12,1) (if you looked through the code that's what is there) which is what I thought should be used since the display is advertised as a 12X1. This corresponds to the all the examples i have seen using lcd.begin(16,2) and I have tested this via breadboard using a 16x2 display and worked perfectly. That LCD was a Sharp using HD44780 chip.
That is not the display i planned to use and only had the 16x2 on hand at the time.

7b_w:
To get the display to show those first 6 characters I used lcd.begin(12,1) (if you looked through the code that's what is there) which is what I thought should be used since the display is advertised as a 12X1.

Yes we could see that in the code from the first post; however, you didn't post the code you mentioned in post #7 that was displaying "LCD TE"

The difference between them is 1 line vs 2 line mode.
That can affect the contrast setting. Did you try adjusting the contrast pot when using 2 line mode?

The LCD TE on the display is the expected output for that display given the memory addressing map shown in the data-sheet.
The "missing" ST characters are stored in DDRAM but are not displayed on the physical LCD as the right half of the display is using DDRAM starting at memory location 40 - it is essently the first 6 characters of what is normally the 2nd line of a LCD display.
That is what the code that david provided in post #8 was trying to work around.

But it seems like there is some kind of issue with 2 line mode.

The examples in the data-sheet show using 2 line mode.
so I'm bit surprised that 2 line mode isn't work.

If you can get 2 line mode to work, then you can use the hd44780 library to auto wrap lines to make the 6x2 display work like a 12x1 display.

--- bill

Thanks for the reply Bill.

Sorry I should have provided that code but it was the example "Hello World" code in examples under the IDE just modified a little by me (pins etc.).

At first I thought I could use just a diode to ground with a 10K resistor in series to provide contrast but that didn't work to well so used an outboard pot to adjust then measure the resistance and put in a fixed resistor in place of the diode. I will take that out and try the pot again since I can see what your getting at about the contrast between both halves of the display.

I got a response back from Newhaven forum and the driver ST7066 chip should be compatible with the HD44780. I did ask about using lcd.begin(12,1) versus lcd.begin(6,2) and which one is correct to use so still awaiting a reply on that.

Bruce

7b_w:
I got a response back from Newhaven forum and the driver ST7066 chip should be compatible with the HD44780. I did ask about using lcd.begin(12,1) versus lcd.begin(6,2) and which one is correct to use so still awaiting a reply on that.

The only parameter that affects initialization of the actual h/w (in this case) is the rows. (1 vs 2)
The hd44780 chip has two modes. single line mode and two/multi line mode.

In the data sheet I found on mouser and provided a link to, (assuming that is the proper one)
the sample initialization code that they provide in the datasheet uses 2 line mode.
See pages 7 and 8 of the mouser newhaven datasheet.
You can seem them setting the N bit (bit 3) of the function set command in their sample initialization sequence which is setting 2 line mode. They even commented about using 2 line mode.
i.e. these lines:

command(0x38); //Function set: 8-bit/2-line

command(0x28); //Function set: 4-bit/2-line

Again, neither mode will change how text from DDRAM memory is displayed on the physical display.
That is fixed by the internal h/w as shown in the data sheet as two discontiguous sections of memory since internally it is two lines.

But if you can get 2 line mode working, you can use the hd44780 library to make the 2 line display work like a 1 line display.

--- bill

So I put the temporary pot back in and adjusted contrast with lcd.begin(6,2) and got "LCD TE" to display. Then I went back and added "ST" and set cursor to 0,1...excellent it now displays "LCD TEST".

#include <LiquidCrystal.h>

LiquidCrystal lcd (4,5,6,7,8,9);
int time = 0;
void setup() {
  lcd.begin(6,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("LCD TE");
  lcd.setCursor(0,1);
  lcd.print("ST");

}

void loop() {
  //lcd.setCursor(0,0);
 // lcd.print(time);
  //delay(1000);
  //time++;

}

So now how do i get this to act as 1 line 12 characters in length?
Thanks for everyone's help so far.
Bruce

Update:
I did a search for HD44780 library and found yours Bill so I loaded into my library and now have to find info on how to use it.