Shop OBEX P1 Docs P2 Docs Learn Events
Problems with PCA9555... — Parallax Forums

Problems with PCA9555...

Jorge PJorge P Posts: 385
edited 2011-05-02 04:05 in Propeller 1
He all, I am having a problem getting the code from this thread working http://forums.parallax.com/showthread.php?102475-PCA9555-IO-Expander-Driver&p=719130&viewfull=1#post719130

I wired it exactly like the diagram noting the backword symbols for the LEDs and still get nothing. Can someone verify if the code works ok for them... Hope I didnt get some bad chips from digikey:blank: All five do not work.

Comments

  • Jorge PJorge P Posts: 385
    edited 2011-05-01 21:00
    Here is the schematic from the file. All my diods are bicolor. I also used bi-color LEDs on the SCL and SDA lines to see if there was activity. I lowered the 10K ohm I2C to 2K. I am using 100 Ohm resisters on all LEDs.
    {{
      PCA9555 Driver Test
      By Dave Fletcher
       ┌────────────────────────────────────────────────────────────────────┐
       │                                                          Vdd       │
       │                 ___     ┌────┐┌────┐                      │        │
       │     unconnected INT─────┤    └┘    ├───Vdd────Vdd                 │
       │            Vss──A1──────┤          ├───SDA────────────────┴─P14    │      
       │            Vss──A2──────┤ PCA9555N ├───SCL────────────────┬─P15    │      
       │         00 Vdd──────┤          ├───A0─────Vss                 │
       │         01 Vdd──────┤          ├─── / ──Vss 15 s1   │        │
       │         02 Vdd──────┤          ├─── / ──Vss 14 s2  Vdd       │
       │         03 Vdd──────┤          ├──────Vdd 13               │
       │ PORT 0  04 Vdd──────┤          ├──────Vdd 12               │
       │         05 Vdd──────┤          ├──────Vdd 11  PORT 1       │
       │         06 Vdd──────┤          ├──────Vdd 10               │
       │         07 Vdd──────┤          ├──────Vdd 09               │
       │            Vss──GND─────┤          ├──────Vdd 08               │
       │                         └──────────┘                               │ 
       └────────────────────────────────────────────────────────────────────┘
                                                       Test Circuit Schematic
     
      8 pin DIP isolated 1K resistors appear to work well for the LEDs
      along with a 3.3v Vdd.
      The pull up resistors on SDA/SCL are 10K.
      The address pins are all tied to Vss making an address of 000. Tie to Vdd to
      use other addresses to put more devices on the bus.
      NOTE: The LEDs on port 1 on the right are backwards in the diagram because
            the Propeller Tool doesn't seem to have the reversed LED graphic.
     
    }}
    

    I have this wired up on PPDB, using the dipswitch as the two switches used in the schematic. I wired and rewired this several times to make sure I didn't make any mistakes. This is the code provided for the program, the pca9555 driver will follow.
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
     DIRECTION       = %1100_0000_0000_0000
     ALL_ON          = %1100_0000_0000_0000
     ALL_OFF         = %1111_1111_1111_1111
     ALT1            = %1110_1010_1010_1010
     ALT2            = %1101_0101_0101_0101
     DELAY           = 30  ' 1/30 second 
     SHORT_DELAY     = 60  ' 1/60 second 
     REPEAT_COUNT    = 2
     FLASH_COUNT     = 50 
     NUM_OUTPUTS     = 14
     NUM_SWITCHES    = 2
     MODE1           = %0000_0000_0000_0000 
     MODE2           = %0100_0000_0000_0000 
     MODE3           = %1000_0000_0000_0000 
     MODE4           = %1100_0000_0000_0000 
                     '  hw   a0-2  r/w
     DEVICE          = %0100__000__0
    OBJ
      io   : "pca9555"
      'term : "vga_text"
    PUB start | i, in
      'term.start(16)
      io.start(14, 15)
      ' LED test is all output.
      'term.str(string(13, "io.dir: "))
      'term.dec(io.setDir(DEVICE, DIRECTION))
      'term.str(string(13, "io.getDir: %"))
      'term.bin(io.getDir(DEVICE), 16)
      io.setDir(DEVICE, DIRECTION)
      repeat
        in := io.getIn(DEVICE) & DIRECTION
        'term.str(string(13, "in(bin): %"))         
        'term.bin(in, 16)
        'term.str(string(13, "in(dec): "))         
        'term.dec(in)
        ' Default.
        if in == MODE4
          'term.str(string(13, "MODE4"))
          repeat REPEAT_COUNT
            io.setOut(DEVICE, ALL_OFF)
            repeat i from 0 to NUM_OUTPUTS
              io.setOut(DEVICE, !(1 << i))
              waitcnt(CNT + (CLKFREQ / DELAY))
              in := io.getIn(DEVICE) & DIRECTION
              if in <> MODE4
                quit
            if in <> MODE4
              quit
            repeat i from NUM_OUTPUTS to 0 
              io.setOut(DEVICE, !(1 << i))
              waitcnt(CNT + (CLKFREQ / DELAY))
              in := io.getIn(DEVICE) & DIRECTION
              if in <> MODE4
                quit
            if in <> MODE4
              quit
     
        ' Inverse.
        elseif in == MODE3
          'term.str(string(13, "MODE3"))
          repeat REPEAT_COUNT
            io.setOut(DEVICE, ALL_ON)
            repeat i from 0 to NUM_OUTPUTS
              io.setOut(DEVICE, 1 << i)
              waitcnt(CNT + (CLKFREQ / DELAY))
              in := io.getIn(DEVICE) & DIRECTION
              if in <> MODE3
                quit
            if in <> MODE3
              quit
            repeat i from NUM_OUTPUTS to 0
              io.setOut(DEVICE, 1 << i)
              waitcnt(CNT + (CLKFREQ / DELAY))
              in := io.getIn(DEVICE) & DIRECTION
              if in <> MODE3
                quit
            if in <> MODE3
              quit
     
        ' Flashy
        elseif in == MODE2
          'term.str(string(13, "MODE2"))
          repeat i from 0 to FLASH_COUNT
            if (i // 2) == 0
              io.setOut(DEVICE, ALT1)
            else
              io.setOut(DEVICE, ALT2)
            waitcnt(CNT + (CLKFREQ / SHORT_DELAY))
            in := io.getIn(DEVICE) & DIRECTION
            if in <> MODE2
              quit
        ' Solid
        elseif in == MODE1
          'term.str(string(13, "MODE1"))
          repeat REPEAT_COUNT
            io.setOut(DEVICE, ALL_ON)
            waitcnt(CNT + (CLKFREQ / SHORT_DELAY))
            in := io.getIn(DEVICE) & DIRECTION
            if in <> MODE1
              quit 
    

    pca9555.spin
    {{
      PCA9555 Driver By Dave Fletcher
      A .600 mil DIP-24 version of this chip currently costs $1.66 US from DigiKey.
      Based on Minimal I2C driver 2008-01 by deSilva
      [URL]http://forums.parallax.com/forums/default.aspx?f=25&m=244743[/URL]
    }}
    CON
      INPORT0  = 0 ' Input port 0
      INPORT1  = 1 ' Input port 1
      OUTPORT0 = 2 ' Output port 0
      OUTPORT1 = 3 ' Output port 1
      POLINV0  = 4 ' Polarity Inversion port 0
      POLINV1  = 5 ' Polarity Inversion port 1
      CONF0    = 6 ' Configuration port 0
      CONF1    = 7 ' Configuration port 1
    VAR
      LONG scl
      LONG sda
    PUB start(_scl, _sda)
      scl := _scl
      sda := _sda
    PUB setDir(addr, value)
      return writecmd(addr, CONF0, CONF1, value)
    PUB getDir(addr)
      return readcmd(addr, CONF0, CONF1)
    PUB setOut(addr, value)   
      return writecmd(addr, OUTPORT0, OUTPORT1, value)
    PUB getOut(addr)
      return readcmd(addr, OUTPORT0, OUTPORT1) 
     
    PUB setPolInv(addr, value) : recvd
      return writecmd(addr, POLINV0, POLINV1, value)
    PUB getPolInv(addr)
      return readcmd(addr, POLINV0, POLINV1) 
     
    PUB getIn(addr) : recvd
      return readcmd(addr, INPORT0, INPORT1) 
    PRI writecmd(addr, cmdlow, cmdhigh, value) : status | high, low
      status := 0
      high := (value & %1111_1111_0000_0000) >> 8 
      low  := value & %0000_0000_1111_1111
      status := _writecmd(addr, cmdlow, low)
      status |= _writecmd(addr, cmdhigh, high) 
     
    PRI _writecmd(addr, command, value) : status
      engage 
      status := snd(addr)
      status |= snd(command)
      status |= snd(value)
      release
    PRI readcmd(addr, cmdlow, cmdhigh) : retval
      retval := _readcmd(addr, cmdhigh)
      retval <<= 8
      retval |= _readcmd(addr, cmdlow)
    PRI _readcmd(addr, command) : retval | status, high, low
      retval := 0
      engage 
      status := snd(addr)
      status |= snd(command)
      engage 
      status |= snd(addr+1)
      retval := rcv
      release
     
    PRI engage
      ' Pulls sda to LOW whilst CLK is HIGH
       dira[scl]~~                     
       outa[sda]~  
      ' The former two instructions need be done only once, if all is o.k.
       outa[scl]~~   
       dira[sda]~    ' Pulse sda; HIGH by pullup (default)
       dira[sda]~~   ' Enable = LOW
       outa[scl]~    ' Keep scl LOW
     
    PRI snd(by) : status 
      status := 0
      ' Send a byte (and get status: 0: ACK  1: NAK)
      by := (!by) >< 8             ' Reverse bits and invert pattern
      repeat 8       
        dira[sda] := by
        outa[scl]~~                ' Transfer on rising edge
        by >>= 1
        outa[scl]~ 
      ' Returns "acknowledge bit": 0 = ACK, 1 = NAK.
      dira[sda]~            ' release sda
      outa[scl]~~           ' puls-in ACK
      status := ina[sda]
      outa[scl]~            ' keep CLK low
     
    PRI release
      ' Assert stop condition.
      ' sda transits from LOW to HIGH whilst scl is HIGH
      dira[sda]~~           ' LOW
      outa[scl]~~
      dira[sda]~            ' release sda (HIGH)
     
    PRI rcv : val
      val := 0
      ' Get a byte
      repeat 8
        outa[scl]~~        ' Request bit
        val <<= 1
        val |= ina[sda]
        outa[scl]~         ' Keep CLK low
    PRI nak
      ' Send ackbit
      dira[sda]~~           ' LOW
      outa[scl]~~           ' Pulse scl
      outa[scl]~            ' keep CLK low
      dira[sda]~            ' release sda
     
    PRI ack
      ' Send ackbit
      dira[sda]~          ' HIGH
      outa[scl]~~         ' Pulse scl
      outa[scl]~          ' keep CLK low 
      dira[sda]~          ' release sda
    

    Help is appreciated. I am getting activity on the SDA and SCL lines. Should I instead rewire the LED's to ground and set the IO lines to outputs? Is the code missing something?
  • RaymanRayman Posts: 14,992
    edited 2011-05-01 22:00
    Well, the usual things are to try using pull-up resistors (~10k) on both lines. Make sure the device is rated for 3.3V, maybe it needs 5V?

    Also, make sure you don't have something like a PCA9555A, with a different i2c address...

    Can you read anything from the chip?
  • Jorge PJorge P Posts: 385
    edited 2011-05-02 04:05
    Fianaly success. The jumper I used on Pin 23-SDA on the chip to the pullup resister was broken, no continuity. I tried the 10k pullups to start with, but the 2K pullups seem to work fine.

    Edit:

    The IC's are PCA9555N, I think it is time to invest in some 22awg stranded wire instead of solid. Now I will try to connect the 16Segment LED display with a couple of these and try to get a DMM schematic wired up as I2C, I'll post in the Projects section or my Blog once I get something working if anyone is interested...

    Thanks for the Input Rayman.

    Oh, By the way, There is no code in obex for the PCA9555 IC, if the author is still around can you add this driver and demo to OBEX?
Sign In or Register to comment.