SOLVED: How to get a 1x16 10PIN LCD to work with Arduino?

Hello Everybody,

this is my first post here. I hope I fulfill the quality standards with my post and don´t receive harsh critique like others before me. :confused:
I have tried to find answers for my little problem in this forum and all over the web for no good. So, this is my last attempt on this and hopefully some knowledgeable folks can help me.

I have salvaged a 1x16 10PIN LCD display from a cricut digital cutting machine.
It appears to be a generic unit with "UM1601 A1" printed on the back and some other numbers, none of them good to find a manufacturer / data sheet. Here is a picture front and back:

I am trying to use this display with an Arduino UNO.

My assumptions:
It has a Hitachi HD44780 compatible controller,
It is not an I2C display,
Its R/W is pulled to GND as default, otherwise I would not get along with just 10 pins.

The reduced number of pins does not allow me to connect it the "standard" way like a 16pin or 14 pin unit.

Regarding the Pin assignment I am 100% sure on these pins: (the colors refer to the wires, that I am using in my prototype setup as seen on the fotos below.)

PIN1 GND black
PIN2 VCC +5V red
PIN3 VO BIAS (or commonly known as "contrast") 10K Potentiometer between GND and +5V
PIN10 Background light appx. 4.2V 100 Ohm resistor connected to yellow / +5V

Just with above pins connected to the UNO board I have the background light working and see squares on the left half of the display.

I am 50% sure on:

PIN4 RS Blue, connected to Ardu Pin 12
PIN5 Clock (E) White, connected to Ardu Pin 11
PIN6-9 DATA Orange LCD pin 6 to Ardu Pin 5, LCD7 to 4, 8 to 3 and the LCD Pin 9 to Ardu Pin2. (kind of cross wired, I have tried the other way around with identical result)

All wires are checked good for continuity, by the way. All breadboard connections are fine, have used different slots, used the original wire harness, all with same result.

With this Setup I can set a cursor to any position, have it blinking, turn the display on/off, but I don´t get any characters displayed with the "print" or "write" commands.

Here is, how I have it connected to the Arduino:



Here is the code that I worked with when I took the screenshot:

This code kind of "grew" out of the basic "Hello World" sketch when I was adding different LCD related commands to see what the action is. Basic result: all commands in that sketch work except "print" and "write".
I am using liquidChrystal 1.4, but have tried older versions (1.0).

Here are my questions:

Has anybody dealt with a 10pin LCD of this kind before?
Am I correct with above assumptions regarding HD44780, I2C and R/W?
Am I doing anything wrong with the wiring or the code?
Is it possible that I shot the LCD´s character ROM and the RAM during my initial PIN testing with +5V or GND?
Might a different library do the job?
Are there any other tricks that I might try like delay timings between commands or library tweaks (might need some help with that though)
Am I a fool wasting X hours of my life just to get a used 5$ device back to use??

Here are some observations, which might be useful:

1)After I pull and re-connect the +5V to the LCD it weakly shows the 8 dark squares on the left side of the display, with a cursor blinking and scrolling slowly from left to right, blinking for 5 sec on each slot, then disappear for good. The squares remain dimmed until I re-load the code to the Arduino. Then the squares disappear and the blinking cursor has its full contrast again and it is doing its sketched blinking.
2)The cursor continues to blink, when the "print" commands should be executed. So, basically there is a 10sec blinking cursor instead of 5sec blinkiblinki and a 5sec "HALLO".
3) When I pull any of the orange "Data" wires during sketch execution, the cursor continues to blink until the current delay time is up, then the display goes blank. The cursor comes back when I plug the wire back in. It appears, that the pulling of the wire kind of "pauses" the execution of the sketch.
4) During the initial PIN identification phase, I had situations, where all kinds of different characters were displayed. That looked pretty promising and tells me that the character ROM worked then. I cannot recall, which PIN combinations caused these indications. At that time I had not figured out yet, that there is no R/W pin.

Any idea is welcome,
Thanks in advance

Am I a fool wasting X hours of my life just to get a used 5$ device back to use??

For practical purposes, yes but why stop now.

Its R/W is pulled to GND as default, otherwise I would not get along with just 10 pins.

Why not? The LCD itself only needs 14 pins and if you forgo the 8-bit mode you are down to 10. I suspect that it is DB0, DB1, DB2 and DB3 that are missing. On the other hand also getting rid of R/W gives you a free pin for the backlight if your device has one. Since you can see some activity on the screen I suspect that R/W is indeed pulled to GND.

