User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

16 Channel GPIO Input Expander

Tue May 27, 2014 2:29 pm

Here's a 'simple' design to allow 16 digital inputs using just 5 of the GPIO ports.
CD4067B Schematic(2).gif
GPIO Expander
CD4067B Schematic(2).gif (25.36 KiB) Viewed 3066 times
And here's the code...

Code: Select all

# ************************************************
# * SAMPLE PROGRAM FOR USING THE CD4067B IC AS A *
# * GPIO INPUT PORT EXPANDER.  THIS PROVIDES 16  *
# * DIGITAL INPUTS USING JUST 5 GPIO PORT LINES. *
# ************************************************
# * GPIO PORTS USED:                             *
# *                                              *
# * GPIO25 - Pin 10 of the CD4067B (LSB Address) *
# * GPIO24 - Pin 11 of the CD4067B               *
# * GPIO23 - Pin 14 of the CD4067B               *
# * GPIO22 - Pin 13 of the CD4067B (MSB Address) *
# * GPIO7 - Pin 1 of the CD4067B (common in/out).*
# *                                              *
# * Please read the manufacturers data sheet for *
# * full details of the CD4067B CMOS device.     *
# ************************************************


import RPi.GPIO as GPIO                             # Import the GPIO driver module as 'GPIO'

import time                                         # Import the 'time' module

GPIO.setmode (GPIO.BCM)                             # Set the GPIO port mode to BCM numbering

input_port = 7                                      # Set the GPIO input port

output_ports = [22, 23, 24, 25]                     # Set the GPIO output ports (MSB first)

for bit in output_ports:
    GPIO.setup (bit,GPIO.OUT)
    GPIO.output (bit,0)

GPIO.setup (input_port,GPIO.IN, pull_up_down = GPIO.PUD_DOWN)

# ------------------------------------------------
# START OF FUNCTION

# ************************************************
# * Function to read the values on all sixteen   *
# * input channels of the CD4067B IC.  On exit,  *
# * this returns a value between 0 and 65535     *
# * depending on the bit value of each input.    *
# ************************************************

def input_value():
    
    global input_port, output_ports                 # Allow access to the external constants
    value = 0                                       # Set the initial input value to zero
    for z in range (16):                            # Select the CD4067B channel address (0 to 15)
        b = bin (z)                                 # Turn it into a binary string
        b = b [2:len(b)]                            # Strip off the '0b' from the start of it
        b = b.zfill(4)                              # If needed, pad out the left side with zero's
        print ("Channel "),                         # Remove this line to prevent screen printing
        if z > 9:                                   # Remove this line to prevent screen printing
            print ("\b\b"),                         # Remove this line to prevent screen printing
        print (z), ("("), b, (") ="),               # Remove this line to prevent screen printing
        
# 'b' contains a binary string 4 characters long.
# Use this to turn on the GPIO output ports to
# set the address of the current channel (0 to 15)
# Because the GPIO ports cannot be turned on or 
# off in parallel mode (all bits at once), we have
# to turn them on or off one bit at a time.

        x = 0                                       # Pointer into the binary string
        for bit in output_ports:                    # Select the required GPIO port
            output_state = int (b[x])               # Select whether it should be a '1' or '0'
            GPIO.output (bit,output_state)          # Turn on or off the relevant GPIO bit
            x = x + 1                               # Move the pointer to the next bit

# The four GPIO address lines are now set.
# Now get the value from the CD4067 input channel.
# This will be either '0' or '1'.  If it's '0'
# then ignore it.  If it's '1' then add the
# binary bit value to the returned value until
# all sixteen channels have been scanned.

        print (GPIO.input(input_port))              # Remove this line to prevent screen printing
        if GPIO.input (input_port):                 # If the CD4067B channel input is high (1)
            value = value + 2 ** z                  # then add the binary bit value to 'value'

    return (value)                                  # Exit with the CD4067B input value

# END OF FUNCTION
# ------------------------------------------------

# ************************************************
# * SAMPLE TEST ROUTINE TO DISPLAY INPUT VALUES  *
# ************************************************

