Looking for an LCD program

hbl2013

Senior Member
Has anyone written a program driving a standard LCD in a 4 or 8 bit mode? I like to get the actual program listing, not how to do it. I have written several versions for it running on the 28x2 and 40x2 chip, and I can not get it to work. I need an actual listing so that I can compare my program with a program which is known to work, so that I can find out if it is a software or hardware problem.
NOTE: To make sure that the LCD I am using was OK, I substituted the exsisting LCD in a commercial product with the one I have, and it worked there as intended.
Any references or suggestions are appreciated.
 

westaust55

Moderator
Yes there are many examples on this forum for 4 and 8 bit code posted by others.

Have you tried a forum search or looked in the Finished Proejcts area?

PICAXE forum member marks is one that come to mind having posted a range of LCD driver code for 4 and 8 bit interface.
Here is just one thread: http://www.picaxeforum.co.uk/showthread.php?19474-Learning-to-Drive-an-LCD-DISPLAY

Why not post your own code as developed thus far here so that folks can review and help you correct/modify what you have started.
There are many ways to impliment the LCD interface so available code examples may not match your method and your own code may not be far from working.

Do you know which controller chips is used for your LCD module? That may have a bearing on which code example to look at.
Even knowing which pins are being used from the PICAXE for the interface is needed for code structure.
 
Last edited:

inglewoodpete

Senior Member
One of the problems with parallel-connected LCD programs is that there are many ways to interconnect the pins of the LCD to the pins of the controller chip. Most designs that are posted on the forum require strict adherence to the hardware layout that the particular poster used.

A few months ago, I posted this 4-bit LCD software design that offers a more flexible approach for interconnecting a PICAXE with a parallel LCD.
 

hbl2013

Senior Member
Thanks for the replies, it gave me some material to look at. I looked at the program from inglewoodpete and it looks like that it is what I was looking for. I too, am using the 28X2 and the B and C ports as the output leads. Only I do not quite understand why the B1 lead is used as the LCD D4 driver. I used the B.4 for that, it makes outputting the data so much easier. Thus that is my change to the program; otherwise it fits my hardware perfectly. I will see if it works in a few days.

BTW In 1997 a fellow named Julyan Ilett wrote a couple of articles in a Magazine called "Everyday Practical Electronics" were he described a method to program LCDs without a Computer using 9 switches and a push-button to generate all the data necessary to get an LCD working. I build one of these, but used HEX switches instead of seperate data switches, and it works like a charm. Slow to use, but it is good enough to check unknown LCDs if they are working or not without the use of an uP.
 

John West

Senior Member
I'm still curious to see hbl2013's original code. I'd like to see where he/she went wrong so I don't make the same mistake.
 

westaust55

Moderator
Thanks for the replies, it gave me some material to look at. I looked at the program from inglewoodpete and it looks like that it is what I was looking for. I too, am using the 28X2 and the B and C ports as the output leads. Only I do not quite understand why the B1 lead is used as the LCD D4 driver. I used the B.4 for that, it makes outputting the data so much easier. Thus that is my change to the program; otherwise it fits my hardware perfectly. I will see if it works in a few days.
.
I suggest that IWP had provided his code as an example of being more flexible and not having all the 4 data lines on consecutive pins where it is possible to consider options for simpler but more specific (less universal) code.

Such an arrangement as per IWP's code is useful for example if using a 14M2 where the i2c clock and data lines are using pins B.3 and B.4 thus using B.0 or B.1 for one of the LCD lines makes sense.
For the 18M2 it would make seance to avoid B.1 and B.4 to keep the i2c bus available.
Likewise avoiding B.5 and B.7 with the 20M2.

So having now taken IWPs code and found that works, have you gone back to determine what exactly was wrong with your own code as a learning case? As suggested it can be worthwhile as a part of the learning process to put your own code forward rather than hide it from scrutiny.
 

inglewoodpete

Senior Member
I purchased a cheap LCD shield from DealExtreme and then fitted it to the AXE401 PICAXE shield. Put simply, the pins were all over the place. I had a look at the Ar***o driver for it and saw that each pin was mappable. Hence, the idea for a "universal" piece a software for the PICAXE.
 

hbl2013

