Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    pyscan EXPANDER IO BUT0-BUT7

    Scheduled Pinned Locked Moved Expansion Board
    pyscan5v toleranceexternal pins
    11 Posts 3 Posters 1.0k Views 3 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T Offline
      theshade
      last edited by theshade

      Hello all,

      Looking at the pinout of the PYSCAN here:
      https://docs.pycom.io/.gitbook/assets/pyscan-pinout.pdf
      it does clearly represent some BUT0-BUT7 IO pins
      Looking into the chip marking I found out it is a PCA9554 which is great because it seems its IO are 5 V tolerant according to the datasheet which is great because I need to interface some relays (albeit with opto couplers but the logic still uses 5V) and some down voltage converters enable pins...
      So far so good. But there seem to be a serious lack of documentation, I2C address of the PCA9554, maybe examples on how to use it... A small library would even be great!! Any hint on how to use it would be just fine!!

      I found some example code here, but it would only work if the I2C address is the same and the I2C bus is on the PYCOM.
      https://github.com/kaelmik/amp/blob/master/pca9554.py

      Thank you

      1 Reply Last reply Reply Quote 0
      • P Offline
        Paul Thornton
        last edited by

        Hey,

        Apologies for the slow response. the team took a look at the thread and suggested a few things:

        Datasheet for the PCA is available here: http://www.ti.com/lit/ds/symlink/pca9554.pdf

        Use I2C commands to interact with IO Expander, A2,A1,A0=Low so the address is 20 (HEX). Then the registers are described in the chapter 8.3 of the datasheet.

        An example library lives here: https://github.com/kaelmik/amp/blob/master/pca9554.py which shouldn’t be too difficult to rewrite for MicroPython

        Hopefully this is some help. Any other querys and Ill gladly take them back to the team :)

        T John BairdJ 3 Replies Last reply Reply Quote 0
        • T Offline
          theshade @Paul Thornton
          last edited by

          @paul-thornton Thank you now worries, that is all I needed to get started!!

          1 Reply Last reply Reply Quote 0
          • T Offline
            theshade @Paul Thornton
            last edited by

            @paul-thornton

            Hey Paul,
            in the process of getting started with this I tried to update the firmware / dfu of my pyscan
            according to this:
            https://docs.pycom.io/pytrackpysense/installation/firmware.html
            unfortunately the link is missing and I am unable to find the dfu for the pyscan...
            not even being able to find the firmware for a released product seems odd to me... Can you help or is it somewhere hidden. I searched most if not all of the GIT and forum but can't still find it.

            Cheers

            P 1 Reply Last reply Reply Quote 0
            • P Offline
              Paul Thornton @theshade
              last edited by

              @theshade I dont think we have ever released an upgraded firmware for the pyscan. I think the version you have installed is likely to be the latest version I will how ever confirm this with the team.

              T 1 Reply Last reply Reply Quote 0
              • T Offline
                theshade @Paul Thornton
                last edited by theshade

                @paul-thornton
                Hey Paul, You are probably right about the no upgraded firmware. But just in case someone flashes the DFU with a wrong version.. it would be cool to be able find the current and only one somewhere I guess.

                P 1 Reply Last reply Reply Quote 0
                • P Offline
                  Paul Thornton @theshade
                  last edited by

                  @theshade Yeah your right. Ill look into getting it sorted!

                  1 Reply Last reply Reply Quote 0
                  • T Offline
                    theshade
                    last edited by theshade

                    This is the ported lib to use the expander IO

                    ################################################################################
                    # Author			: akael "ported" by theshade
                    # Creation date 		: 02.02.2019
                    # Langage			: microPython
                    # Filename			: pca9554.py
                    # Target		 		: Pycom pyscan
                    # Description		: PCA9554A GPIO Expander
                    ################################################################################
                    
                    import time
                    from machine import I2C
                    
                    
                    IN = const(1)
                    OUT = const(0)
                    #"""
                    #Pca9554 (8 bit I2C expander)
                    #"""
                    class PCA9554():
                        #Define register
                        Pca9554_IN_REG = const(0x00) #Input register
                        Pca9554_OUT_REG = const(0x01) #Output register
                        Pca9554_POL_REG = const(0x02) #Polarity inversion register (1=data inverted)
                        Pca9554_DIR_REG = const(0x03) #Config register (0=output, 1=input)
                        Pca9554_I2CADDR = const(0x20)
                        i2c_bus=-1
                        i2c_address=-1
                        line=0xFF
                    	#def __init__(self, bus_id=0,address=0x39,line=0, direction="Null"):
                        def __init__(self, line=0x00, direction=1, sda = 'P22', scl = 'P21'):
                            #if pysense is not None:
                            #   self.i2c = pyscan.i2c
                            #else:
                            self.i2c = I2C(0, mode=I2C.MASTER, pins=(sda, scl))
                            #self.i2c_bus = smbus.SMBus(bus_id)
                    		#Pca9554_I2CADDR=address
                            print(line)
                            self.line=line
                            print(self.line)
                            print('setting direction')
                            if direction == 1:
                                self.setinput()
                            if direction == 0:
                                self.setoutput()
                    
                            time.sleep(0.01)
                    
                    	def set_dir_reg(self, value):
                    		#"""set direction register : 0=output, 1=input"""
                    		self.i2c.writeto_mem(Pca9554_I2CADDR, Pca9554_DIR_REG, value)
                    
                            #"""set bit as output"""
                        def setoutput(self):
                            print('setting output to')
                            currentvalue = self.i2c.readfrom_mem(Pca9554_I2CADDR , Pca9554_DIR_REG, 1)
                            print(currentvalue[0] | (0x01<<self.line))
                            self.i2c.writeto_mem(Pca9554_I2CADDR, Pca9554_DIR_REG , currentvalue[0] & 255-(1<<self.line))
                    
                            #"""set bit as input"""
                        def setinput(self):
                            print('setting input to')
                            currentvalue = self.i2c.readfrom_mem(Pca9554_I2CADDR , Pca9554_DIR_REG, 1)
                            print(currentvalue[0] | (0x01<<self.line))
                            self.i2c.writeto_mem(Pca9554_I2CADDR, Pca9554_DIR_REG ,currentvalue[0] | (0x01<<self.line))
                            #self.i2c.writeto_mem(Pca9554_I2CADDR, Pca9554_DIR_REG , self.line)
                    
                        def writebyte(self,value):
                    		#"""write output byte value"""
                    		self.i2c.writeto_mem(Pca9554_I2CADDR, Pca9554_OUT_REG, value)
                    		return
                        def readbyte(self):
                    		#"""read input byte value"""
                            return self.i2c.readfrom_mem(Pca9554_I2CADDR, Pca9554_IN_REG,1)
                    
                        def set(self):
                            #"""set output bit at 1"""
                            currentvalue = self.i2c.readfrom_mem(Pca9554_I2CADDR, Pca9554_OUT_REG,1)
                            #self.i2c.writeto_mem(Pca9554_I2CADDR, Pca9554_OUT_REG, 1<<2)
                            self.i2c.writeto_mem(Pca9554_I2CADDR, Pca9554_OUT_REG, currentvalue[0] | 1<<self.line)
                    
                        def reset(self):
                    		#"""reset output bit at 0"""
                    		currentvalue = self.i2c.readfrom_mem(Pca9554_I2CADDR, Pca9554_OUT_REG,1)
                    		self.i2c.writeto_mem(Pca9554_I2CADDR, Pca9554_OUT_REG, currentvalue[0] & (255-(1<<self.line)))
                    		return
                        def get(self):
                    		#"""read input bit value"""
                    		linevalue = self.i2c.readfrom_mem(Pca9554_I2CADDR, Pca9554_IN_REG,1)
                    		ret = ((linevalue >> self.line) & 1 )
                    		return ret
                    
                    1 Reply Last reply Reply Quote 1
                    • T Offline
                      theshade
                      last edited by

                      @theshade

                      I just tried the lib with the folowing main.py and line1 seems to switch every second.
                      pca9554.py micropython ported lib is not tested but apparently works enough for me.

                      import time
                      from PCA9554 import PCA9554
                      
                      line1 = PCA9554(line=1, direction=0)
                      
                      while True:
                          line1.set()
                          time.sleep(1)
                          line1.reset()
                          time.sleep(1)
                      1 Reply Last reply Reply Quote 0
                      • T Offline
                        theshade
                        last edited by

                        Dear @paul-thornton,

                        Now that the library porting works I need to look into the hardware, I figured that the best I could do to use those ports is to make my own "intermediate" PCB to access them and fan them out.
                        I also want to access other pins which on the fipy so putting a board inbetween seems to be the best option.
                        Anyway since the pins don't seem to be aligned on any particular grid, would it be possible to share the mechanical drawing of the connectors dxf, gerber or kicad format ?
                        Thank you

                        1 Reply Last reply Reply Quote 0
                        • John BairdJ Offline
                          John Baird @Paul Thornton
                          last edited by

                          @Paul-Thornton Thanks for the pointers and @theshade thanks for the library.

                          Can we find out how this works in deepsleep? Questions such as:
                          Does the PCA remain powered up?
                          Can we choose to power it down if we aren't using it?
                          Can the PCA interrupt line be used? If so how?
                          Can the PCA interrupt signal the PIC to wake the main processor from deepsleep?
                          If so, how do we establish why we woke from deepsleep? Can the PIC tell us?

                          Or perhaps you could just give us the schematics/PIC code and we could figure it out ;-)

                          Thanks!!

                          1 Reply Last reply Reply Quote 0

                          Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                          Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                          With your input, this post could be even better đź’—

                          Register Login
                          • 1 / 1
                          • First post
                            Last post

                          Pycom on Twitter

                          Pycom