while True:                                         # Run an infinite loop
    a = input_value()                               # Get the CD4067B input value
    print ("CD4067B Input Value ="),a,("\n")        # Print it
    time.sleep (1)                                  # Wait for a second in order to at
                                                    # least make the results readable!


I've produced an entire educational MS Word document covering this project, complete with photographs. But I don't know how I can include it here. Can someone help me out?
Electronics... It's what I do!

User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 2:31 pm

Oh, the picture's been screwed up. It shouldn't be that tiny!

Will this work I wonder... ?

http://www.carol-anne-dolls.co.uk/Raspb ... pander.doc
Electronics... It's what I do!

User avatar
Burngate
Posts: 5967
Joined: Thu Sep 29, 2011 4:34 pm
Location: Berkshire UK Tralfamadore
Contact: Website

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 3:50 pm

SavagePi wrote:Oh, the picture's been screwed up. It shouldn't be that tiny!
It looks okay to me - but I'm using prosilver; others may see it differently
No it didn't - at least for me! It wanted to open in Libre Office, which couldn't make sense of it

User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 4:18 pm

Burngate wrote:
SavagePi wrote:Oh, the picture's been screwed up. It shouldn't be that tiny!
It looks okay to me - but I'm using prosilver; others may see it differently
No it didn't - at least for me! It wanted to open in Libre Office, which couldn't make sense of it
It's a standard MS Word document with a few photo's included. Maybe Libre Office couldn't handle it?
Electronics... It's what I do!

User avatar
FLYFISH TECHNOLOGIES
Posts: 1750
Joined: Thu Oct 03, 2013 7:48 am
Location: Ljubljana, Slovenia
Contact: Website

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 4:21 pm

Hi,
SavagePi wrote:It's a standard MS Word document.
Use a format which is really standardized... ;-) PDF comes to mind.


Best wisehs, Ivan Zilic.
Running out of GPIO pins and/or need to read analog values?
Solution: http://www.flyfish-tech.com/FF32

User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 4:30 pm

Okay. I've converted it to PDF.

Does this work...?

http://www.carol-anne-dolls.co.uk/Raspb ... pander.pdf
Electronics... It's what I do!

User avatar
mikronauts
Posts: 2717
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 4:34 pm

Worked for me.
SavagePi wrote:Okay. I've converted it to PDF.

Does this work...?

http://www.carol-anne-dolls.co.uk/Raspb ... pander.pdf
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

User avatar
FLYFISH TECHNOLOGIES
Posts: 1750
Joined: Thu Oct 03, 2013 7:48 am
Location: Ljubljana, Slovenia
Contact: Website

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 4:53 pm

Hi,
SavagePi wrote:Does this work...?
... better... when you'll replace/remove whitespace from file name(s), you'll become even more user-friendly. ;-)

Few quick hints:
1) you can attach switches to 3.3V instead of 5V and overcome potential diff issue,
2) even better - you can supply the CD4067B with 3.3V (TI's version can be supplied with voltages from 3.0V to 18.0V),
3) optionally (a kind of taste) I prefer pull-ups instead of pull-downs. The reason is that logical high voltage range is wider (with all positive consequences that this causes)
.. and, .. lastly, a single resistor in the circuit can do the job ! ;-)


Best wishes, Ivan Zilic.
Running out of GPIO pins and/or need to read analog values?
Solution: http://www.flyfish-tech.com/FF32

User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 5:41 pm

I understand all your points, Ivan. But that was not the object of my project. It was intended to explain various aspects of electronics design using CMOS IC's.

I disagree with your use of positive voltage as a pull-up reference, since positive supplies can vary, whereas 0V is absolute in all circuits.

In your last comment, you mention that a single resistor in the circuit can do the job. Where would you impliment this single resistor?
Electronics... It's what I do!

User avatar
FLYFISH TECHNOLOGIES
Posts: 1750
Joined: Thu Oct 03, 2013 7:48 am
Location: Ljubljana, Slovenia
Contact: Website

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 5:55 pm

Hi,
SavagePi wrote:Where would you impliment this single resistor?
Place the single resistor as pull-up resistor (value like 4k7 to 10k) on the chip's output pin (which is directly connected to GPIO input pin). 16 switches are connected towards ground.