Senior Member
Only I do not quite understand why the B1 lead is used as the LCD D4 driver. I used the B.4 for that, it makes outputting the data so much easier.
Sorry, I wrote this without really reading the comments. I DO understand now why inglewoodpete did that when I looked closer at those. But since I am using the 28X2 and 40X2 ships only, I changed it.
Also, I am planning to change the write command to the following code to take advantage of the SHIFT instruction of the X2 parts:

'Assuming the LCD DATA leads are connected to B4-B7

out_cmd:
Low oLCDRS

out_data:
b2 = b0
outpinsB = b0
pulseout oLcdEn, 2
b0 = b2 << 4 'shift LSB in MSB
pause 4
outpinsB = b0
pulseout oLcdEn, 2
High oLCDRS
pause 4
Return

And here is the code that did not work. Connections are for an New Haven 8 BIT LCD connected to the B0-7 port. There are a few things that do not show but I tried later on, with no success.
1. using a reset code of $38 three times at the start and
2. using the PULSEOUT instruction instead of manually manipulating the E lead.
Also I understand that by sending an $0F as the very first command, you should see a Cursor with Underline flashing on your LCD and know that everything is working as it should. That did not happen in my case.
I am not even sure that the following program is the one I ended up with. I changed things in an attempt to get it working. But here it is


#rem
FILE: New Haven LCD.bas Version 1.0
This is the program for the New Haven C0220AU LCD
---------------------------------------------------------------------------

This uses the PICAXE 40x2 chip
----------------------------------------------------------------------------
#endrem

'Following is associated with the LCD Pin Outs Pin4 - Pin14

symbol rs = D.0 'Mode H=Cmnd, L=Data
symbol rw = D.1 'R/W = High/Low
symbol e = D.2 'enable

'Init Codes of LCD = 3C-0E-01-03
'2line/5x10--displ ON,cursor OFF,blink OFF--Clear Displ--Increment,shift ON

symbol code1 = 0x3c
symbol code2 = 0x0e
symbol code3 = 0x01
symbol code4 = 0x03

'Following is the data to be displayed

symbol digit1 = 0x31 '1
symbol digit2 = 0x32 '2
symbol digit3 = 0x33 '3

'---------------------------------------------------

'PORT assignments

dirsB = 0xFF 'LCD 8-Bit DATA Port
dirsD = 0xFF 'LCD Control Port

outpinsB = 0xFF 'all LCD Data=High
outpinsD = 0xFF 'all LCD Control Lines=HIGH



'-------------- We are starting here --------------------


'intialize LCD 3X

for b0 = 1 to 3
b1 = code1
gosub out_cmnd

b1 = code2
gosub out_cmnd

b1 = code3
gosub out_cmnd

b1 = code4
gosub out_cmnd

pause 50
next


main:
high e
high rs
b1 = digit1
gosub out_data
pause 5
b1 = digit2
gosub out_data
pause 5
b1 = digit3
gosub out_data
pause 400 'wait
goto main 'and do it over again


out_cmnd:
low rs

out_data:
outpinsB = b1
pause 1
low e
pause 2
high e
pause 3
return

end
 

westaust55

Moderator
Your original 4-bit initialisation was sending the sequence:
$3C, $3C, $3C, $0E, $01, $03

Whereas the usual 4-bit intialisation uses the data sequence:
' Nibble commands - To initialise 4-bit mode (as an extract from hippys old website)
Code:
$33 ; %0011---- %0011----   8-bit / 8-bit
$32 ; %0011---- %0010----   8-bit / 4-bit

 ' Byte commands - To configure the LCD
$28 ; %0010 1000 ==> %001L NF00   Display Format
                           ; L : 0 = 4-bit Mode  1 = 8-bit Mode
                           ; N : 0 = 1 Line      1 = 2 Lines
                           ; F : 0 = 5x7 Pixels  1 = N/A

$0C ; %0000 1100  ==> %0000 1DCB   Display On
                            ; D : 0 = Display Off     1 = Display On
                            ; C : 0 = Cursor Off      1 = Cursor On
                            ; B : 0 = Cursor Steady   1 = Cursor Flash
$06 ; %0000 0110 ==> %0000 01IS   Cursor Move
                            ; I : 0 = Dec Cursor      1 = Inc Cursor
                            ; S : 0 = Cursor Move     1 = Display Shift
