Shop OBEX P1 Docs P2 Docs Learn Events
Propeller 1 and I2C LCD: Please Help - Page 2 — Parallax Forums

Propeller 1 and I2C LCD: Please Help

2

Comments

  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-02 20:44
    Thanks JonnyMac. After getting your object and comparing to the data sheet I will better understand the whole thing. I will check back.
  • jtilghmanjtilghman Posts: 67
    edited 2013-04-03 15:23
    JonnyMac:
    I have been around these forums long enough to know that nothing much beats you. Good luck with this LCD it is a pretty nice little unit.

    TheKaduu:
    All I can say is that your not too far off, the last code you posted works for me as well. I had to change the LCD address back to 27 and the Row/Columns to 2 x 16 as well as the SCL to 28.
    I am using a Quickstart board, using pins: SDA, SCL, GND and VIN. Just jumpered from the QS to the LCD. Seems to work fine.
    Your test code isn't going to print anything, and I can't tell you how to fix it.. :(
    But it looks like your not sending enough control data to the LCD, but it's just a guess.
    With your new code I can get the Backlight to come on or stay off after the init. But once the init is over can't get it to do any more. Also I hacked out some parts of the init and it STILL works.
    Makes me wonder if those parts are needed. I will post the before and after.
    BEFORE:
    pub LCDInit(c, r)
      backLightVal := LCD_NOBACKLIGHT
      cols := c
      rows := r
    
      displayFunction := LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS
      displayFunction |= LCD_2LINE
      waitcnt(clkfreq / 30 + cnt)
    
      ExpanderWrite(backLightVal)
      waitcnt(clkfreq + cnt)
    
      Write4Bits($03 << 4)
      waitcnt(clkfreq / 200  + cnt)
    
      Write4Bits($03 << 4)
      waitcnt(clkfreq / 200 + cnt)
    
      Write4Bits($03 << 4)
      waitcnt(clkfreq / 6000 + cnt)
      
      Write4Bits($02 << 4)
    
      Command(LCD_FUNCTIONSET | displayFunction)
      displayControl := LCD_DISPLAYON | LCD_CURSORON | LCD_BLINKON
      Display
      
      Clear
      displaymode := LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT
      Command(LCD_ENTRYMODESET | displaymode)
      Home
      
      BackLight
    

    AFTER:
    pub LCDInit(c, r)
      backLightVal := LCD_NOBACKLIGHT
      cols := c
      rows := r
    
      displayFunction := LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS
      displayFunction |= LCD_2LINE
      waitcnt(clkfreq / 30 + cnt)
    
      ExpanderWrite(backLightVal)
      waitcnt(clkfreq + cnt)
    
      Write4Bits($03 << 4)
      waitcnt(clkfreq / 200  + cnt)
    
      Write4Bits($03 << 4)
      waitcnt(clkfreq / 200 + cnt)
    
      Write4Bits($03 << 4)
      waitcnt(clkfreq / 6000 + cnt)
      
      Write4Bits($02 << 4)
    
      'Command(LCD_FUNCTIONSET | displayFunction)
      'displayControl := LCD_DISPLAYON | LCD_CURSORON | LCD_BLINKON
      'Display
      
      'Clear
      'displaymode := LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT
      'Command(LCD_ENTRYMODESET | displaymode)
      'Home
      
      BackLight
    

    Glad we got this far, exicted to see where we go from here.
    Thanks for everything.
    jt
  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-04 00:08
    I just wanted to INIT the LCD first before I would do the other functions. Some of the stuff likee Home and Clear does not mean anthing cause we were not able write anythin on the screen... I think Display just turns the screen on which is on by default... I can't wait for JonnyMac's object :)))
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-04 08:23
    I got the shipping notice from Jameco -- should be here today or tomorrow (I'm just down the coast from them).
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-05 20:28
    Easy-peasy. I have a 2x16 display but the object will work with 4-line displays, too (be sure to look at the constants for moving to the 3rd and 4th lines). The demo writes characters (normal and custom defined), strings, and formatted numbers. It also shows how to control the backlight. Note that with the backlight you must write something to the display to refresh that bit. In the demo I simply refresh the "cursor off" display mode; this write updates the backlight control bit.

    Have fun!

    BTW... It is okay to connect to the 5v port's SCL and SDA pins. Both are pulled up through 10K which more than protects the Propeller pins' over-voltage diodes. My demo is connected to a Propeller Boe using M-F 0.1" jumper wires. The 5v port is easier to connect to than the miniature 2x5 headers. EXCEPTION: Do not connect the LCD 5v I2C pins to pins 28 and 29 on your Propeller as those already have pull-ups to 3.3v If you want to use P28 and P29 then you must use the 3.3v SCL and SDA pins on the display (2x5 headers).

    EDIT: I fixed a small bug that would cause the program only to work with address %000 which is what the LCD defaults to (all address jumpers on); I also updated the .backlight() method to refresh the display so you don't have to do that manually.

    EDIT: See code attached to later post.
    800 x 533 - 491K
  • jtilghmanjtilghman Posts: 67
    edited 2013-04-05 21:49
    Code looks great.

    Doesn't work for me.

    I cannot change the I2C address on my LCD its always 0x27.

    I also noticed that you use 14 and 15 and not 28 and 29. Was wondering why ?

    I changed the 0x20 in the file to 0x27, still no luck. Also tried 14,15 as well as 28,29 after making changes for that.

    Maybe I need some pull-ups ? I do know that does work with the ardunio code.

    Anyway, its late so I am off. I will try working with it over the weekend to see if I can figure out whats going wrong.

    Thanks for all your hard work, JohnnyMac.

    John
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-05 23:38
    I'm regretting the time spent on this as the display I just spent $20 on seems to have died now that I plug it in to try again. I swear, it worked perfectly this afternoon -- I guess no good deed goes unpunished....

    In response to your questions: I used the schematic for the LCD, the docs for the PCA8574, and the docs for the Hitachi HD44780 LCD to write my code. I've done dozens of LCD projects, this is not something new to me. I've also done quite a lot of work with I2C. The original code was working in under an hour; I spend the rest of the time finessing and cleaning and making everything presentable.

    The LCD has pull-ups on the address pins. The jumpers -- when installed -- pull these lines to ground. That means, then, with all three jumpers installed, as I received the LCD, the base address bits are %000. If you look at Table 4 in the PCA8574 docs you'll see the base address is $20 << 1 plus the address bits; this makes the address range $20 << 1 to $27 << 1.

    My code is setup for pins 14 and 15 because I can connect to them on the Propeller BoE.

    No, you don't need pull-ups -- they're already on the board. NOTE -- this only applies when not using P28 and P29; do not connect the 5v I2C pins on the display to P28 and P29 on your Propeller board

    I have an Arduino somewhere. I will see if I can get the display working with that and then reconnect to my BoE. Irritating that it stopped working....
  • jtilghmanjtilghman Posts: 67
    edited 2013-04-06 07:46
    Sorry that your LCD died, hope it comes back for you.

    I went to the DFRobots site and found that my LCD is an OLDER model than the one that's available now.

    That being said, I think it should still work with the prop and I know that it works with arduino.

    I am going to try using i2cScan and see what it can tell me. At least to make sure I have the I2C setup correctly.
  • jtilghmanjtilghman Posts: 67
    edited 2013-04-06 08:10
    Just used I2cScan, couldn't see the LCD using 14,15 but could see it on 28,29.

    Went and put 10k's on both SCL and SDA on 14,15 and now I2CScan sees the LCD. Can't your code to work with the LCD on 14,15 or 28,29 using 0x20 or 0x27. :frown:

    But I did use the code that TheKaduu posted, and at least I am back to turning off the backlight.

    Seems as like I did need the pull ups, must be because this is an older model.

    So I hope this little be of information helps the cause along.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-06 10:43
    If you're scanning for the LCD you must scan the pins it's connected to. If you're connected to P28 and P29 then scanning P14 and P15 is useless -- like looking in an empty closet for your missing shirt ;)

    I did find a "gotcha" in my code that would allow it to work at address $20 but no others; that is corrected (see above). I also updated the .backlight() method so that it refreshes the display automatically.

    I couldn't find the I2CSCAN program you referred to so I wrote my own. My display seems to be dead. It worked out of the box and while I developed the demo. I unplugged it to work on something else after posting my code and when there was a report of trouble I plugged it back in. It went wacky for no apparent reason (on close inspection, the solder joints look cold so I'm hoping Jameco will exchange it for me -- otherwise I just wasted $20). I tried connecting and running it with an Arduino. No joy. When I reconnected to the Propeller it came back. I turned it off to remove the jumpers so I could test my code fix and it seemed to be dead for good at that point. Pretty disappointed in this display....

    Just found the I2CSCAN program (in this thread!) -- will give it a try.
  • jtilghmanjtilghman Posts: 67
    edited 2013-04-06 10:48
    Hey JonnyMac,

    The I2CSCAN program is in the top of this thread. :smile:
  • jtilghmanjtilghman Posts: 67
    edited 2013-04-06 10:51
    You misunderstand,

    When the LCD was attached to 28,29 the I2CSCAN could see it, I then recompiled the I2CSCAN to to look on 14,15 as you have it in your code.

    This didn't see the LCD, until I added the 2 - 10k pull ups.

    I will try your corrected code. :)

    Here is a picture of the LCD I am working with:

    vlcsnap-2013-04-06-14h05m38s14.jpg


    Hope the picture is clear enough, used my webcam.

    Also tried the new code, still doesn't seem to work for this LCD.

    Here is the output from I2CSCAN with the LCD on 14,15:
    Scanning I2C Bus....
    Scan Addr :  001110 00100111,  ACK
    Scan Addr :  111000 01111100,  ACK
    i2cScan found 2 devices!
    

    Not sure why its showing 2 addresses, but 0x27 is the only one I know about.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-06 13:37
    Maybe your version doesn't have 10K pull-ups built in as mine does. The I2CSCAN found the display on P14 and P15 with all jumpers on and all jumpers off -- this is encouraging news. I'm back at the PCA8574 docs to see if I can sort this out.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-06 14:53
    Sorry for late reply... It is odd that JonnyMac's LCD quit working :(

    JonnyMac's code worked almost out of the box (first image)! I used the Propeller ASC+ board which has protection resistors on the most IO pins... I don't know if this is right...

    Also, the code does not work all the time. It just displays weird characters.... Something wrong that I haven't figured out yet... I will update later.

    JonnyMac, thank you for your efforts.
    1024 x 1371 - 138K
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-06 15:17
    I'm thinking it's a timing-related issue. When I use my buss scanner and Tim Moore's scanner on P28 and P29 of the Propeller BoE, both programs find the EEPROM and the ADC. Tim's scanner sees the display on P14 and P15, but my scanner (using my I2C code) does not.

    My display has been intermittently working so this bolsters my thought about timing.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-06 15:51
    I have an update on the display... I made a video using my IPad I am attaching it and I hope all can view it with no problems.
    What happens is when the LCD initialized the firts time, bunch of weird characters displayed. However, the display shows these weird characters according to the code, for example, first and second line animates with the same amnount of pauses. Then the other repeat... Lastly, the backlight turns on and off as it was programmed to do so...

    After what I just described happens 2-3 times. The display in the video link below repeats forever...

    https://www.youtube.com/watch?v=-XWv9am8P3I

    Any ideas?
  • jtilghmanjtilghman Posts: 67
    edited 2013-04-06 16:41
    JonnyMac wrote: »
    I'm thinking it's a timing-related issue. When I use my buss scanner and Tim Moore's scanner on P28 and P29 of the Propeller BoE, both programs find the EEPROM and the ADC. Tim's scanner sees the display on P14 and P15, but my scanner (using my I2C code) does not.

    My display has been intermittently working so this bolsters my thought about timing.

    I think JonnyMac has hit it on the head. I really do think it is a timing issue. Since in my case the code that TheKaduu at least will turn my backlight off, and jonnymacs doesnt.

    Also I am a little puzzled why mine shows as 2 addresses on I2C line.

    I feel like we are going forward, and yet not so much. :)

    JonnyMac would it help for me to attach the ardunio code that does work for mine ?

    Thanks
  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-06 17:54
    I think I got it... Don't ask me why it has to be this way (newbie remember), but it is working... I tried to follow JonnyMac's code with the DFRobot library for Arduino... Only change I had to make was the following:
    pri lcd_init
    ' Initializes LCD using 4-bit interface via PCA8574
      ctrlbits := BL_MASK                                           ' backlight on, others 0
      waitcnt((ms001 * 50) + cnt)                                   ' allow power-up
      
      wr_4bits(%0011 << 4)                                               ' 8-bit mode  
      waitcnt((ms001 * 5) + cnt)
      
      wr_4bits(%0011 << 4)  
      waitcnt((ms001 * 2) + cnt)
                                         
      wr_4bits(%0011 << 4)
      waitcnt((ms001 >> 2) + cnt)                                   ' 250us
      
      wr_4bits(%0010 << 4)                                               ' 4-bit mode 
      
      cmd(%0010_1000)                                               ' multi-line
      cmd(%0000_0110)                                               ' auto-increment cursor
      dispctrl := %0000_1100                                        ' display on, no cursor
      cmd(dispctrl)
      cmd(LCD_CLS)
    

    When I put this into the EEPROM, and restart the ASC+, it still works without any weird characters at the begining... I hope this helps. Let me know if this works for you.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-06 18:02
    Now... I tried two LCDs at the same time and could not make it work. I tried to instantiate 2 of the "jm_twi_lcd" objects... I probably need to modify the object to create 2 LCD within the object, right?
    Thank you for your time.

    JonnyMac: Is you LCD totally gone?

    jtilghman: How is yours doing? Let me know if you try the modification to JonnyMac's I suggested...
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-06 18:02
    Nope, my LCD is working again.

    Edit: Silly me... I changed wr_4bits but did not change lcd_init to match. Dumb mistake -- even those of us with a few miles on our sneakers make them from time-to-time. On fixing that the LCD works without secondary pull-ups. New files attached.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-06 18:49
    I don't know what's going on, but I had to shift what I sent to wr_4bits like this => wr_4bits(%0011 << 4)... When I do this the new version you just posted works as well.
    Why does it work on yours the way that you have and I have to shift left by 4 to make it work on mine? Any ideas?

    Also, I do not use any pull-ups as it is shown in the first image... The Propeller ASC+ has 2k2 resistors on some I/O lines. I use pin 0 for SCL and pin 1 for SDA.
    1024 x 765 - 94K
    1024 x 765 - 71K
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-06 19:04
    I did make some changes in my code. the wr_4bits routine expects the 4 data bits in the msb position of the value you send. It adds the other bits. The archive attached above has all the new stuff that is running fine on my end.
  • jtilghmanjtilghman Posts: 67
    edited 2013-04-06 19:16
    That last one seems to work, I have no idea if what I am seeing is correct yet.

    But at least its something.

    I will upload a video if I can.

    When starts up there seems to be random characters going from left to right, then the backlight blinks a few times, then I see 'JonnyMac Rules' scrolling then its time and temp or something like.

    Nothing every steady or clear. But at least its something. :lol:

    Better than it was.

    Very cool.


    UPDATE:

    I took this code out:

    '  lcd.set_char(0, @mouth0)                                      ' define custom characters
    '  lcd.set_char(1, @mouth1)
    '  lcd.set_char(2, @mouth2)
    '  lcd.set_char(3, @smile)
    

    And the DEMO to works great now. :)

    More work for me now.

    Great job JonnyMac !
  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-06 19:36
    jtilghman: Try adjusting the backlight from the pot. It seems to get better..

    JonnyMac: Thank you so much for your help. I will now adapt this object to work with 2 LCD for I have 2 temperatures (motor temperatures), 2 voltages (boat and remote controller lipo voltage per cell) and 2 speeds (current and max from GPS). Each using one line, therefore I have 2 lines blank on the second LCD. But I'll figure something out for the blank ones :)))

    In general about the Propeller ASC+, since I have the 2k2 resistors on I/O lines, is it OK to use 5v on them? I have been doing this with my LCD testing and nothing seems to be damaged (yet).
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-06 19:37
    Have a look at the archive I just updated. It fixed lcd_init to match wr_4bits. That fixed things nicely on my desk. Sorry... I was making too many simultaneous changes to the code and objects and lost track of that one. I should have looked at post #49 more closely.
    Thank you so much for your help. I will now adapt this object to work with 2 LCD

    You're welcome.

    Tip: Pass the addresses of your displays and save them. Add a public method called select() that lets you select LCD 0 or LCD 1. On calling select with 0 or 1 you can change the variable devid to to correspond to the display you want to use. Remember that you'll have to call lcd_init twice as well.

    I have the 2k2 resistors on I/O lines, is it OK to use 5v on them?

    Remember that there are 10K pull-ups between the 5v and the pins -- this protects the pins. I don't have inline resistors on the BoE and it's just fine. Well-behaved I2C devices NEVER drive the clock or data line high; they allow the pull-ups to take the line to the "1" state.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-06 19:59
    Sometimes I play goofy little games with myself. I looked at the clock and thought, "Ooo... 20 minutes until the new Dr. Who -- can I update the driver to work with multiple LCDs in that much time?" I think the answer is yes. I have run the attached code with my one display. If you have two on the same buss I would love to know if it works.

    Notes:
    -- call start just once
    -- for each LCD on your buss:
    * call select to set the unit (0 to 7)
    * call initialize to setup the LCD

    You will use the calls as in the first version, you need only set which LCD you want information to go to by using .select(). Let me know if it works.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-06 20:09
    Well, great -- my display stopped talking again. I will NOT be recommending this product in my column....
  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-06 20:38
    I was just working on 2 LCD and you change the object to work on 2 LCD... Well, I'll give it a try and let you know shortly.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-06 21:04
    Great minds think alike... I was doing the same thing you were doing and having the exact same issue that I am now having with your code. Here it is... If I control them individually, it all works fine. Ex:
    pub main
      lcd.start(LCD_SCL, LCD_SDA)                                   ' start i2c for lcd
      
     ' run these two lines for each display on buss
      
      lcd.select(0)                                               ' select LCD to use
      lcd.initialize                                                ' do this first
    
      'lcd.select(7)
      'lcd.initialize
    
      repeat
        lcd.select(0)
        lcd.cmd(lcd#LCD_CLS)
        lcd.str(string("The"))
        'lcd.select(7)
        'lcd.cmd(lcd#LCD_CLS)
        'lcd.str(string("Kaduu"))
        pause(25)
    

    Now. I tried to connect the second LCD which has the address of 27... if I connect the second LCD's SCL and SDA (to the same bus obviously), the first LCD (at address 20) stops responding even with the code given above...

    Any ideas? Do you think the other LCD having pull ups as well has anything to do with this?
  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-06 21:19
    I think you got a faulty device... Mine never had problem so far. I just don't know how to interface with them :/
Sign In or Register to comment.