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

Propeller 1 and I2C LCD: Please Help

TheKaduuTheKaduu Posts: 41
edited 2013-04-17 16:16 in Propeller 1
Hi experts,

I am new to Propeller. I am trying to convert my existing Arduino project to Propeller.
The project, in a nutshell, is a remote controlled boat that has two motors, two ESCs, 2 temperature sensors for motors, GPS, Xbee Pro and parallel lipos for the power...

Well, I also made a remote controller for the boat that uses Xbee to communicate. There is a joystick, linear pot for the speed and two I2C LCDs (I2C/TWI 20x4 white on blue from DFRobot). LCD will be displaying per cell voltages (boat and remote controller), motor temperatures and speed from the GPS...

Now, I have been using Arduino library provided by DFRobot which uses Wire library on Arduino. Everything works just fine. When I try to convert everything to Propeller, the only problem I have is the LCDs.

I have been using Michael Green's Basic_I2C_Driver v1.3 which was simple enough for a Propeller newbee like me. I have been using the following code to turn the backlight of the LCD which is the first step in the DFRobot library's LCD initialization. I will attach the DFRobot library files. Project wiring is described after the code.
CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
                
  i2cSCLLine = 0    'SCL is on Propeller pin 0
  i2cSDALine = 1    'SDA is on Propeller pin 1
  LCD_Addr   = $20

  'Flags for backlight control
  LCD_BACKLIGHT   = $08
  LCD_NOBACKLIGHT = $00

  'debug - USE onboard pins
  pcDebugRX = 31
  pcDebugTX = 30

  'serial baud rates  
  pcDebugBaud = 115200 

OBJ
   i2cObject : "Basic_I2C_Driver_1"
   debug     : "Debug_PC" 

VAR
   byte displayFunction, cols, rows, backLightVal, displayControl, displayMode
   long d

PUB Main
  waitcnt(clkfreq * 2 + cnt) 
  debug.startx(pcDebugRX,pcDebugTX,pcDebugBaud)
  debug.strln(string("Started serial communication..."))
  debug.putc(13)

  i2cObject.Initialize(i2cSCLLine)

  repeat 3
    debug.putc(".")
    waitcnt(clkfreq / 2 + cnt)

  debug.putc(13)
  backLightVal := LCD_NOBACKLIGHT
  waitcnt(clkfreq / 20 + cnt)

  i2cObject.Start(i2cSCLLine)
  debug.strln(string("I2C - Started..."))
  debug.putc(13)  

  i2cObject.Write(i2cSCLLine, LCD_Addr | 0)  
  debug.strln(string("I2C - Address written..."))
  debug.putc(13)

  d := backLightVal
  i2cObject.Write(i2cSCLLine, (d | backLightVal))
  debug.strln(string("I2C - Value written..."))
  debug.putc(13)

  i2cObject.Stop(i2cSCLLine)
  debug.strln(string("I2C - Stopped..."))
  debug.putc(13)  
  waitcnt(clkfreq + cnt)

Here is how I wired the project... I use 4 bi-directional voltage level converter from Adafruit between the Propeller ASC+ and LCD. LCD is powered by 5V and SCL and SDA pins are pulled up using 4.7k at the 3.3v side (which I think will be converted to 5V at the LCD side by the level converted... if not, please let me know)... It is also important to point out that I soldered the smd jumper in the back of the Propeller ASC+ for pin 0 and pin 1 as suggested at http://mghdesigns.com/wiki/asc:start

Why the backlight not turning off? What am I doing wrong? Can anyone help?

Thank you for your time and help,