Best wishes, Ivan Zilic.
Running out of GPIO pins and/or need to read analog values?
Solution: http://www.flyfish-tech.com/FF32

User avatar
Richard-TX
Posts: 1549
Joined: Tue May 28, 2013 3:24 pm
Location: North Texas

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 6:03 pm

I think it would be a lot easier to use a MCP23017 plus it would only occupy 2 GPIO pins leaving the rest for other things.
Last edited by Richard-TX on Tue May 27, 2014 7:01 pm, edited 1 time in total.
Richard
Doing Unix since 1985.
The 9-25-2013 image of Wheezy can be found at:
http://downloads.raspberrypi.org/raspbian/images/raspbian-2013-09-27/2013-09-25-wheezy-raspbian.zip

User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 6:14 pm

FLYFISH TECHNOLOGIES wrote:Hi,
SavagePi wrote:Where would you impliment this single resistor?
Place the single resistor as pull-up resistor (value like 4k7 to 10k) on the chip's output pin (which is directly connected to GPIO input pin). 16 switches are connected towards ground.


Best wishes, Ivan Zilic.

That's not good practice with any CMOS device. That would leave all 16 inputs 'floating' when all switches are open. That's very bad practice with CMOS.
Electronics... It's what I do!

User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 6:17 pm

Richard-TX wrote:I think it would be a lot easier to use a MCP233017 plus it would only occupy 2 GPIO pins leaving the rest for other things.
That's another possibility, Richard. I was just presenting a circuit idea.
Electronics... It's what I do!

User avatar
FLYFISH TECHNOLOGIES
Posts: 1750
Joined: Thu Oct 03, 2013 7:48 am
Location: Ljubljana, Slovenia
Contact: Website

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 6:23 pm

Hi,
SavagePi wrote:That's not good practice with any CMOS device. That would leave all 16 inputs 'floating' when all switches are open. That's very bad practice with CMOS.
These 16 pins are not (logic) inputs, they are one side of analog switches instead.

I agree that it's not good practice to leave floating inputs, but this is not the case here.


Best wishes, Ivan Zilic.
Running out of GPIO pins and/or need to read analog values?
Solution: http://www.flyfish-tech.com/FF32

User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 6:39 pm

I understand that, Ivan. And I explained this in my PDF version...

http://www.carol-anne-dolls.co.uk/Raspb ... pander.pdf

I know it's not important in this particular application. But it's important that users know about the general use of CMOS IC's.

Also, what would the input reference point be with an open switch? A floating input with no defined value?
Electronics... It's what I do!

User avatar
FLYFISH TECHNOLOGIES
Posts: 1750
Joined: Thu Oct 03, 2013 7:48 am
Location: Ljubljana, Slovenia
Contact: Website

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 7:03 pm

Hi,
SavagePi wrote:I understand that
Ok, I'm glad that we both agree that an optimization with a single resistor is valid and compliant to good design practice.
SavagePi wrote:Also, what would the input reference point be with an open switch?
There is no reference, because... there is no reference. ;-)
Actually, the chip is not ideal and there are tiny leaks, but this is out of scope here.
SavagePi wrote:A floating input with no defined value?
At the time when you read any input, it has defined value (either low via shorted switch, or high through single pull-up).


Best wishes, Ivan Zilic.
Running out of GPIO pins and/or need to read analog values?
Solution: http://www.flyfish-tech.com/FF32

boyoh
Posts: 1316
Joined: Fri Nov 23, 2012 3:30 pm
Location: Selby. North Yorkshire .UK

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 7:12 pm

SavagePi wrote:Here's a 'simple' design to allow 16 digital inputs using just 5 of the GPIO ports.


I'm a bit confused of how you are using the CD4067B
I might be totally wrong, But I thought the A B C D
Are a 4bit binary in/put digital code , 1 0 1 0( ex sample )
To give you any 1 of 16 out/put from the CD4067B
Are you using It in reverse
CD4067B Schematic(2).gif
And here's the code...

Code: Select all