$01 ;                                            Clear Screen
You need to follow the sequence as given in the Hitachi HD44780 LCD controller datasheet


Edit:
seems that New Haven LCD module uses an NT7606 controller chip. Datasheet available:
http://www.newhavendisplay.com/app_notes/NT7605.pdf

Most commands appear to be same as the Hitachi chip. The 4-bit initialisation appears differnt on page 25 but I suspect the Hitachi sequence will work
 
Last edited:

John West

Senior Member
Thanks for the code troubleshooting, Westy, and Pete. In addition to helping hbl2013 solve a problem, it's helping me get more comfortable with these LCD's and their drive code.
 

inglewoodpete

Senior Member
Sorry, I wrote this without really reading the comments. I DO understand now why inglewoodpete did that when I looked closer at those. But since I am using the 28X2 and 40X2 chips only, I changed it.
Also, I am planning to change the write command to the following code to take advantage of the SHIFT instruction of the X2 parts:
I would recommend using 4 or 8 consecutive pins where ever possible. I have explained the reason why I wrote the "universal" code: I had to. I shared it with the forum because one of the most frustrated questions asked is "Does my LCD module work?". I have the patience (it may not always be obvious!!) to spend many hours debugging both hardware and software - I have been in the microprocessor/microcontroller game for over 30 years and can work most things out given enough time. However, many newbys are not so confident and are at risk of giving up if their LCD does not work in the first couple of hours.

8-bit mode is simpler to use than 4-bit mode but uses more PICAXE pins and therefore is more expensive.

With the right code and the right PICAXE chip you can write all 32 characters (16x2) in under 20mS using a 4-bit bus. That's around 50Hz or 50 complete screen updates per second. I'm currently developing a combination high speed serial (up to 115200 bits/s) and i2c (100kbits/s) interface to Rev-Ed's Winstar 16x2 OLED module. I'll publish the details when I complete the project, hopefully in the next couple of weeks.
 
Last edited:

westaust55

Moderator
8-bit mode is simpler to use than 4-bit mode but uses more PICAXE pins and therefore is more expensive.
Also from some speed tests done by forum member marks (see an earlier link I provided in this thread) using 8-bit only achieves around 17% speed improvement if the code is written well, otherwise might achieve up to 38% improvement over 4-bit interfacing.

So doubling the data-bus width may not achieve a 50% speed improvement let alone a doubling of the data transfer rate.
 
Last edited:

hippy

Technical Support
Staff member
It's very difficult to compare the merits of contiguous 8-pin buses, contiguous 4-pin buses, and arbitrary 8-pin or 4-pin buses for LCD control.

In terms of speed, and disregarding complexity of use, that is the best order of choice for speed - I measured using a contiguous 8-pins at about three times faster than contiguous 4-pins and about five times faster than any arbitrary pin allocation.

For most programmers however, particularly those unfamiliar with LCD and even for those who are, it is not purely about speed but ease of use. It is much easier to have LCD control through subroutine calls to simplify achieving what one wants to do while limiting complexity of implementation to within those subroutines. That adds overhead and in turn makes the gains of various mechanisms less in terms of the whole. Thus the gains are rarely as great as they could potentially be as Westaust55 alludes to.

In fact, given the advantage of SEROUT in requiring a single I/O pin, ease of use and '#' number formatting, programmers can use an AXE033, AXE133 and the like without losing out. There are some circumstances where direct parallel control of an LCD can be better than serial control but it's far from an absolute that parallel control is better than serial control. In terms of simply wanting to use an LCD it often does not matter what type of bus one chooses, they will all get the job done and none will stand in the way of that.

If one wants to have fastest speed for whatever reason then it does start to matter what pin allocations are used and the faster the speed sought the more care has to be put into allocating pins to use, and the greater the skill required to do that. And, depending upon what one wants, it may not be easy to provide what is needed so one may be stuck with best compromise; for example you can't have a contiguous 8-pin bus if a couple of those pins are required for I2C or other use. Likewise tracking issues may dictate an arbitrary pin allocation as was the case for inglewoodpete.

