Shop OBEX P1 Docs P2 Docs Learn Events
Simple Serial LCD OBJ question — Parallax Forums

Simple Serial LCD OBJ question

DRMorrisonDRMorrison Posts: 81
edited 2014-07-16 23:46 in Propeller 1
Of all of the serial objects in the exchange that will drive the Parallax 4-line LCD, which of them will do the minimum job of just writing
to the LCD, and have the minimum code size? Compact. I only need text and integers for this project, but see below for another
question.

Thank you, Daniel


As an aside, how do I print decimal numbers to said LCD? That must require a different object?

I should state that I'm kind of new at his stuff, and have looked into this, but not with much luck.
Thanks for any help.

Comments

  • ChrisGaddChrisGadd Posts: 310
    edited 2014-07-16 10:42
    If that's all you need, then something like this should suit:
    CON
      _clkmode = xtal1 + pll16x                                                   
      _xinfreq = 5_000_000
      Tx_pin   = 30
      Baud     = 19_200
    
    PUB Main
    
      dira[tx_pin]~~
      outa[tx_pin]~~
      waitcnt(cnt + clkfreq)
    
      tx($0C)   ' Clear screen - the datasheet lists all of the command bytes
      tx("A")   ' ASCII "A"
      tx($0D)   ' Carriage return
      dec(1234) ' Decimal 1234
      tx($0D)
      str(string("This is a string"))
    
    PUB Dec(value) | i, x
    
      x := value == NEGX                                    'Check for max negative
      if value < 0
        value := ||(value+x)                                'If negative, make positive; adjust for max negative
        Tx("-")                                             'and output sign
    
      i := 1_000_000_000                                    'Initialize divisor
    
      repeat 10                                             'Loop for 10 digits
        if value => i                                                               
          Tx(value / i + "0" + x*(i == 1))                  'If non-zero digit, output digit; adjust for max negative
          value //= i                                       'and digit from value
          result~~                                          'flag non-zero found
        elseif result or i == 1
          Tx("0")                                           'If zero digit (or only digit) output it
        i /= 10                                             'Update divisor
    
    PUB str(stringptr)
    
      repeat strsize(stringptr)
        tx(byte[stringptr++])
        
    PUB Tx(Tx_byte) | t
    
      Tx_byte := (Tx_byte | $100) << 1
      t := clkfreq / Baud + cnt
    
      repeat 10
        waitcnt (t += clkfreq / Baud)
        outa[tx_pin] := Tx_byte & 1 
        Tx_byte := Tx_byte >> 1
    
    Very no frills, like you asked for. The display doesn't transmit anything, so there's no reason for a receiver in the code, and the max baud according to the datasheet is 19,200, well within the capabilities of Spin. The DEC method is copied from FullDuplexSerial, and gives you your decimal numbers.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-07-16 13:08
    For printing on an LCD you might prefer a method that puts integers in a fixed width field padded in front with spaces. That makes it easier to line up data on the lines.
    [SIZE=1][FONT=courier new]PUB DecW(value, width) | sign,  idx, box[4]
      width <#= 15                                ' limit width of field to 15 chars
      if value < 0
        ||value                                   ' handle negative (but not NEGX)
        sign~~                                    ' will put "-" in the buffer, but not yet
      else
        sign~
      bytefill(@box, 32, 15)                      ' fill the buffer with spaces
      byte[@box+15] := 0                          ' zstring
      repeat idx from 0 to 14
        byte[@box+14-idx] := value//10 + "0"      ' peel digits from least significant end
        value/=10                                 ' ... into buffer
        if value == 0                             ' have run out of digits
          quit
      if sign
        byte[@box+14-idx++] := "-"                ' put the "-" in the buffer
    ' if idx > width                              ' implement conditional for overflow??
      TxStr(result:=@box+15-width)                ' print string & leading spaces, return pointer
    [/FONT][/SIZE]
    
  • DRMorrisonDRMorrison Posts: 81
    edited 2014-07-16 17:30
    ChrisGadd,
    Doesn't this need an object? I've no problem with writing to the LCD, I was looking for a smaller object than the FullDuplxSerial object, if such a thing exists.
    Is there an object available that is bare bones, so as not to take up much space?

    Daniel
  • ChrisGaddChrisGadd Posts: 310
    edited 2014-07-16 17:53
    Sure, save it as a separate object if ya want, or just copy and paste the methods into your top object. It really is as simple as setting the tx pin as a high output and then calling dec, str, or tx.

    Chris
  • DRMorrisonDRMorrison Posts: 81
    edited 2014-07-16 19:03
    ChrisGadd wrote: »
    Sure, save it as a separate object if ya want, or just copy and paste the methods into your top object. It really is as simple as setting the tx pin as a high output and then calling dec, str, or tx.

    Chris
    Thanks a million. I didn't think it was this easy--easy for me to say, of course.

    Now, what about printing floating numbers to the LCD? As in 23.45

    Daniel
  • ChrisGaddChrisGadd Posts: 310
    edited 2014-07-16 19:43
    True floating point numbers I can't help with, I know there's a float to string object in the library folder, but I've never had reason to try it. Looks like Str(FloatString.FloatToString(23.45)) might do the job.
    I do have a method that can accept an integer, a divisor, and the number of decimal places to display the result. For 23.45, that's 2345 divided by 100 displayed to 2 decimal places so you'd call DecF(2345,100,2). Hope this helps.

    Chris
    PRI DecF(value,divider,places) | i, x
    {
      DecF(1234,100,3) displays "12.340"
    }
    
      if value < 0
        || value                                            ' If negative, make positive
        Tx("-")                                             ' and output sign
      
      i := 1_000_000_000                                    ' Initialize divisor
      x := value / divider
    
      repeat 10                                             ' Loop for 10 digits
        if x => i                                                                   
          Tx(x / i + "0")                                   ' If non-zero digit, output digit
          x //= i                                           ' and remove digit from value
          result~~                                          ' flag non-zero found
        elseif result or i == 1
          Tx("0")                                           ' If zero digit (or only digit) output it
        i /= 10                                             ' Update divisor
    
      Tx(".")
    
      i := 1
      repeat places
        i *= 10
        
      x := value * i / divider                             
      x //= i                                               ' limit maximum value
      i /= 10
        
      repeat places
        Tx(x / i + "0")
        x //= i
        i /= 10    
    
    Again based heavily of the Dec method from FullDuplexSerial.
  • DRMorrisonDRMorrison Posts: 81
    edited 2014-07-16 22:19
    Chris,
    You are a life saver. Thanks a ton.

    I did notice that this doesn't work if my clk is set to 5MHz i.e.
      _clkmode = xtal1  
      _xinfreq = 5_000_000
    

    Works fine when running at the 80MHz setting. Is it due to the CON you set as Baud = 19_200 and later used as in the PUB tx(tx_byte) method?

    Daniel
  • kuronekokuroneko Posts: 3,623
    edited 2014-07-16 23:33
    @DRMorrison: Yes, 5MHz is not enough to operate this method at this speed. Think about it, @5MHz each bit (@19200baud) uses about 260 clock cycles (or a bit over 16 hub windows). That's not enough time for the interpreter to even read the loop body, let alone internal operations.
  • DRMorrisonDRMorrison Posts: 81
    edited 2014-07-16 23:46
    Yes, I should have done the math. I guess I could slow down the baud rate if needed. The slowest the LCD will go is 2,400, and that should be slow enough.

    Thanks to all for the help. You guys are great!

    Daniel
Sign In or Register to comment.