You seem to be doing pretty well so far. Since it is a 16x1 display and you only have one IC blob you have correctly chosen to deal with it as an 8x2.

I think you will have a better chance of figuring things out if you remove everything from loop() and clean up setup().

#include <LiquidCrystal.h>

//LiquidCrystal lcd(RS, E, D4, D5, D6, D7);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);       // put your pin numbers here

void setup()
  {
  lcd.begin(8, 2);                           // put your LCD parameters here
  lcd.print("hello wo");
  lcd.setCursor(0,1);
  lcd.print("rld!");
  }

void loop()
  {
                                             // do nothing in 'loop'
  }

I hope I fulfill the quality standards with my post and don´t receive harsh critique like others before me.

I don't want you to be disappointed so next time try a copy and paste of your code (make sure to use a code box as I did) instead of a photo of your screen.

Don

Don, thanks for your reply

ok, I copy/pasted your code into the IDE. No change on the wiring. After the upload to the Arduino board initially I had a blank display. Then I turned the Poti to the lowest Resistance (CCW with +5V connected to the left leg) and I uploaded your sketch again. Then it became interesting: the display showed characters!!! Not "Hello World", just some weird character combination but something at least!
It changes a little bit every time I re-upload the code.

So, the character ROM is obviously not shot then!
But I have doubts now, that Pin 3 is the correct pin for VO "Contrast". Might it be a data Pin?
Any advice on how to continue from here?

Thanks for your assistance

So, while I am waiting for some response on my last post, I play with the Poti setting while the sketch is executed in a loop. No change in the wiring.
Here is the sketch copy/pasted from my IDE:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2);

void setup() {

// set up the LCD's number of columns and rows:
  lcd.begin(8, 2);     //is 16x1, adressed as 8x2
  lcd.setCursor(0,1);  //init right hand side
  lcd.home();          //back to start
  
}
void loop() {
lcd.setCursor(0,0);   //set cursor to the left side
lcd.blink();          //blink on the left side
delay(5000);          //blink for 5 seconds
lcd.print("Hello Wo");   //print left side "Hello Wo"
lcd.setCursor(0,1);     //go to right
lcd.print("rld!");      //print "rld" on right side
lcd.setCursor(3,1);     //set cursor 1 step right
lcd.blink();            //blink to the right of the words
delay(5000);            //do that for 5 seconds
}

Here is what I find:

When the Poti is on highest resistance setting (fully clockwise against GND, GND on the right leg):
The Cursor jumps to the positions where it is supposed to be and blinks there for 5 sec. It behaves as it is supposed to do. BUT: No characters are displayed at all.

When the Poti is on the lowest resistance setting, (fully counter clockwise against +5V):
The cursor appears to start some kind of random behavior. It jumps to some position, disappears and comes back in a different position, sometimes blinking, sometimes not. Random characters and solid squares appear and disappear.

When I slowly rotate the Poti back to HIGH, it never gets back to its behavior that I have described for the high setting. I have to reset the LCD by pulling +5V and plug it back in.

The contrast of the display does not change by the way, when I change the poti's resistance.
To me it is pretty obvious now that the wiring is wrong and that I have to find the correct pin for the contrast.

I will wait with that until I hear back from someone more knowledgeable than me. Maybe there is some smart procedure for HOW TO DETERMINE THE CORRECT PIN SETTING ON A NON-STANDARD LCD DISPLAY WITHOUT FRYING IT.

Don, I hope, you forgive me, that I played a little bit and posted, not waiting for your response first. But I bet that your next steps would go into a similar direction in order to narrow this down.

Thanks

I see that you replied back while I was writing this.

You don't want to do any kind of troubleshooting with any code in loop. You need a static situation to have any hopes of figuring out what is going on. I'm not going to spend much time reading what you observed, it's futile.

Many displays work acceptably with the contrast pin connected to GND so they could have dispensed with the contrast pin. See what I have written below about checking that out.

If there's no contrast pin then the 'extra' pin could be R/W or it could be GND for the backlight. In the latter case the backlight GND would likely be pin 9. Can you trace the wiring and see where it goes.

Here's what I wrote earlier.

But I have doubts now, that Pin 3 is the correct pin for VO "Contrast". Might it be a data Pin?
Any advice on how to continue from here?

Connect up only what you think are V+, GND, and contrast. With the pot at one end the display should be blank and at the other end you should see dark boxes on half of the screen. If this much works then you have identified pins 1, 2, and 3. You get the blank screen with the contrast pin at 5v with respect to GND.

