Shop OBEX P1 Docs P2 Docs Learn Events
Need help with character placement on LCD — Parallax Forums

Need help with character placement on LCD

robotrobot Posts: 13
edited 2007-12-03 03:38 in BASIC Stamp
Hey folks, Here is my problem. The characters on my 4x20 lcd screen get written to the third line before the second. I've read the datasheets for the lcd and understand that I must send the characters to the correct adress on the LCD. I'm not sure how to do this though.... Heres my code for sending characters and instructions

DATA· @0, "Text sent displayed on LCD" , %00000000·
Display:
READ index,ch 'read data from eeprom
IF ch = %00000000 THEN RETURN
GOSUB sendchr 'send to lcd
index = index + 1 'increment eeprom addr
GOTO Display


sendchr:
GOSUB busychk 'wait til lcd not busy
OUTB = ch.HIGHNIB 'upper part first
HIGH rs 'rs high
PULSOUT e,pulstime 'send it
LOW rs 'reset rs
GOSUB busychk 'wait again
OUTB = ch.LOWNIB 'lower nibble
HIGH rs 'rs high
PULSOUT e,pulstime 'send it
LOW rs 'reset rs
RETURN

·

Comments

  • Bruce BatesBruce Bates Posts: 3,045
    edited 2007-12-02 06:38
    robot -

    First, that can not be the entire routine, as less than one full line would probably be written. There is also no indication that the LCD was initialized, and if so how it was initialized. Certain parameters can be set during LCD initialization which can affect the "sizing" of the LCD and how the display is treated internally by the LCD controller chip.

    Second, if you were presuming that the data statement being used (see below) would place the data on the LCD screen in any particular place, that is not the case. The "@ nnn" address merely indicates where to place the data in Stamp memory, not in the LCD ram.

    DATA· @0, "Text sent displayed on LCD" , %00000000

    Third, an explicit command must often be given to adjust the cursor to the location on the LCD where you want the data to appear. So too the actual location of where the data is to be displayed often must be set by manipulating the DDRAM address.

    Fourth, you have given no indication as to the manufacturer and model of the LCD and whether it is HD44780 compatible. The HD44780 is an Hitachi LCD which is generally recognized as the de facto standard for character based LCD's, and the one with which most microcontrollers are compatible.

    Regards,

    Bruce Bates
  • RDL2004RDL2004 Posts: 2,554
    edited 2007-12-02 08:55
    How to control an HD44780 based LCD

    Also, there is some good info in the StampWorks Manual

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - Rick
  • robotrobot Posts: 13
    edited 2007-12-02 17:35
    Thanks for having a look at my code..........You are right, that definitly wasn'y all of it. I was trying to post the part I thought needed modifing, without overwhelming you guys with all the code. I will post all of the code below. Basically The program is· from "Build a Reaction Timer" in the Basic stamp homework book. The difference is, instead of using my computer monitor and debug commands, I used an LCD screen. It works great other than the instructions displayed on the LCD print first line then third line. here is all of the code....Thanks fore the help guys!

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}

    pulstime CON 500 'pulsout time interval
    'changes based on stamp model

    'see "pulsout" command for
    'timing details.
    '
    ' Some command constants based on the Hitachi 44780 spec
    '
    WakeUp CON %00110000 'Wake up
    FourBitMode CON %00100000 'Set to 4 bit mode
    OneLine5x8Font CON %00100000 '1 line 5x8 font
    OneLine5x10Font CON %00100100 '1 line 5x10 fnt
    TwoLine5x8Font CON %00101000 '2 line 5x8
    TwoLine5x10Font CON %00101100 '2 line 5x10
    DisplayOff CON %00001000 'Display off
    DisplayOn CON %00001100 'Display on, no cursor
    DisplayOnULCrsr CON %00001110 'Display on, underline cursor
    DisplayOnBLCrsr CON %00001101 'Display on, blink cursor
    IncCrsr CON %00000110 'Auto-increment cursor no display shift
    IncCrsrShift CON %00000111 'Auto-increment display. shift display left
    DecCrsr CON %00000100 'Decrement cursor. No display shift
    DecCrsrShift CON %00000101 'Decrement cursor with display shift
    ClearDisplay CON %00000001 'clear display
    HomeDisplay CON %00000010 'Cursor to home
    ScrollLeft CON %00011000 'Scroll to left
    ScrollRight CON %00010100 'Scroll right
    CrsrLeft CON %00010000 'Cursor to left
    CrsrRight CON %00010100 'Cursoft right
    MoveCrsr CON %10000000 'Move cursor to position
    MoveToCGRAM CON %01000000 'Move to CGRAM position

    e CON 3 'enable
    rw CON 2 'read/write
    rs CON 1 'register select
    'outb is data bus for lcd (p4-p7)

    x VAR Byte 'scratchpad var
    cmd VAR Byte 'command to sendcmd sub
    ch VAR Byte 'character to sendchr sub
    temp VAR Nib 'temp scratchpad
    index VAR Byte 'index to eeprom
    timecounter VAR Word
    value VAR Byte
    text VAR Word

    DATA @0, "·· Press and hold····· light turn red,·· pushbutton to make " , %00000000
    DATA @75, " When light turns··· fast as you can!··· green, let go as········ " , %00000000
    DATA @150, "You must wait until light turns green" , %00000000
    DATA @200, "Your time was ", %00000000
    DATA @225, " ms", %00000000
    Init:
    DIRL = %11111110 'p1-p7 outputs
    LOW e 'put
    LOW rw ' control lines
    LOW rs ' in initial state
    PAUSE 500 'wait til vcc stable
    GOSUB InitLCD 'initialize LCD


    beginning:
    cmd = ClearDisplay
    GOSUB sendcmd
    index = 0
    GOSUB instructions
    PAUSE 1250
    cmd = ClearDisplay
    GOSUB sendcmd
    index = 75
    GOSUB instructions
    GOSUB Game

    Game:

    DO
    ···· IF (IN9 = 1)· THEN
    ···· LOW 14
    ···· HIGH 15
    ···· RANDOM value
    ···· PAUSE 1000 + value

    ···· HIGH 14
    ···· LOW 15

    ···· timecounter = 0

    ···· DO
    ···· PAUSE 1
    ···· timecounter = timecounter + 1
    ···· LOOP UNTIL IN9 = 0
    ···· LOW 14
    ···· timecounter = timecounter * 2
    ···· IF (timecounter = 2) THEN
    ···· cmd = ClearDisplay
    ···· GOSUB sendcmd
    ···· index = 150
    ···· GOSUB instructions
    ···· PAUSE 2000
    ···· GOTO beginning
    ···· ELSE
    ···· cmd = ClearDisplay
    ···· GOSUB sendcmd
    ···· index = 200
    ···· GOSUB instructions
    ···· DEBUG DEC timecounter
    ···· value = timecounter DIG 2
    ···· LOOKUP value, [noparse][[/noparse]32, 49, 50, 51, 52, 53, 54, 55, 56, 57], ch
    ···· GOSUB sendchr
    ···· value = timecounter DIG 1
    ···· LOOKUP value, [noparse][[/noparse]48, 49, 50, 51, 52, 53, 54, 55, 56, 57], ch
    ···· GOSUB sendchr
    ···· value = timecounter DIG 0
    ···· LOOKUP value, [noparse][[/noparse]48, 49, 50, 51, 52, 53, 54, 55, 56, 57], ch
    ···· GOSUB sendchr
    ···· index = 225
    ···· GOSUB instructions
    ···· PAUSE 2000
    ···· GOTO beginning



    ··· ENDIF
    ··· ENDIF
    LOOP

    instructions:
    Display:
    READ index,ch 'read data from eeprom
    IF ch = %00000000 THEN RETURN
    GOSUB sendchr 'send to lcd
    index = index + 1 'increment eeprom addr
    GOTO Display






    '
    ' Initialize LCD according to specifications for the HD44780
    '
    InitLCD:
    FOR x=1 TO 3 'spec said to do three times
    OUTB = WakeUp>>4 'send wakeup call
    PULSOUT e,pulstime 'send command
    PAUSE 5
    NEXT

    OUTB = FourBitMode>>4 'go to 4 but mode
    PULSOUT e,pulstime 'send it
    PAUSE 1

    '
    ' Initialization command sequence...
    '
    cmd = FourBitMode
    GOSUB sendcmd
    cmd = TwoLine5x8Font
    GOSUB sendcmd
    cmd = DisplayOff
    GOSUB sendcmd
    cmd = DisplayOnBLCrsr
    GOSUB sendcmd
    cmd = IncCrsr
    GOSUB sendcmd
    cmd = ClearDisplay
    GOSUB sendcmd
    cmd = HomeDisplay
    GOSUB sendcmd
    RETURN

    '
    ' send character to ddram on lcd
    '
    sendchr:
    GOSUB busychk 'wait til lcd not busy
    OUTB = ch.HIGHNIB 'upper part first
    HIGH rs 'rs high
    PULSOUT e,pulstime 'send it
    LOW rs 'reset rs
    GOSUB busychk 'wait again
    OUTB = ch.LOWNIB 'lower nibble
    HIGH rs 'rs high
    PULSOUT e,pulstime 'send it
    LOW rs 'reset rs
    RETURN


    '
    ' Send command in the var "cmd" to the lcd
    '
    sendcmd:
    GOSUB busychk 'wait til lcd not busy
    OUTB = cmd.HIGHNIB 'upper cmd first
    PULSOUT e,pulstime 'send it
    GOSUB busychk 'wait again
    OUTB = cmd.LOWNIB 'lower nibble
    PULSOUT e,pulstime 'send it
    RETURN

    '
    ' waits til the lcd is no longer busy and then returns
    ' uses the var "temp"
    '
    busychk:
    DIRL = %00001110 'make lcd databus input
    HIGH rw 'were reading
    busyloop:
    HIGH e 'enable
    temp = INB 'get data from lcd
    LOW e 'toggle back enable
    PULSOUT e,pulstime 'because were in 4bit mode (two reads of 4 bits)
    TEMP = temp & $80 'mask all but busy flag (db7 from lcd)
    IF temp <> 0 THEN busyloop 'loop until not busy
    LOW rw 'back to write
    DIRL = %11111110 'reset databus back to output
    RETURN
  • robotrobot Posts: 13
    edited 2007-12-03 01:08
    Is there a way to have the different colors pasted in , when I paste code in a post? It takes along time to change every command to blue. It is a lot easier to read when the colors are in the code....
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2007-12-03 01:31
    It's easiest when one Uploads his program as an attachment.
  • robotrobot Posts: 13
    edited 2007-12-03 02:18
    Thanks!

    Here is my program in an easier to read format.............Hope this works!
  • robotrobot Posts: 13
    edited 2007-12-03 02:28
    We'll I guess I thought it would be viewable without someone having to download it, but anyway, anyone with some LCD help would Rock!
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2007-12-03 02:37
    As you've noted, the 4x20s go line 1, line 3, line 2, line 4.· That's just the way they are.

    You just have to structure your DATA so that you don't send more than 20 characters at a time, assuming that you're starting at the beginning of a line.

    Are you familiar with the ASCII formatting codes?·
    • $02 (02), a Home Cursor, puts you at the start of line 1·
    • $0C (12), a Form Feed,·does the same thing except it also erases everything
    • $0D (13), a Carriage return, ·puts the cursor at the start of the current line
    • $0A(10), a Line Feed, sends the cursor to the next line without putting it at the start of that line.
  • robotrobot Posts: 13
    edited 2007-12-03 03:11
    Some of the info I might need to display is more than twenty characters....What I need is someway to check where the current character is being written and determine if the next character should proceed or skip to a spot on the screen.

    I am familiar with the ascii codes, I used some of them in my code above, however, I'm still new to this, and far from proficient at using them to control character placement.
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2007-12-03 03:22
    robot -

    That sound pretty simple. Just use a counter and add one to it each time you write a character to the screen. Once the count gets to the limit, do whatever it is that you need to do and reset the counter.

    Regards,

    Bruce Bates

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2007-12-03 03:38
    I don't know of any "smart displays" that'll report back the cursor's line and position, if that's what you're fishing for.· The Parallax 4x20 has some extra formatting characters where you can place the cursor at any one of the 80 places.

    Anyway, you must structure your DATA·(break it up)·and not run more than·19 characters in succession (20 will force·the cursor·to the next line, but not the next line down) --·assuming that you begin at position 1 of any line.· Take stock of the situation (count) and figure to position your cursor accordingly.

    Try programming the LCD outside of your game program, get a hang of the formatting codes, see how they work out.

    12, "Hope", 10, 13, "This", 10, 13, "Makes", 10, 13, "Sense"
Sign In or Register to comment.