# ************************************************
# * SAMPLE PROGRAM FOR USING THE CD4067B IC AS A *
# * GPIO INPUT PORT EXPANDER.  THIS PROVIDES 16  *
# * DIGITAL INPUTS USING JUST 5 GPIO PORT LINES. *
# ************************************************
# * GPIO PORTS USED:                             *
# *                                              *
# * GPIO25 - Pin 10 of the CD4067B (LSB Address) *
# * GPIO24 - Pin 11 of the CD4067B               *
# * GPIO23 - Pin 14 of the CD4067B               *
# * GPIO22 - Pin 13 of the CD4067B (MSB Address) *
# * GPIO7 - Pin 1 of the CD4067B (common in/out).*
# *                                              *
# * Please read the manufacturers data sheet for *
# * full details of the CD4067B CMOS device.     *
# ************************************************


import RPi.GPIO as GPIO                             # Import the GPIO driver module as 'GPIO'

import time                                         # Import the 'time' module

GPIO.setmode (GPIO.BCM)                             # Set the GPIO port mode to BCM numbering

input_port = 7                                      # Set the GPIO input port

output_ports = [22, 23, 24, 25]                     # Set the GPIO output ports (MSB first)

for bit in output_ports:
    GPIO.setup (bit,GPIO.OUT)
    GPIO.output (bit,0)

GPIO.setup (input_port,GPIO.IN, pull_up_down = GPIO.PUD_DOWN)

# ------------------------------------------------
# START OF FUNCTION

# ************************************************
# * Function to read the values on all sixteen   *
# * input channels of the CD4067B IC.  On exit,  *
# * this returns a value between 0 and 65535     *
# * depending on the bit value of each input.    *
# ************************************************

def input_value():
    
    global input_port, output_ports                 # Allow access to the external constants
    value = 0                                       # Set the initial input value to zero
    for z in range (16):                            # Select the CD4067B channel address (0 to 15)
        b = bin (z)                                 # Turn it into a binary string
        b = b [2:len(b)]                            # Strip off the '0b' from the start of it
        b = b.zfill(4)                              # If needed, pad out the left side with zero's
        print ("Channel "),                         # Remove this line to prevent screen printing
        if z > 9:                                   # Remove this line to prevent screen printing
            print ("\b\b"),                         # Remove this line to prevent screen printing
        print (z), ("("), b, (") ="),               # Remove this line to prevent screen printing
        
# 'b' contains a binary string 4 characters long.
# Use this to turn on the GPIO output ports to
# set the address of the current channel (0 to 15)
# Because the GPIO ports cannot be turned on or 
# off in parallel mode (all bits at once), we have
# to turn them on or off one bit at a time.

        x = 0                                       # Pointer into the binary string
        for bit in output_ports:                    # Select the required GPIO port
            output_state = int (b[x])               # Select whether it should be a '1' or '0'
            GPIO.output (bit,output_state)          # Turn on or off the relevant GPIO bit
            x = x + 1                               # Move the pointer to the next bit

# The four GPIO address lines are now set.
# Now get the value from the CD4067 input channel.
# This will be either '0' or '1'.  If it's '0'
# then ignore it.  If it's '1' then add the
# binary bit value to the returned value until
# all sixteen channels have been scanned.

        print (GPIO.input(input_port))              # Remove this line to prevent screen printing
        if GPIO.input (input_port):                 # If the CD4067B channel input is high (1)
            value = value + 2 ** z                  # then add the binary bit value to 'value'

    return (value)                                  # Exit with the CD4067B input value

# END OF FUNCTION
# ------------------------------------------------

# ************************************************
# * SAMPLE TEST ROUTINE TO DISPLAY INPUT VALUES  *
# ************************************************

while True:                                         # Run an infinite loop
    a = input_value()                               # Get the CD4067B input value
    print ("CD4067B Input Value ="),a,("\n")        # Print it
    time.sleep (1)                                  # Wait for a second in order to at
                                                    # least make the results readable!


I've produced an entire educational MS Word document covering this project, complete with photographs. But I don't know how I can include it here. Can someone help me out?
BoyOh ( Selby, North Yorkshire.UK)
Some Times Right Some Times Wrong