There are a huge number of ways to handle parallel LCD driving, both simpler and more difficult to use, and using a variety of pin allocations. There is no solution that is simplest and fastest at the same time so it's always a trade-off. My own feeling is that it doesn't really matter and worry over what is best and implementing a more complicated system is often wasted effort.

My rule of thumb is to use the simplest to get things working and optimise afterwards if required. My recommendation would be start with arbitrary pin allocations as that will always work.
 

hbl2013

Senior Member
Most commands appear to be same as the Hitachi chip. The 4-bit initialisation appears differnt on page 25 but I suspect the Hitachi sequence will work
As I noted, I just showed one program I used, but I tried many different codes to initialize the LCD. I looked at the specs for the LCD in question for the correct ones, and but I still could not get it to work.
The reason that I posted this thread is that I wanted to know if my general software approach was correct, and if not, what to do to correct it. For that reason I wanted a working program, I could always modify it to fit my hardware. inglewoodpete gave that to me, and I am in the process to implement his program as is to start with. By all reasoning, everything should work then as it did for him. If not, I have a hardware problem and can work on that, but at least I do not have to question the software.

What frustrates me is the fact that I successfully have programmed LCDs many times in the past for at least 4 different uPs and in 3 different languages, but I am new to the PICAXE. I am still learning how to use its BASIC and the implications of its instructions, which are not always immediately apparent.
 

marks

Senior Member
Hi hbl2013,
I havent played with the 40x2 much but briefly wrote a 4bit program forit -post#32
http://www.picaxeforum.co.uk/showthread.php?19474-Learning-to-Drive-an-LCD-DISPLAY/page4
interesting need to add a pause in to initialise as the 40x2 was alot qicker than a 20x2 and a 18m2 which is slower again
I know the post has become a bit of a mess lol.from memory the home and clear commands need a bit more time
post #31 also a good example
i'm sure these can be improved upon but just a matter of checking timings and different speeds.
 
Last edited:

glens

New Member
Hi, I hope this is not off topic; but I recently used the "spare pins" of a 40x2 (18F45K22) running at 16 MHz on 3V to drive an LCD from a Nokia 3315 phone. The only pins available for driving the lcd were A.3,A.5,A.6,A.7 & C.3. Despite checking all the obvious (shorts, o/c parasitics etc), all lines were cleanly switching between Vcc & Vss, sclk/ sda timing seemed sensible. I swapped the 40x2 for another, inserted pauses in the lcd write stubs, slowed the clock, etc all to no avail. I confirmed the hardware and basic code integrity by lashing up a 28x2 in place of the 40x2 and connected it's B.0 - B.5 to the 40x2's pins A3,5,6,7 & C.3 as above. The lcd worked with the 28x2, so I reinstalled the 40x2 & connected the LCD to C.3 to C.7, which worked on both 40x2's.. The point being that despite no visible differences in the waveforms on the scope etc, there may be advantages in trying another port if the lcd isn't working. The code was patched together from something that Hippy wrote for a 28x2 on this forum a while back. Hope this helps someone.
Regards, Glens
 

hbl2013

Senior Member
The point being that despite no visible differences in the waveforms on the scope etc, there may be advantages in trying another port if the lcd isn't working.
I am starting to think that is is the problem I was running into. I did not change ports as Glens did, thinking that the problem was in my software, but his expierence let me think that I should do so.
 
Last edited:

hippy

Technical Support
Staff member
The point being that despite no visible differences in the waveforms on the scope etc, there may be advantages in trying another port if the lcd isn't working.
I am starting to think that is is the problem I was running into. I did not change ports as Glens did, thinking that the problem was in my software, but his expierence let me think that I should do so.
I doubt you had the same problem and simply changing ports would have fixed things. It would be more likely there was something wrong with the code being used. For example, the code in post #9 would not work because it is not controlling E correctly.

Without knowing what the code was it's impossible to say whether it should have worked and, if it should have but did not, why not. The only thing one can do is to move forward and see what happens with the code that is currently being used where such an assessment can be made if required.

As to why glens' configuration did not work when it might have been expected to I guess that won't ever be known either.
 

hbl2013

Senior Member
For example, the code in post #9 would not work because it is not controlling E correctly.
Ah, finally a reply that I was hoping for! A comment as why my software did not work!
hippy, I thought that the LCD would process the code at the HIGH to LOW part of the pulse.
That is why I wrote it so that the pulse would go from HIGH to LOW and then back to HIGH again. Was that wrong?
 