You haven't said how you are interpreting the rest of the pins or if your display has a backlight (and if the backlight works if there is one). On second thought I see a resistor connected to pin 10 so I suspect that you do have a backlight, it is connected to pin 10, and that it works.

I would suspect GND, V+, Contrast, RS, E, DB4, DB5, DB6, DB7, and backlight in that order. From what I can see on your photos it looks as if that is the way you have them connected but I really can't tell if you got the data pins right since the orange wires are jumbled together.

With these displays problems like yours frequently come from wiring problems. The Chinese jumper wires are particularly notorious so I would check them out with an ohmmeter or by substituting them, one at a time, into your backlight circuit.

Don

From your descriptions and assuming it is wired the way you say it is and all the wires are good (lots of assumptions) it sounds like pin 3 is not Vo but a control line since adjusting the pot never affected the contrast.
So that leaves what is pin 3?
Pin 3 can't be R/W since you are doing things to the display.
In your first descriptions you got no characters, so that could mean that pin 3 is RS and the pot was biased twards ground meaning the LCD saw RS as low which would cause everything to be interpreted as commands.
If pin 4 were actually R/W instead of RS then the LCD would only accept instructions when the Arduino was attempting to send commands as it would be driving what it thinks is RS low but might actually R/W.

So it is possible that there is no contrast input, and the pins are:
GND, V+, RS, R/W, E, DB4, DB5, DB6, DB7, and backlight in that order.

There are some things you could check.
It should be possible to detect which pins are which but but I'm assuming it just didn't bring out the DB0 to DB3 pins.

For example, use weak pullups and attach them to the 7 data & 3 control pins.
(you could this in s/w on the Arduino using INPUT_PULLUP)

Right after powerup, Read each pin. Control pins will always float high.
The data pins will be driven by the LCD because

  • RW is high which means read
  • RS is high which means data not status
  • E is high which tells the LCD to drive the bus.

After power up, the device should be in 8 bit mode and driving the bus with the character at address 0
which will be 0x20 after a power up.
That means that DB4 to DB7 will be 0x2

While it is possible to be more sophisticated, it is easiest to each of these from a fresh powerup to ensure each step does not alter anything for other steps.

If you lower E, then DB4 to DB7 will change to all high since the LCD is no longer driving the bus.

If you lower RS then DB4 to DB7 will change to all low since the LCD is driving the status/address register on the bus and BUSY should not be set and the address will be zero from powerup.

If you lower R/W then DB-DB4 will change to all high since LCD is no longer driving the bus.

If you are doing it in s/w you can also drive the DB4-DB7 pins with something like 0x5 and hump E a few times.
If R/W is low, and RS is high you will see some characters on the display.

It shouldn't be that difficult to figure the pins once you do some probing and see the results.

--- bill

Don, Bill, thanks for both your replies,

following Don's advice from his last post, I have been looking for the correct Vo pin and it appears, there is none.
Just Pin2 gives me some adjustment of contrast when I put it on the pot, but that is my main +5V supply and should stay 5V all the time, right?
I get good contrast on 8 squares with just GND on PIN1 and +5V on PIN2.
Pin 10 provides good background light. So no trouble there.
The 8 squares on the left make sense, because the LCD is not initialized on the right row of 8.
Need to find the command lines for that.

So it is possible that there is no contrast input, and the pins are:
GND, V+, RS, R/W, E, DB4, DB5, DB6, DB7, and backlight in that order.

Bill, unfortunately this is not working. Would have been to easy! Looks like, the pin assignment does not follow the "standard" order. Also I would like to mention, that there is no Resistor R7 soldered to its spot on the LCD PCB. If R7 is associated with PIN 7, could that hint towards any special function of this PIN?
I think, I need to follow Bill's SW / probing route now.

Does anybody know, where I can find a reference sketch for the probing procedure Bill has explained in his post?
I would adjust it then for my needs.
I am not so firm yet with my coding skills. Just started recently with Arduino.

Thanks

Roland

solarwizzo:
Does anybody know, where I can find a reference sketch for the probing procedure Bill has explained in his post?

You are now off in a highly experimental area so you will have to write any s/w yourself.
I wrote a bunch of similar code in the hd44780 i2c backpack i/o library for auto pin detection, but that code won't work for you as it is for probing across an i2c interface using a PCF8574.
But the over concept is essentially the same.

--- bill