User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 8:30 pm

Not at all, boyoh.

The assignment of the GPIO bits are purely for convenience of programming:

GPIO25 = A (1)
GPIO24 = B (2)
GPIO23 = C (4)
GPIO22 = D (8)

It actually doesn't matter which GPIO ports are used, as long as they're defined in the first place. The reason I defined them in reverse order was because it makes the program easier to write.
Electronics... It's what I do!

boyoh
Posts: 1316
Joined: Fri Nov 23, 2012 3:30 pm
Location: Selby. North Yorkshire .UK

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 11:00 pm

SavagePi wrote:Not at all, boyoh.

The assignment of the GPIO bits are purely for convenience of programming:

GPIO25 = A (1)
GPIO24 = B (2)
GPIO23 = C (4)
GPIO22 = D (8)

It actually doesn't matter which GPIO ports are used, as long as they're defined in the first place. The reason I defined them in reverse order was because it makes the program easier to write.

The IC getting very hot for no aperant reason
Could this be due to fact that most current
Is demanded at the peak of signal change
With the signal changing very fast
BoyOh ( Selby, North Yorkshire.UK)
Some Times Right Some Times Wrong

User avatar
FLYFISH TECHNOLOGIES
Posts: 1750
Joined: Thu Oct 03, 2013 7:48 am
Location: Ljubljana, Slovenia
Contact: Website

Re: 16 Channel GPIO Input Expander

Tue May 27, 2014 11:37 pm

Hi,
boyoh wrote:The IC getting very hot for no aperant reason
Could this be due to fact that most current Is demanded at the peak of signal change With the signal changing very fast
I doubt. These signals don't drive any outputs (loads).
I'd assume you have either broken chip or there is a connection/junction mistake.


Best wishes, Ivan Zilic.
Running out of GPIO pins and/or need to read analog values?
Solution: http://www.flyfish-tech.com/FF32

User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

Re: 16 Channel GPIO Input Expander

Wed May 28, 2014 4:22 pm

FLYFISH TECHNOLOGIES wrote:Hi,

I doubt. These signals don't drive any outputs (loads).
I'd assume you have either broken chip or there is a connection/junction mistake.


Best wishes, Ivan Zilic.
I agree with Ivan here. This situation shouldn't be a problem with the 4067. As I mention in my PDF version, this mainly occurs with CMOS logic gate IC's when unused inputs are left floating. It's akin to putting your foot flat down on the accelerator of a car and leaving it there. Eventually, the engine will burn out!

Also, ensure C1 is fitted across the supply rails.
Electronics... It's what I do!

kourpetis
Posts: 50
Joined: Sat Oct 03, 2015 12:16 pm

Re: 16 Channel GPIO Input Expander

Sun Feb 07, 2016 1:09 am

Could i connect a MPC3002 https://www.sparkfun.com/products/8636 to the output of this multiplexor and read 16 analog devices with my raspberry pi 2 ?

asandford
Posts: 1997
Joined: Mon Dec 31, 2012 12:54 pm
Location: Waterlooville

Re: 16 Channel GPIO Input Expander

Sun Feb 07, 2016 1:52 am

kourpetis wrote:Could i connect a MPC3002 https://www.sparkfun.com/products/8636 to the output of this multiplexor and read 16 analog devices with my raspberry pi 2 ?
No. The MPC3002 uses SPI.

kourpetis
Posts: 50
Joined: Sat Oct 03, 2015 12:16 pm

Re: 16 Channel GPIO Input Expander

Sun Feb 07, 2016 2:01 am

it uses SPI to connect with the raspberry pi, but it reads analog. If the multiplexor is feeding it with analog wouldn't i get those reading through the ADC to my raspberry pi GPIO ?

kourpetis
Posts: 50
Joined: Sat Oct 03, 2015 12:16 pm

Re: 16 Channel GPIO Input Expander

Sun Feb 07, 2016 2:06 am

The purpose is to read 16 analog devices, the GPIOS can tell to the multiplexer witch channel to read and provide this read to the ADC, then through SPI i can read that particular channel. Am i right ? am i missing something here ?

Return to “Other projects”