hippy

Technical Support
Staff member
hippy, I thought that the LCD would process the code at the HIGH to LOW part of the pulse.
That is why I wrote it so that the pulse would go from HIGH to LOW and then back to HIGH again. Was that wrong?
I recall Datasheets usually have a requirement to set RS before raising E so raising E then changing RS would be out of spec operation. "Would not work" is perhaps over-stating things, but it's definitely not the order used in most LCD code which does work.
 

John West

Senior Member
LCD's are relatively slow in responding to commands, and the order of events and timing constraints listed in the datasheet must be followed. A simple logic-state analyzer can come in handy to determine if bits are actually changing in the proper order relative to each other. and with the proper timing requirements. These are the sorts of things that software simulations can miss, but actual measurements will catch. And occasionally, (especially with cheap knock-off devices,) the controller chips may not fully meet the timing requirements specified in the datasheet.
 

hbl2013

Senior Member
And occasionally, (especially with cheap knock-off devices,) the controller chips may not fully meet the timing requirements specified in the datasheet.
According to the specs of the New Haven Display I used, the shortest wait time in between code processing is 40us (Some Cntrl Mode codes) and is 1.64ms for the rest of the codes. It seemed to me that using a 2ms wait time would be then sufficient for any code in that case.
However, since this wait period is required to give the LCD time to process the code entered, the correct way of entering data is to monitor the BUSY lead and wait until it indicates that the LCD is ready to accept the next code. (Read the Data port with RS=0, RW=1, bit7 should be 0 when it is ready to accept data again) To simplify the code, programmers generally do not do so, but insert a suitable wait period instead of reading the port data and in most cases this will work OK.

BTW I recall reading somewhere that reading the BUSY lead is an good way to see if the codes indeed are being accepted, if they are not, the BUSY lead will never go to 0.
Hmm... So you could after some fashion make an Interrupt out of that lead and thus make sure that the timing is always correct that way?
 

inglewoodpete

Senior Member
There is no busy lead so there is no point using interrupts. However, there is a busy bit that can be read.

The relatively low operating speed of a PICAXE, even at 64MHz, means that the busy bit is almost always clear. If you poll the status of this bit, more processor time is wasted than can possibly be saved.

You are better off putting a short delay after the known slow commands (Clear and Home).

As hippy says, there is no mystery around using one or another port or pin: when configured correctly they all behave the same. The important part is to get the prerequisite pins in their correct states before pulsing the Enable (E) lead.

Obviously, getting the correct command sequence in place too: especially in 4-bit mode. If you miss sending all of the nibbles during initialisation, the LCD will be left out-of-sync with the microcontroller.
 

hippy

Technical Support
Staff member
According to the specs of the New Haven Display I used, the shortest wait time in between code processing is 40us (Some Cntrl Mode codes) and is 1.64ms for the rest of the codes.
Usually it's 40us for everything except for Clear Display and perhaps Cursor Home.
 

hbl2013