Also I would like to mention, that there is no Resistor R7 soldered to its spot on the LCD PCB. If R7 is associated with PIN 7, could that hint towards any special function of this PIN?

Could you elaborate on this R7 business for me?

Don

Could you elaborate on this R7 business for me?

If you look closely at the very first picture in my 1st post (the picture of the back side off the LCD display), you see 10 resistor spots, but at R7 there is no resistor soldered to.

Roland

Bill,
I am doing my first steps now to probe the pins via software.
I am not sure, if this is as you suggested.
Here is the sketch, that I have created:

// LCD Pin 1 is continously connected to Arduino GND
// LCD Pin 2 is connected to Arduino Pin D2 and used to switch ON and OFF the LCD
// LCD Pins 3-9 are the pins to be probed and connected to Arduino Pins D3-D9
// LCD Pin 10 is Backlight and continously powered with 4.2V
void setup()
{
  pinMode( 3, INPUT);     //Pins 3-9 to be probed are pulled High
  pinMode( 4, INPUT);
  pinMode( 5, INPUT);
  pinMode( 6, INPUT);
  pinMode( 7, INPUT);
  pinMode( 8, INPUT);
  pinMode( 9, INPUT);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  Serial.begin(9600);
  pinMode( 2 , OUTPUT);   //Pin 2 is defined as output to power up the LCD







  Serial.print("__Power off");  //The Initial status of Pins 3-9 is checked under 
  Serial.println();             // LCD power-off condition

  Serial.print("Pin3");
  Serial.print(digitalRead(3));
  Serial.println();

  Serial.print("Pin4");
  Serial.print(digitalRead(4));
  Serial.println();

  Serial.print("Pin5");
  Serial.print(digitalRead(5));
  Serial.println();

  Serial.print("Pin6");
  Serial.print(digitalRead(6));
  Serial.println();

  Serial.print("Pin7");
  Serial.print(digitalRead(7));
  Serial.println();

  Serial.print("Pin8");
  Serial.print(digitalRead(8));
  Serial.println();

  Serial.print("Pin9");
  Serial.print(digitalRead(9));
  Serial.println();

  digitalWrite( 2 , HIGH );         //Powers up the LCD

  Serial.print("Power on");         // Prints input values for Pins 3-9 during power-Up
  Serial.println();

  Serial.print("Pin3");
  Serial.print(digitalRead(3));
  Serial.println();

  Serial.print("Pin4");
  Serial.print(digitalRead(4));
  Serial.println();

  Serial.print("Pin5");
  Serial.print(digitalRead(5));
  Serial.println();

  Serial.print("Pin6");
  Serial.print(digitalRead(6));
  Serial.println();

  Serial.print("Pin7");
  Serial.print(digitalRead(7));
  Serial.println();

  Serial.print("Pin8");
  Serial.print(digitalRead(8));
  Serial.println();

  Serial.print("Pin9");
  Serial.print(digitalRead(9));
  Serial.println();

  digitalWrite( 2 , LOW );      //Turns the LCD off

  Serial.print("Power off");
  Serial.println();

  Serial.print("Pin3");           // Checks status of pins 3-9 after power-off
  Serial.print(digitalRead(3));
  Serial.println();

  Serial.print("Pin4");
  Serial.print(digitalRead(4));
  Serial.println();

  Serial.print("Pin5");
  Serial.print(digitalRead(5));
  Serial.println();

  Serial.print("Pin6");
  Serial.print(digitalRead(6));
  Serial.println();

  Serial.print("Pin7");
  Serial.print(digitalRead(7));
  Serial.println();

  Serial.print("Pin8");
  Serial.print(digitalRead(8));
  Serial.println();

  Serial.print("Pin9");
  Serial.print(digitalRead(9));
  Serial.println();

}

void loop()
{
}

Is this going into the direction that you were pointing?

As a result I get the following Serial Read out during the first run of the sketch right after an Arduino RESET:

__Power off
Pin30
Pin40
Pin50
Pin60
Pin70
Pin80
Pin90
Power on
Pin31
Pin41
Pin51
Pin60
Pin70
Pin81
Pin91
Power off
Pin30
Pin40
Pin50
Pin60
Pin70
Pin80
Pin90

As you can see, Pin 6 and 7 stay low during power UP, the rest goes high.

Any advice on all this? Does this code and its result make any sense?

Thanks,
Roland

That is in the direction. I would put in at least a 100ms delay when powering down and again after powering up.

Bill, I understand, the delay command should be right after the HIGH command for PIN2, right?