TheKaduu
«13

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2013-03-23 18:24
    The Arduino sample code uses $27 as the LCD address. Your SPIN code uses $20. Unless you can configure the display I don't think that's going to work.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-23 18:49
    Kuroneko,

    I have two of these and addresses can be changed using jumpers as shown in the image. As the other image shows (not from 20x4 wiki page but from 16x2 wiki page... But the same backpack) that I have it in $20 address (I am using the top one). As far as the Arduino example at the DFRobot wiki page you mentioned, they must have taken all the jumpers of for that to work :)

    Thank you for your time.

    TheKaduu
    956 x 1280 - 296K
    637 x 437 - 52K
  • kuronekokuroneko Posts: 3,623
    edited 2013-03-23 23:32
    I thought as much. The other thing is that the I2C object expects the device address to be pre-shifted (<< 1, this is where the r/w bit gets inserted). Then a single command like this should work (untested):
    CON
      LCD_Addr = $20 << 1
    
    ...
    
      i2cObject.WriteByte(i2cSCLLine, LCD_Addr, i2cObject#NoAddr, LCD_NOBACKLIGHT)
    
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-03-24 09:05
    Marko is correct: Propeller I2C objects take an eight-bit value which includes the R/W bit where the Arduino uses a 7-bit value that truncates the R/W bit (which is maddening, becuase values in Arduino programs don't match manufacturer data sheets).

    Also, the Propeller already has an I2C buss that you can use which will free up a couple pins. You can in fact share the buss that the boot EEPROM (pins 28 and 29) is connect to.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-25 09:27
    Kuroneko and JonnyMac:
    Thank you so much for your responses. I saw this in twi.cpp which is referenced by Wire.cpp which is referenced by the DFRobot LCD library.
    I was confused by this previously when I was testing the LCDs with Arduino... I will try this and let you know.

    JonnyMac:
    About I2C bus sharing... I will still have to have the I2C object for my LCDs, right? If so, I will only be saving couple of pins, right?


    Another question... The I2C chip (http://www.dfrobot.com/image/data/DFR0154/PCA8574 Datasheet.pdf) on these LCD modules are 2.3v to 5.5v. I am powering using 5v. Do I have to use the voltage level converter at all? In other words, does powering the LCD with 5v make the SCL and SDA 5v level? I just answered my own question... Please check out the page 14 of the documentation about "Input SCL; input/output SDA"...
    Thanks anyway... (I am not deleting what I just wrote. It might benefit someone, I hope.)

    Thank you for your time.
    509 x 350 - 26K
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-03-25 10:52
    About I2C bus sharing... I will still have to have the I2C object for my LCDs, right? If so, I will only be saving couple of pins, right?

    Yes, but, ultimately, you may want to use a high-speed (PASM) I2C driver and have it shared among devices -- you can't do this if the devices are connected to different pins. Using extra pins is fine if you have them; having started with the BASIC Stamp 1 I'm always in "resource conservation" mode.
  • photomankcphotomankc Posts: 943
    edited 2013-03-25 12:57
    JonnyMac wrote: »
    Marko is correct: Propeller I2C objects take an eight-bit value which includes the R/W bit where the Arduino uses a 7-bit value that truncates the R/W bit (which is maddening, becuase values in Arduino programs don't match manufacturer data sheets).

    Also, the Propeller already has an I2C buss that you can use which will free up a couple pins. You can in fact share the buss that the boot EEPROM (pins 28 and 29) is connect to.


    Interesting point of view. I always went nuts because lots of data-sheets specify 7 bit addresses and the code required 8 bits. Still other datasheets give it to you as binary with leading zeros removed. Thanks.... that's very helpful. I wouldn't care one way or the other but when I first started coding my own object I thought it made more sense to pass the 7 bit address to the object and let it do the manipulation to create the read/write address from that and lots of the datasheets I was looking at gave 7bit addresses.

    I wish they would just pick one way and all do it the same!
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-25 14:38
    JonnyMac wrote: »
    Yes, but, ultimately, you may want to use a high-speed (PASM) I2C driver and have it shared among devices -- you can't do this if the devices are connected to different pins. Using extra pins is fine if you have them; having started with the BASIC Stamp 1 I'm always in "resource conservation" mode.

    Indeed... Thanks again. I will use the PASM I2C on pins 28 and 29 tonight along with << 1.

    Thank you for your time.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-25 17:45
    I tried the following and it did not work. I am trying to make it work with the "Basic_I2C_Driver_1" before I can move on to the PASM version... Any ideas?

    Edit: Attached image shows that the LCD still functions OK with the Arduino setup...

    Thank you for your time...
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
                    
      i2cSCLLine = 28    'SCL is on Propeller pin 28
      i2cSDALine = 29    'SDA is on Propeller pin 29
      LCD_Addr   = $20 << 1
    
      'Flags for backlight control
      LCD_BACKLIGHT   = $08
      LCD_NOBACKLIGHT = $00
    
     
    OBJ
       'i2cObject : "pasm_i2c_driver"
       i2cObject : "Basic_I2C_Driver_1"
    
     
    PUB Main
      waitcnt(clkfreq + cnt)
      i2cObject.Initialize(i2cSCLLine)
      i2cObject.Start(i2cSCLLine)
      i2cObject.WriteByte(i2cSCLLine, LCD_Addr, i2cObject#NoAddr, LCD_NOBACKLIGHT)  
      waitcnt(clkfreq + cnt)
      i2cObject.Stop(i2cSCLLine)
    
    1024 x 765 - 74K
  • kuronekokuroneko Posts: 3,623
    edited 2013-03-25 17:57
    WriteByte includes the necessary start/stop calls so they are not required at this level (and may even interfere with the proper operation of the device). Also, I don't see any initialisation code for the LCD which may (not) be required.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-25 18:17
    Kuroneko:
    I tried to take the Start and Stop off and still not working. In the attached DFRobot library file, the first thing it is doing is to turn the backlight off. Before that, it is executing Wire.begin()... I cannot believe this simple task is taking long time for me.

    Thank you.
  • kuronekokuroneko Posts: 3,623
    edited 2013-03-25 18:41
    I'm running out of ideas here. @all: If someone else has a bright idea chime in!

    FWIW, could you verify what the prop thinks is available in the bus? I'll attach Tim Moore's i2cScan object modified for FDS usage.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-25 19:00
    I ran the I2CScan and got the following output:
    [INDENT][U]Scanning 12C Bus....
    Scan Addr : %10100000 01010000, ACK
    i2cScan found 1 devices![/U][/INDENT]
    

    Hopefully, this is not the EEPROM on the ASC+ board... If so, the LCD is somehow not visable, right?
    I unplug the LCD, rerun the scan and still get the same thing. Therefore, the LCD is not being recognized.
    What's next?

    Thanks Kuroneko.

    EDIT: I had to put the output into the code block to get it show up...

    Meanwhile, I did the same thing on the Arduino side and got the following:
    Scanning...
    I2C device found at address 0x20  !
    done 
    
  • kuronekokuroneko Posts: 3,623
    edited 2013-03-25 19:34
    That is - unfortunately - the EEPROM address ($A0). Which somehow suggests an issue with the level shifter given that the LCD works with your Arduino. This is outside my area of expertise but I'm sure someone else will respond in time.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-25 19:48
    Thanks for the help so far, Kuroneko. I know more than I did before. Hopefully someone else will take a stab at it...
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-25 22:19
    I somehow got it to working. I had to replace the level converter as Kuroneko suggested. However, I still cannot get the LCD detected at P28 and P29.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-26 08:44
    @All,

    Now I have a different problem. The DFRobot LCD library is using Stdio.h through Print.h as shown below:
    void LiquidCrystal_I2C::printstr(const char c[])
    {
       //This function is not identical to the function used for "real" I2C displays
       //it's here so the user sketch doesn't have to be changed
       print(c);
    }
    

    How this could be implemented in SPIN?

    Thank you for your time.

    TheKaduu
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-03-26 08:48
    Have a look at FullDuplexSerial -- you can copy methods from it to get string and formatted numeric output.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-26 09:47
    I am looking at the "str" method. So, instead of the "tx" call, I will just write that byte to the LCD using the I2C, right? I did not see anything special done in the DFRobot library; it just calls print("....").
    Thanks JonnyMac.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-03-26 10:44
    Are you able to write control and ASCII characters to the LCD now? If yes, then you're in good shape: where tx is used you would substitute that method, and call that from your copy of str.

    Is there a schematic for the LCD? The data sheet is for the core chip, not for the LCD module. Knowing the connections would make helping you create object for it far easier. Who's to say that the Arduino library you're using now is best? ;)
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-26 11:22
    JonnyMac:
    I found the schematic for the I2C backpack which shows the connections to the LCD (attached). On the side note, if I get this to work, I don't have to use a logic level converter! All I have to do is to use the gadgeteer ports on the backpack which has built-in voltage level converter for the gadgeteer ports. Anyway... I think I tried to send a single character to the LCD using the I2CObject.WriteByte. I don't remember it working. I can only send bytes that has commands like Backlight on/off...

    Thanks.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-03-26 12:04
    I was able to deduce most of the connections from the .cpp file. It won't be hard to write a proper object for that LCD, but I can't do it right this minute. I'm going to order one as it seems like a handy display, anyway.

    Hints:
    -- the LCD is connected in four bit mode
    -- this means there will be six i2c writes per character
    * write byte (2 writes) with E low, write byte (2 writes) with E high, write byte (2 writes) with E low again
    -- RS bit is decoded as command (0) or character (1)
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-26 12:45
    I definately recommend this LCD. It is white on blue and fast. I first got the 128x64 Serial Graphic LCD from SparkFun, but the firmware is really troublesome. SparkFun even recommends the users to replace the firmware with someone else's.
    I also recommend DFRobot. They are relatively cheap and have fast shipping. I get what I ordered in 3-4 days from China (where they are located) for $10-12 shipping (DHL). I am in Florida... You should be able to get it in 1-3 days.

    Anyway, I ordered FTDI cable and once it's here, I will fix the Sparkfun Graphic LCD which we have an object for in the OBEX. I already hooked that up and got it to run in as much time as it takes to wire it up and upload the code to the propeller :)

    If it's not going to be too much trouble for you, can you explain the hints you gave? I saw the LCD init function in the DFRobot library was trying to switch to 4 bit mode.... But, why would there be 6 I2C writes? A char is one byte which would take 2 writes in 4 bot mode, right? Where does the extra 4 writes coming from? Also, I did not understand the last hint. Sorry.

    Thank you for your time.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-03-26 13:58
    Remember that you're not only writing the character nibbles, you also have to write the state of the E pin which moves data from the expander into the LCD. Since you need to have the buss setup before taking the E pin high, you need to do this

    write character with E clear (2 writes)
    write character with E set (2 writes)
    write character with E clear (2 writes)

    You can see this in the .cpp code (pulseEnable calls expanderWrite twice):
    /************ low level data pushing commands **********/
    
    // write either command or data
    void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) {
    	uint8_t highnib=value&0xf0;
    	uint8_t lownib=(value<<4)&0xf0;
        write4bits((highnib)|mode);
    	write4bits((lownib)|mode);
    }
    
    void LiquidCrystal_I2C::write4bits(uint8_t value) {
    	expanderWrite(value);
    	pulseEnable(value);
    }
    
    void LiquidCrystal_I2C::expanderWrite(uint8_t _data){
    	Wire.beginTransmission(_Addr);
    	printIIC((int)(_data) | _backlightval);
    	Wire.endTransmission();
    }
    
    void LiquidCrystal_I2C::pulseEnable(uint8_t _data){
    	expanderWrite(_data | En);	// En high
    	delayMicroseconds(1);		// enable pulse must be >450ns
    
    	expanderWrite(_data & ~En);	// En low
    	delayMicroseconds(50);		// commands need > 37us to settle
    }
    
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-26 14:12
    So, 1 byte is broken to 2 nibbles because of 4 bit mode. For each nibble, "expanderwrite" is executed 3 times which makes it 6 transmissions.
    Do you think I would be ok if I use the "send" to send the characters one by one since I already converted the "write4bits", "expanderwrite" and "pulseEnable" methods to SPIN?

    Thanks.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-03-26 16:14
    This is just translating without testing, but the Spin version of the those functions may look something like this:
    pri send(value, mode)
    
      write_4_bits((value & $F0)) | mode)                           ' send high nibble
      write_4_bits(((value << 4) & $F0)) | mode)                    ' send low nibble
    
    
    pri write_4_bits(value)
    
      expander_write(value)
      pulse_enable(value)  
    
    
    pri expander_write(value)
    
      i2c.start
      i2c.write(lcdaddr)
      i2c.write(value | (blcontrol << 3))                           ' blcontrol is 1 for on, 0 for off
      i2c.stop
    
    
    pri pulse_enable(value)
    
      expander_write(value | E_MASK)                                ' blip E pin
      expander_write(value)
    


    Note that I have my own very simple I2C library (based in part on Mike's code) that has just a few methods: start, write, read, and stop -- I'm basing my example on that.
  • TheKaduuTheKaduu Posts: 41
    edited 2013-03-26 17:23
    Thank you for your help so far JonnyMac!

    I did it little bit different but I'll try those... Meanwhile, I did a work around for my problem. I basically send the values to Arduino Mega to use the I2C library from DFRobot to display the values. It is a lot like reaching your left ear with right hand, but it serves the purpose. Here is the code for both and attached images are the setup:
    Con
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      pcDebugRX = 0
      pcDebugTX = 1
      pcDebugBaud = 57600 
      
    Var
      long x, y, z, t
    
    Obj
     debug : "Debug_PC"
     
    Pub Main
      debug.startx(pcDebugRX,pcDebugTX,pcDebugBaud)
      
      x := 1
      y := 1
      z := 1
      t := 1
      
      repeat
        debug.str(string("@"))
        debug.dec(x++)
        debug.str(string("#"))
        debug.dec(y += 2)
        debug.str(string("$"))
        debug.dec(z += 3)
        debug.str(string("%"))
        debug.dec(t += 5)
        waitcnt(clkfreq + cnt)
    
    
    #include <Wire.h> 
    #include <LiquidCrystal_I2C.h>
    
    LiquidCrystal_I2C lcd1(0x20,20,4);
    
    void setup()
    {
      Serial1.begin(57600);
      lcd1.init();
      lcd1.backlight();
    }
    
    void loop(void)
    {
      //*
      if(Serial1.available() > 0)
      {
        char b = (uint8_t) Serial1.read();
        
        if( b == '@')
        {    
          lcd1.setCursor(0,0);
          lcd1.print("               ");
          lcd1.setCursor(0,0);
        }
          
        else if( b == '#')
        {
          lcd1.setCursor(0,1);
          lcd1.print("               ");
          lcd1.setCursor(0,1);
        }
        else if( b == '$')
        {
          lcd1.setCursor(0,2);
          lcd1.print("               ");
          lcd1.setCursor(0,2);
        }
          
        else if( b == '%')
        {
          lcd1.setCursor(0,3);
          lcd1.print("               ");
          lcd1.setCursor(0,3);
        }
          
        else
          lcd1.print((char)b);
      }
      //*/
    }
    

    NOTE: Arduino code is pasting fine but SPIN code is not... Admins??
    1024 x 765 - 78K
    1024 x 1371 - 72K
  • jtilghmanjtilghman Posts: 67
    edited 2013-04-02 16:10
    Did you ever get this to work with the LCD ?

    I have the same LCD and would love to look at some code that will talk to iy.

    I to can make it work with the Arduino , but having troubles with the prop.

    Thanks
  • TheKaduuTheKaduu Posts: 41
    edited 2013-04-02 19:04
    jtilghman: I saw your questions too. This is the same thing but 4 lines instead of 2 lines... I have been able to work it with Arduino without problems. I'm just not used to work on this low level programming. Stick around and we might learn something :)

    JonnyMac: Below pasted code is what I have so far. I am able to INIT the LCD (which comes back with backlight off) and turn on the back light... Beyond that, I haven't been able to write characters or anything else to it. The screen looks like it is just connected to power (attached image).

    Any ideas? Can you check the code (espacially the Str subroutine) and give us some feedback?

    Thank you for your time.

    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
                    
      i2cSCLLine = 0    'SCL is on Propeller pin 0
      LCD_Addr   = $20 << 1
     
      'Commands
      LCD_CLEARDISPLAY = $01
      LCD_RETURNHOME = $02
      LCD_ENTRYMODESET = $04
      LCD_DISPLAYCONTROL = $08
      LCD_CURSORSHIFT = $10
      LCD_FUNCTIONSET = $20
      LCD_SETCGRAMADDR = $40
      LCD_SETDDRAMADDR = $80
    
      'Flags for display entry mode
      LCD_ENTRYRIGHT = $00
      LCD_ENTRYLEFT = $02
      LCD_ENTRYSHIFTINCREMENT = $01
      LCD_ENTRYSHIFTDECREMENT = $00
    
      'Flags for display on/off control
      LCD_DISPLAYON = $04
      LCD_DISPLAYOFF = $00
      LCD_CURSORON = $02
      LCD_CURSOROFF = $00
      LCD_BLINKON = $01
      LCD_BLINKOFF = $00
    
      'Flags for display/cursor shift
      LCD_DISPLAYMOVE = $08
      LCD_CURSORMOVE = $00
      LCD_MOVERIGHT = $04
      LCD_MOVELEFT = $00
    
      'Flags for function set
      LCD_8BITMODE = $10
      LCD_4BITMODE = $00
      LCD_2LINE = $08
      LCD_1LINE = $00
      LCD_5x10DOTS = $04
      LCD_5x8DOTS = $00
    
      'Flags for backlight control
      LCD_BACKLIGHT = $08
      LCD_NOBACKLIGHT = $00
      En = $04 '%00000100  'Enable bit
      Rw = $02 '%00000010  'Read/Write bit
      Rs = $01 '%00000001  'Register select bit
    
    OBJ
       i2cObject : "pasm_i2c_driver"
       'i2cObject : "Basic_I2C_Driver_1"
    
    VAR
       byte displayFunction, cols, rows, backLightVal, displayControl, displayMode
        
    PUB Main
      i2cObject.Initialize(i2cSCLLine)
      LCDInit(20, 4)
      
    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_CURSOROFF | LCD_BLINKOFF
      Display
      
      Clear
      displaymode := LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT
      Command(LCD_ENTRYMODESET | displaymode)
      Home
      
      BackLight
     
      Str(string("Testing 1, 2, 3..."))
                                         
    PUB Str(stringptr)
    '' Send string                    
      repeat strsize(stringptr)
        Command(byte[stringptr++])  ' [B]<--- Is this right?? What am I doing wrong?[/B]
    
    pub NoBlink
      displaycontrol &= !LCD_BLINKON
      command(LCD_DISPLAYCONTROL | displayControl)
      
    pub blink
      displaycontrol |= LCD_BLINKON
      Command(LCD_DISPLAYCONTROL | displayControl)
    
    pub NoBacklight
      backLightVal := LCD_NOBACKLIGHT
      ExpanderWrite(0)
    
    pub Backlight
      backLightVal := LCD_BACKLIGHT
      ExpanderWrite(0)
    
    pub Write4Bits(value)
      ExpanderWrite(value)
      PulseEnable(value)
    
    pub ExpanderWrite(data)
      i2cObject.Start(i2cSCLLine)
      i2cObject.WriteByte(i2cSCLLine, LCD_Addr, 0, (data | backLightVal))
      i2cObject.Stop(i2cSCLLine)
    
    pub PulseEnable(data)
      ExpanderWrite(data)
      waitcnt(clkfreq / 100_000 + cnt)
      ExpanderWrite(data & !En)
      waitcnt(clkfreq / 20_000 + cnt)
    
    pub Command(value)
      Send(value, 0)
    
    pub Send(value, mode)
      Write4Bits((value & $F0) | mode)            ' HIGH nibble      
      Write4Bits(((value << 4) & $F0) | mode)     ' LOW nibble  
    
    pub Display
      displayControl |= LCD_DISPLAYON
      Command(LCD_DISPLAYCONTROL | displayControl)
    
    pub NoDisplay
      displayControl &= !LCD_DISPLAYON
      Command(LCD_DISPLAYCONTROL | displayControl)
    
    pub Clear
      Command(LCD_CLEARDISPLAY)
      waitcnt(clkfreq * 2 + cnt)
    
    pub Home
      Command(LCD_RETURNHOME)
      waitcnt(clkfreq * 2 + cnt)
      
    
    956 x 1280 - 223K
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-04-02 20:13
    I ordered one of those displays from Jameco today. When it arrives I'll write an object for it.
Sign In or Register to comment.