Senior Member
UPDATE- I used a program written by inglewoodpete some time ago, where he describes an Universal LCD Test Program.
I happen to have one of the STAMP 8x2 LCDs, which works fine with their program using a BASIC2x, and adapted his program to work with this LCD and a 40X2 chip. Since the original test sentence "Hello World!" is too long for an 8 character LCD, I split it in two, with the intention to display the word "Hello" on the first line, and the word "World!" on the second.
BTW - As written originally, the whole sentence appears on the 2X8 LCD, but it is scrolled by.
I can not, however, get the LCD to display any data on the second line. I was under the impression that every HD44780 based LCD has the same memory layout, regardless of how many characters can be displayed at one time. From the data published, I understand that all of them start with address 00 for the first line, $40 for the second, $10 for the third, and $50 for the fourth line, depending how many lines your LCD has. (You have to add $80 to this to be able to program the address into the LCD, so $40 becomes $C0 )
When I patch this information into the original program, only "Hello" will appear on the first line, but nothing appears on the second line. If I replace the $C0 with $D0, the word "Hello" is replaced by "World!" on the first line (?)
The question is, why is the 2nd line not working? What am I leaving out here?
Any comments anyone?
---------------------------
The program follows here:
Code:
(Some of the comments are left out to conserve space)
'Uses the PICAXE 40X2
'
' **** Pins ****
'
' 4-bit mode: Uses a total of 8 wires between the PICAXE and LCD:
'              0v, +5v, Register Select and LCD Enable
'              4 data wires: Pins 4 to 7 on the LCD
'
'  Note that the 4 data pins must be addressed in 2 two different ways
'
Symbol oLCDpin4   = outpinB.4   'B.4 for writing to the output pin directly 
Symbol oLCD4      = B.4
'
Symbol oLCDpin5   = outpinB.5   'B.5 for writing to the output pin directly
Symbol oLCD5      = B.5
'
Symbol oLCDpin6   = outpinB.6   'B.6 for writing to the output pin directly
Symbol oLCD6      = B.6
'
Symbol oLCDpin7   = outpinB.7   'B.7 for writing to the output pin directly
Symbol oLCD7      = B.7
'
Symbol oLCDRS     = C.1         'C.1 Register select: Low for Commands, High for Characters

Symbol oLCDEn     = C.0         'C.0 Enable pin. Default condition is low. Pulse High to input data.
'

'       EEPROM and Message Pointer

Symbol eMsg1  = 0
Symbol eMsg2  = 9
EEPROM eMsg1, ("Hello", 0)
EEPROM eMsg2, ("World!", 0)
' ************************************************************
' **** Test routine - Uses byte registers b0 and b1       ****                  
' ************************************************************
'
'  DO NOT CHANGE THE CODE LISTED BELOW! 
'  
Init:    'Initialise the I/O Pins
         Output oLCD4, oLCD5, oLCD6, oLCD7, oLCDRS, oLCDEn
         '
         'Initialise the LCD module
         Low oLCDEn                   '(Default value is low)
         Low oLCD7, oLCD6: High oLCD5, oLCD4   'Pattern %0011 ("Function Set")
         PulsOut oLCDEn, 2            'Pulse enable pin 3 times to initialise
         Pause 50                     'Minimum 4.1mS (all clock speeds)
         PulsOut oLCDEn, 2            '2nd Function Set
         Pause 4                      'Minimum 100uS (all clock speeds)
         '
         'Send a series of 8-bit commands to configure the LCD
         b0 = %00110010               '$32 3rd Function Set, then 4-bit data, 2-line display
         Gosub Cmd2LCD                '    Send the command
         b0 = %00001000               '$08 Reset Display to the selected mode
         Gosub Cmd2LCD
         b0 = %00001100               '$0C Turn the Display On with hidden cursor
         Gosub Cmd2LCD
         b0 = %00000110               '$06 Move the input (Ie "cursor") point after each character
         Gosub Cmd2LCD
         b0 = %00000001               '$01 Clear the Display
         Gosub Cmd2LCD
         Pause 35                     '~4mS Required to let LCD clear (all clock speeds)
         '
         'Now send a simple "Hello World!" message to the LCD screen on two lines
         
         b1 = eMsg1               'Point to the EEPROM Massage
         Read b1, b0                  'Fetch the first character
         Do                           'Loop through this code to send each character
            GoSub Chr2LCD             'Send the character to the LCD screen
            Inc b1                    'Move to next source location in EEPROM
            Read b1, b0               'Fetch the next character
         Loop Until b0 < " "          'Drop out of loop when first non-printing character is found
                                      ' (The space $20/32d/" " is lowest printable ASCII character)
'********************************         
         'Now instruct the LCD to go to the next Line

	 b0 = $C0			' Bit 7 should be a 1 - LCD DRAM position of the next line = $40 = % 0100 000, so final code is %1100 000 =$C0
	 gosub Cmd2LCD
	 pause 10
         'Display the next line
         b1 = eMsg2               'Point to the EEPROM Massage
         Read b1, b0                  'Fetch the first character
         Do                           'Loop through this code to send each character
            GoSub Chr2LCD             'Send the character to the LCD screen
            Inc b1                    'Move to next source location in EEPROM
            Read b1, b0               'Fetch the next character
         Loop Until b0 < " "          'Drop out of loop when first non-printing character is found
                Do: Loop