And a HIGH PIN on the readout would point towards a Control Pin, right?

So, I can use this procedure to identify the Data pins, because they would stay LOW after power up?

I will put in some delays now, see what happens.

Thanks

It isn't really quite that simple. all of this is based knowing how the hd44780 pins work
(see the hd44780 datasheet for the full description)
The concept is this:

  • A pin that is a hd447890 control line is never driven by the LCD so it will always be high when a pullup is attached.
  • data lines can be high or low depending on the state of the data bus.

The LCD drives the bus when E is high and R/W is also high.
What the LCD drives on the data pins depends on the R/S signal and the internal state of the LCD address register and its internal RAM.

You can use the combination of all that information to determine which pins are which.
But you have to be careful when driving pins since you don't want to be driving a pin that is hooked up to a LCD data pin, when E and R/W are high.
That creates a short that could damage the AVR or the LCD.

It comes down to careful deduction based on knowing how the part works and being very careful which pins to drive.

--- bill

Hey, Bill
I understand that this is much more complex than it looks like on the first glance.

If I can determine one or two of the control pins by this method, I have a start.

I have one pin, that is always low after power-Up. It is the only one, no matter how long the delay is. I tried delays of 100ms up to 700 ms in 100ms steps, and there is always PIN7 indicating low.

Might that hint towards a special purpose of this pin?

Roland

delaying for an amount of time doesn't not affect the signal level observations as long as you initially wait beyond certain times like slew rates and the time it takes the LCD to drive the bus and that is in the 100ns range.
And anything you do using arduino or by hand will be WAY longer than that so things will not be changing by waiting.

The only reason I mentioned doing any delays is that you have to wait a little bit after powerup to give the LCD time to initialize itself and if you lower/raise what you think is a control line you need to wait at least 500ns to ensure that the LCD has time to react should that signal be a control line.
Things like digitalRead()/digitalWrite()/pinMode() are so slow on AVR based arduinos that you won't have to worry about anything but the powerup delay.

It isn't necessarily super complicated, but it does require using information from the hd44780 spec about how the hd44780 chip works to safely flip signals to be able to observe signal changes on the pins.
i.e. you have to have very good grasp as to how the hd44780 signals work RS, R/W, E in order to be able to do this.
It depends on the state of the control lines as to if the LCD drives the data lines and what it drives them with.
The reason to use pullups rather than driving signals is to ensure that control lines are all held high and data

You have to combine the knowledge of how the hd44780 control and data lines works along with observations to be able to determine which pins are which.

--- bill

Bill,

Yes, you hit the point. I have no clue, how the HD44780 works.
So, I am stumbling through fog here.

BUT:
I just got the LCD to work with the original logic board, where it originally was attached to. It came out of a CriCut digital cutting machine. Kind of a little CNC machine. Would it be helpful to measure the output pins from that board GOING to the LCD in order to find out what function of each pin might be?

It starts up with a fixed display routine when it initializes that logic board.

Can I read the values of those pins when I connect the board GND to ARDUINO GND in order to have a common?

Then read all pins either digital or analog.

I would write a sketch, which runs in the loop and reads each PIN value every 10ms or so during the startup sequence.

Would that be a way with less fog?

solarwizzo:
I just got the LCD to work with the original logic board, where it originally was attached to.

Well at least you know that the display still works.

Can I read the values of those pins when I connect the board GND to ARDUINO GND in order to have a common?

Then read all pins either digital or analog.

I would write a sketch, which runs in the loop and reads each PIN value every 10ms or so during the startup sequence.

You would need something MUCH faster than an arduino to read the pins.
Updates to the pins could be occurring in under 1us in certain cases.
There is no way you could read the pins fast enough with the AVR, especially using arduino code which is pretty slow doing reads from pins. Arduino on the AVR at 16Mhz takes around 6us to read a single pin.
If you had a logic analyzer, you could hook it up to all the pins and look at the trace. Knowing how the hd44780 signals work it would then be possible tell as the logic analyzer could sample the pins MUCH faster like every 40ns or possible even faster and the entire initialization sequence of all the pins would be there shown sampled all at exactly the same time in realtime as it was occurring.

--- bill

Ok, I understand that.

So then I should look into purchasing a logic analyzer. This would be a useful investment for any future project involving electronics - not just this LCD. And I really would like to get into this.

Any recommendations for a good quality Mac compatible device under $50?

Roland

Saleae 8 channel logic analyzer.

Or Analog Discovery, logic analyzer plus.

Analog Discovery 2, just a little more.