LCD from Axman

I wandered through Axman (you can imagine) last week and saw they had some LCD panels. I bought one out of curiosity and today I soldered headers on and tried it out. It seems to be significantly slower than anything I've tried before. Interesting experience after having played with quite a variety of different LCDs to find one that seems so far off the specs of the others.

Running the test program that I've used in writing the enhanced LiquidCrystal, it displays garbled output for a long time, then eventually seems to sync properly and start displaying output that makes sense. This is quite reminiscent of the 16x2 LCD that was a LITTLE slower than all the others I have tested.

I could see that it was dropping a couple of characters after clear, and I increased the delay after clear() from 2000 millisec to 2500 which solved that. I did the same for home().

Running it without a busy test and with delayMicroseconds(100) was problematic and things seemed to improve when I increased that to delayMicroseconds(140).

I've increased the delays in the initialization several times without success yet; it still displays garbled output for a few seconds after startup despite doubling some of the delays. Anyway once it does sync, several seconds after it should have started, it does work perfectly.

The on the back it says "Hyundai Korea HC 20401". rather than round bumps (as most LCDs have) you can see the ICs; the controller chip says 4L3 HD44780A00. it is a 20x4 display.

I've increased the startup delays

 // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
 // according to datasheet, we need at least 40ms after power rises above 2.7V
 // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50
 delayMicroseconds(60000); //I don't think I can adequately test this number; it will depend a little on which Arduino or clone you have and probably
                           //could also vary with the power source applied to that board. The way to test is really to load your program, remove power
                           //and then reapply power so that the program starts up as power is applied. If anyone finds they need a larger number please
                           //let me know: raine001 at tc dot umn dot edu
 // Now we pull both RS and R/W low to begin commands
 digitalWrite(_rs_pin, LOW);
 digitalWrite(en, LOW);

 //put the LCD into 4 bit or 8 bit mode
 if (! (_displayfunction & LCD_8BITMODE)) {
   // this is according to the hitachi HD44780 datasheet
   // figure 24, pg 46

   // we start in 8bit mode, try to set 4 bit mode
//at this point we are in 8 bit mode but of course in this interface 4 pins are dangling unconnected and the values on them don't matter for these instructions.
   write4bits(0x03,LOW);
   delayMicroseconds(7000); // I have one LCD for which 4500 here was not long enough.
   // second try
   write4bits(0x03,LOW);      
   delayMicroseconds(300); // wait 
   // third go!
   write4bits(0x03,LOW); 
   delayMicroseconds(300);
   // finally, set to 4-bit interface
   write4bits(0x02,LOW);

without success yet. An interesting experience and I hope somewhat instructive even if not further solved.

Hmm, interesting. Not sure about that. Was it cheap? Maybe not such a great buy. I have only seen a few displays with the ICs visible on the back and they were not HD44780 displays...

Mowcius

it was $5.95. If it helps me make LiquidCrystal more bulletproof it will be an especially valuable purchase.

Yeah.

Mowcius

While doing yardwork, I thought of this which along with what I posted before seems to work:
begin() calls the initialization routine. I followed the first begin(20,4); with another one. that seems to do it.

When I get time I will fiddle with the delays and see if they can be shorter.
Another thought I had along the same lines was to add extra, optional arguments to begin; those would be the various delays and default to what we have had. I like that idea; it would make it easier for people to advise struggling newbies with goofy displays.

playing with it some more, the double begin is not a panacea.

when I use an interface with a busy flag test the benchmark comes out at 521 milliseconds vs 432 for my other 20x4 display. so its almost 25% slower. It takes a LONG time to finally sync and start showing valid character data with the busy test. I'd estimate 6000 to 8000 characters were sent before it finally straightened out.

Before I switched to the busy flag test I noticed that when I wrote to the screen quickly in right-to-left mode, some text was getting mispositioned. I think that's showing me that my delay after sending a character still wasn't quite long enough. That mispositioning of text is not a problem using the busy flag test.

I played with it some more this morning. I did create a version of LiquidCrystal with more parameters on begin(), which speeds up the cycle of experimentation. Once it has synchronized, the delay per character/command (which is 100microseconds in the standard LiquidCrystal) needs to be over 300. 320 seems to work reliably. Below 300 a few characters get garbled or misplaced.

However playing with the delays in initialization has not been very fruitful. Even a 20 fold increase does not seem to get reliable startup.

It would be tempting to think that I have a weak signal somewhere but every single pin in the interface gets manipulated during busy flag testing and that is rock solid once the display synchronizes.

I haven't played more with the delay after clear and home. 2500 vs the standard 2000 seems to work, I see no more evidence of dropped characters after those commands. It seems odd that the ratio 1.25 seems to have been enough.

//This version of begin can specify 320 microseconds between character, 12000 microSecond pause in first step of init, 5000 microSecond pause in the next two steps
// I did not put in adjustments for the pause after clear and home or for the powerup delay. yet.
      lcd.begin(nColumns,nRows,LCD_5x8DOTS,320,500000,5000);
//       lcd.begin(nColumns,nRows,LCD_5x8DOTS,350,25000,1000);

http://healthriskappraisal.org/LiquidCrystalAxmanbegin.zip

John:

From your original post:

I wandered through Axman...

Since Axman deals in industrial surplus it is possible that they got a bunch of devices that were rejected by some OEM because of a speed problem.

Running the test program that I've used in writing the enhanced LiquidCrystal, it displays garbled output for a long time, then eventually seems to sync properly and start displaying output that makes sense.

I can't see how this behavior would result from an LCD initialization problem since that type of problem wouldn't be cured by the passage of time - unless your test program reinitializes the LCD mudule each time around.

I could see that it was dropping a couple of characters after clear, and I increased the delay after clear() from 2000 millisec to 2500 which solved that. I did the same for home().

If the LCD clock frequency is running at it's lower limit of 190 KHz then the required delay for 'Clear display' and 'Return home' becomes (1520*270)/190 = 2160 uS. Assuming that the times in the above quote were microseconds (you said milliseconds) then your results are consistent with the datasheet specifications.

A 60000 uS (60 mS) startup delay may not satisfy the datasheet requirements of 40 mS after Vcc rises to 2.7v - it all depends on your power supply. Also, remember that this specification was written when the host microcontrollers were running at 1 - 4 MHz, sometimes with 4 or more clock cycles per instruction. It's a lot easier for current microcontrollers to outrun the LCD controller. There really is no reason to try to speed up the library by fiddling with the delays in the initialization routine since that routine is only run once.

AhHa--
I don't see a time delay after the final 'Function set'. There's none shown on the data sheet flowcharts either but that is clearly an error. How could the LCD controller perform this instruction in less time than any of the other instructions, all of which require at least 37 uS. I would use 300 uS here as you did for the previous 'Function set'.

Don

I can't see how this behavior would result from an LCD initialization problem since that type of problem wouldn't be cured by the passage of time - unless your test program reinitializes the LCD mudule each time around.

This is what I saw with the slightly slower 16x2 as well. I think things are not quite synchronized and eventually it happens on some combination of bits that is (misinterpreted but) randomly completes whatever portion of init didn't get done correctly.

I will tried adding a terminal delay to init. With no effect.

 // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
 // according to datasheet, we need at least 40ms after power rises above 2.7V
 // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50
 delayMicroseconds(60000); //I don't think I can adequately test this number; it will depend a little on which Arduino or clone you have and probably
                           //could also vary with the power source applied to that board. The way to test is really to load your program, remove power
                           //and then reapply power so that the program starts up as power is applied. If anyone finds they need a larger number please
                           //let me know: raine001 at tc dot umn dot edu
 // Now we pull both RS and R/W low to begin commands
 digitalWrite(_rs_pin, LOW);
 digitalWrite(en, LOW);

 //put the LCD into 4 bit or 8 bit mode
 if (! (_displayfunction & LCD_8BITMODE)) {
   // this is according to the hitachi HD44780 datasheet
   // figure 24, pg 46

   // we start in 8bit mode, try to set 4 bit mode
//at this point we are in 8 bit mode but of course in this interface 4 pins are dangling unconnected and the values on them don't matter for these instructions.
   write4bits(0x03,LOW);
   delayMicroseconds(_delayFirst); // I have one LCD for which 4500 here was not long enough.
   // second try
   write4bits(0x03,LOW);      
   delayMicroseconds(_delaySecond); // wait 
   // third go!
   write4bits(0x03,LOW); 
   delayMicroseconds(_delaySecond);
   // finally, set to 4-bit interface
   write4bits(0x02,LOW); 
   delayMicroseconds(_delaySecond);
 } else {  
   // this is according to the hitachi HD44780 datasheet
   // page 45 figure 23  -- this is 8 bit mode

   // Send function set command sequence
   command(LCD_FUNCTIONSET | _displayfunction);
   delayMicroseconds(_delayFirst);  // again, one LCD I have needed more than 4500

   // second try
   command(LCD_FUNCTIONSET | _displayfunction);
   delayMicroseconds(_delaySecond);

   // third go
   command(LCD_FUNCTIONSET | _displayfunction);
   delayMicroseconds(_delaySecond);
 }

I varied _delaySecond up to 650. If that is needed there, it belongs in every version of LiquidCrystal back to Arduino 17, I think.

The 60000 delay isn't really being tested; I'm rarely removing power between tries and have been using the bootloader.

I hadn't realized there was a lower limit for LCD clock frequency before. so usually they run at 470 and can run as low as 190--less than a factor of 3?

I hadn't realized there was a lower limit for LCD clock frequency before. so usually they run at 470 and can run as low as 190--less than a factor of 3?

They nominally run at 270 KHz but they can range from 190 to 350. Info is in the 'AC Characteristics' on p.52 of the datasheet. I assume that most LCD modules are set up to use the internal oscillator as per note 12.

If that is needed there, it belongs in every version of LiquidCrystal back to Arduino 17, I think.

Why wouldn't a delay be needed there? The delay would have been needed in the earlier versions also except they didn't bother with the software initiailization (those versions didn't work very reliably either).

Did you tinker with the initial 60 mS startup delay at all?

Don

I made 3 changes all at once when I had the slightly slow 16x2:

I increased the power up delay from 50 to 60 millisec. really more on the general principle that the comments surrounding it made me think it was less than it should be rather than based on anything I actually demonstrated.

I increased the first delay from 4500 to 5000(_delayFirst); that is what fixed the 16x2, I think

The delay I decreased was the first 150 (_delaySecond in my current code. that was 4500 in Arduino 17 and 18; based on everything I could figure out it was a mistake. I made that change at the same time I increased the delay before it from 4500 to 5000.

There was one more relevant change to timing. write4bits in Arduino 17 and 18 had the pause between characters, so that it paused between each nibble. So that IS a significant timing change. But the delay got moved in FRONT of sending the next character/command, rather than behind it when I first implemented busy flag testing. I think that is a wash.

Bear in mind, before I posted LiquidCrystal440 or the version with the user busy test I went through a thorough testing procedure. I didn't do that yesterday when I posted the Axmanbegin version. The testing procedure involves testing each LCD: 16x1 (=8x2), 16x2, 16x4, 20x4 and 40x4 against each interface it might use so the 16x4 is tested against 4 bit with and without RW and also 4 bit with busy test and 8 bit with and without RW. So five interfaces get checked against each of the 1 chip LCDs. 3 interfaces (RW set to 255 or not and user busy) for the 40x4. And the test program puts them through every subroutine inside LiquidCrystal and tries to demonstrate every problem I've found. It does the 'benchmark' which for a 20x4 involves about 3200 characters as fast as it will go.

The startup routine gets checked then 23 times against 5 different LCDs and is solid for all of the LCDs I bought through ordinary channels. The only time the 60000 startup delay gets 'tested' though is sort of casual: when I switch from one size LCD to the next, I pull the USB cable out of the computer, pull the LCD out of the Arduino Mega, put a different size LCD into the Arduino and then plug the USB cable back into the computer. At this point the Mega starts to run what is in flash RAM, which is code for the wrong size LCD. If I was testing the 16x4 and move to the 20x4, that looks pretty reasonable, for most of the other options it looks pretty strange. But just seeing characters that make a little sense showing up on the screen before the code for the appropriate sized display compiles and uploads is a demonstration that the initialization succeeded.

The code really is very thoroughly tested and successful with every other LCD I've had. I'm beginning to think that the controller chip on this one might have a flaw in addition to just being slow.

John:

How well do you know the guys at Axman? If you explain the problem they might let you try out a few similar devices. You will have to devise a way to connect them without soldering - perhaps a male header wedged in at an angle (assuming the module has plated through holes).

There used to be at least two stores like Axman in Rochester (NY). I know that one of them is now out of business but I am not sure about the other. Of course when I was a kid there was "radio row" on and around Cortlandt Street in NYC. The area was demolished in the early 60s to make way for the World Trade Center.

Don

I don't have a problem with picking up a couple more to test; they are cheap and actually fairly nice displays once they sync. If I don't get it done tonight it will be at least a week, though.

I did briefly test another one tonight. It acts just like the first one.

Which Axman did you buy the LCD form?

I did briefly test another one tonight. It acts just like the first one.

That's interesting. Maybe you just stumbled across the 'worst case' for your LCD tests.

Don

It was the Axman near University and Snelling. I think they had several hundred of them. I've also been in the Fridley store in the last few wks and they seemed only to have a few.

The trouble with it being the worst case, which it seems to be, is that I've juggled the delays every which way, it seems to me. At least with the first LCD.

Maybe I can think of a more structured way to test the delays. I suppose with the axman begin I can have the sketch systematically try delay numbers and signal with a button that it hasn't worked, to go on to the next test delay numbers.

Anyway I will be away from this for a week at least.

I suppose someone has tried to walk through US airport security with an Arduino in their hand luggage at some time. I wonder what the chances are?