'
' ************************************************************
' **** Subroutine: Write a Single Byte to the LCD         ****
' ************************************************************
'
'         Two different entry points: Either send command or character to LCD
'         Registers Used: b0 must be used due to bit addressing
'
Cmd2LCD: Low oLCDRS                   'Point to command register (Otherwise defaults to character reg)
         '
Chr2LCD: oLCDpin4 = bit4              'High nibble is sent first
         oLCDpin5 = bit5
         oLCDpin6 = bit6
         oLCDpin7 = bit7
         PulsOut oLCDEn, 2            'Clock 4 high bits of data into LCD
         oLCDpin4 = bit0              'Followed by the low nibble
         oLCDpin5 = bit1
         oLCDpin6 = bit2
         oLCDpin7 = bit3
         PulsOut oLCDEn, 2            'Clock 4 low bits of data into LCD
         High oLCDRS                  'Next received byte defaults to displayable character
         Return
' ************************************************************
end
 
Last edited by a moderator:

inglewoodpete

Senior Member
Hi hbl, The answer is probably in the data sheet for your display. I've never used an 8x2 display so don't know the addresses. Maybe other forum members have.

I haven't refreshed myself by rereading the entire thread so the following is off-the-cuff: either the manufacturer or the retailer of your display should provide the proper documentation on your display module.
 

SAborn

Senior Member
When I patch this information into the original program, only "Hello" will appear on the first line, but nothing appears on the second line. If I replace the $C0 with $D0, the word "Hello" is replaced by "World!" on the first line (?)
Im not sure if i follow here, but the first line should be $80 or 128 decimal, and the second line should be $C0 or 192 decimal, i dont see where $D0 comes into use with a 2 line display.
 

westaust55

Moderator
$D0 would normally be 17 characters along on the second line of a 2-line display. Keep in mode for a 4 line display, line 4 is a wrap around for line 2.
For a 16 char wide displays there are usually several unseen chars before wrap over to line 2.
Like IWP I have not used any LCD with 8 char lines so cannot specifically advisee on that display format.
 

nick12ab

Senior Member
The character addresses for all the different sizes of LCD can be found here: PICAXE LCD Interfacing

The HD44780 can support 16 lines and 40 columns (8 characters per line on 2 lines) without an extension driver and these lines start at instructions 128 and 192. The LCD panel can be rearranged for 16 characters on 1 line to eliminate the need for an extension driver which means the addressing for a 16x1 LCD is a bit inconvenient. This does mean that an 8x2 LCD has the same character addressing as a 16x2 LCD.
 

hbl2013

Senior Member
Thanks fellows. Looking at the LCD info as recommended by nick12ab, I see that I was right, the second line of any HD44780 based LCD always starts at $40; thus it looks that my program is basically correct. The question is still, why is it not working?
To figure this out, I am trying now to adapt the STAMP BASIC program that was used originally to test this LCD into the PICAXE BASIC. This program not only used both lines, it also displayed custom made moving characters. (A Pac-Man character eating characters that were displayed on the line before) In that way I might be able to find out what the problem is.
Also, I have some other 16X2 and 20X2 LCDs which I can try my program on.
See what happens...
 

inglewoodpete

Senior Member
At times like these, I'd write a program that writes a different character to every increment of 8 address locations. Use SerTxd to write (log) each character and the address that it is written to. When you get a character to appear in the second line, use the log to tell you the address it was written to.
 

hbl2013

Senior Member
UPDATE- I found all the references mentioned by members and they were very helpfull. I substituted a standard 20X2 LCD for the 8X2 and everything worked flawlessly using the program I listed previously! I can now put characters in any specific location on the 2 lines at will, something that I was after. The problem seems to lay in the way the memory of the 8X2 is layed out, I still have to work with that one to see if I can accomplish the same with that LCD as with the 20X2, maybe using something what inglewoodpete suggests above. The layout of the 8X2 memory is not as straight forward as I thought, otherwise the program should have worked. (it worked for the 20X2!)
 

inglewoodpete

Senior Member
Have a look at hippy's suggestion in the link that he posted. I'd hadn't remembered it from last year but it looks the best diagnostics idea to me. ...and the code is already written for you!
 
Top