PDA

View Full Version : I/O extender



mychangl
- 1st January 2008, 07:19
Happy New Year to all....

Currently, i am still using pic16f84a for my project due to smaller size and no special task require. However the only problem is limited I/O. I also plan to migrate to pic16f628 soon. I/O still a problem for me. I have gone through some article to expand I/O however it is very limited. Is there any way to increase it to 32 or 64 ? How ?

Thx..

mackrackit
- 1st January 2008, 07:46
It depends on what you want to do with the I/Os.

An RC network using the ADC or POT or RCTIME for inputs.

Outputs could be a "matrix" http://www.mackrackit.com/mac/www/dave/LED/LEDs.html

But shift registers are I think the best, they can be used for both in and out. Three pins from the PIC can be turned into eight outputs. Four pins can be turned into 16 outputs by sharing the clock an load pins on the registers.

Example for reading one register.


Clock var PORTB.7

Load var PORTB.6

Data_1 var PORTB.5

pulsout Load,1

shiftin Data_1,Clock,MSBPre,[keys]

Luciano
- 1st January 2008, 08:48
Hi,

See the Microchip MCP23016. (16-bit bidirectional I/O port expander).

You can address up to eight MCP23016 in your system so this
will give you up to 128 I/O pins.

Microchip MCP23016 16-Bit I2C™ I/O Expander
http://ww1.microchip.com/downloads/en/DeviceDoc/20090b.pdf

Interfacing The MCP23016 I/O Expander with the PIC16F877A:
http://ww1.microchip.com/downloads/en/AppNotes/00245a.pdf


* * *

There is also a version with an 8-bit bidirectional I/O port.

Microchip MCP23008 8-Bit I/O Expander with I2C Interface
http://ww1.microchip.com/downloads/en/DeviceDoc/21919e.pdf

Best regards,

Luciano

mychangl
- 1st January 2008, 14:30
Thx Mackrackit.
It only High and Low I/O. i think shift register would be a good idea. 4 to 8 lines. Bringing total of 128 bit of I/O. Meaning total pin require is 7 ( 4 for address, Clock, Load and Serial Data ). Am i right ?

Thx Luciano for the suggestion. It really a new thing for me. But why both MCP23008 and MCP23016 have 3 addresses ? Can MCP23016 work with 16f84a ?

ronjodu
- 1st January 2008, 14:38
I use 3 of the Maxim Max6957's for a total of 60 additional I/O's with only 3 PIC pins thru SPI interface. They also have a I2C version. In my app. 52 are used for LED's and 8 will be used for relays. TFM is a bit intimidating at first. I could post some code if interested.

Hope this helps.

!!!!!!!!!!!! Happy New Year to All !!!!!!!!!!!!!!

mychangl
- 1st January 2008, 15:27
Interesting. If it is feasible, why not. However I just checked with our local distributor and they do not have max6957. Perhaps i should keep looking for the availability. I keep that in mind. Thx Ronjodu

Luciano
- 1st January 2008, 15:30
Thx Luciano for the suggestion. It really a new thing for me.
But why both MCP23008 and MCP23016 have 3 addresses ?
Can MCP23016 work with 16f84a ?

Hi,


With three address lines you can set the address of up to eight devices.

Binary / Decimal
============
000 = 0
001 = 1
010 = 2
011 = 3
100 = 4
101 = 5
110 = 6
111 = 7

The MCP23016 will work with the 16f84a.
Use the software I2C commands of PicBasic Pro. (I2CIN and I2COUT).

* * *

See also this: (Basic Stamp + MCP23016).
http://www.parallax.com/dl/docs/cols/nv/vol5/col/nv109.pdf

Best regards,

Luciano

mackrackit
- 1st January 2008, 19:15
Thx Mackrackit.
It only High and Low I/O. i think shift register would be a good idea. 4 to 8 lines. Bringing total of 128 bit of I/O. Meaning total pin require is 7 ( 4 for address, Clock, Load and Serial Data ). Am i right ?

Thx Luciano for the suggestion. It really a new thing for me. But why both MCP23008 and MCP23016 have 3 addresses ? Can MCP23016 work with 16f84a ?
If you go with shift registers you will need a clock/load set for inputs and one for outputs.
Look at a HC595 for output and HC165 for inputs (I think, been awhile)

The solution that Luciano gave looks nice. I did not know about these chips. Learned something new and it is the fisrt day of the year:) Off to a good start.

mister_e
- 1st January 2008, 19:26
Those microchip I/O extender are really nice. In the past i also used PCF8574A, maybe easier to find it locally 'cause it's a very old one.. still popular i guess.

mychangl
- 2nd January 2008, 17:22
Use the software I2C commands of PicBasic Pro. (I2CIN and I2COUT).



Do you mean I2Read and I2Write ?
Sorry i am not familiar with it. However i would like to try.

Correct me if i am wrong.
From datasheet,
control 0h and 1h is to read or write to the ports
control 6h and 7h is to set port as input or output

Given scenario 1 :
Connect 23016 address as $01
Assign GP0.0 to GP0.7 as input (control address is 6h)
Assign GP1.0 to GP1.7 as output (control address is 7h)

the code will be :
addr var byte
addr=01
I2CWRITE DataPin,ClockPin,06,addr,[FF]
I2CWRITE DataPin,ClockPin,07,addr,[00]

Scenario 2 :
Read the data on GP0.0 to GP0.7 and put inside Sample1

the code will be :
I2CREAD DataPin,ClockPin,00,addr,[Sample1]

Scenario 3 :
Write data 44h on GP1.0 to GP1.7

the code will be :
I2CWRITE DataPin,ClockPin,00,addr,[44]

Luciano
- 2nd January 2008, 18:24
Hi,

Yes, with PicBasic Pro use I2CREAD and I2CWRITE.
(I2CIN and I2COUT are for the PicBasic compiler).

Best regards,

Luciano

mychangl
- 8th November 2008, 19:42
I took longer time to try out with MCP23016 because i am still using shift register to expand the I/O. Last week i decided to try out MCP23016. However it doesn't work, after few days trial & error and change the address, i almost give up. Not sure what happen. either the code or the IC faulty because i only have one piece.

Can someone advice ?
Appreciate that.


'MASTER CODE
'This test is to check output functionality ( LED ) - Running LED
'MCP23016 connected to address 0

INCLUDE "modedefs.bas"


'*****PORT Setup********************************************* *****************
GreenLED VAR PORTA.0'O Indicator Green
SDA VAR PORTA.1 'O Serial Data
SCL VAR PORTA.2 'O Serial Clock
RedLED VAR PORTA.3 'O Indicator Red

'*****Constant************************************ ****************************
CtrlRW1 CON 00 'Access to Set1 GP0
CtrlRW2 CON 01 'Access to Set2 GP1
CtrlDir1 CON 06 'Access to Set1 IODIR/0
CtrlDir2 CON 07 'Access to Set2 IODIR/1


'**VARIABLES************************************** ****************************
Address VAR BYTE 'Address size
Set1 VAR BYTE 'Place to put Data Set1
Set2 VAR BYTE 'Place to put Data Set2

Address=0 'Select MCP23016 address as 0

Set1=0 'Clear Set1
Set2=0 'Clear Set2


'*****INITIALIZING MCP23016 All as Output**************************************
I2CWrite SDA,SCL,CtrlDir1,Address,[00] 'Set as Output
Pause 10 'Delay 10ms
I2CWrite SDA,SCL,CtrlDir2,Address,[00] 'Set as Output
Pause 10 'Delay 10ms


Start :
Set1=$FF 'To turn on all LEDs connected to Set1
Set2=$FF 'TO turn ON all LEDs connected TO Set2

I2CWrite SDA,SCL,CtrlRW1,Address,[Set1] 'Turn on the LEDs
Pause 10 'Wait 10ms

I2CWrite SDA,SCL,CtrlRW2,Address,[Set2] 'Turn on the LEDs
Pause 10 'Wait 10ms


GoTo Start

keymuu
- 8th November 2008, 21:26
......
'*****INITIALIZING MCP23016 All as Output**************************************
I2CWrite SDA,SCL,CtrlDir1,Address,[00] 'Set as Output
Pause 10 'Delay 10ms
I2CWrite SDA,SCL,CtrlDir2,Address,[00] 'Set as Output
Pause 10 'Delay 10ms


Start :
Set1=$FF 'To turn on all LEDs connected to Set1
Set2=$FF 'TO turn ON all LEDs connected TO Set2

I2CWrite SDA,SCL,CtrlRW1,Address,[Set1] 'Turn on the LEDs
Pause 10 'Wait 10ms

I2CWrite SDA,SCL,CtrlRW2,Address,[Set2] 'Turn on the LEDs
Pause 10 'Wait 10ms

GoTo Start
You could have a label after the line where to jump if an error occurs with I2C, like this:
I2CWrite SDA,SCL,CtrlRW1,Address,[Set1], errorLabel
...
errorLabel:
LCDOUT "Error....

Melanie
- 9th November 2008, 16:37
The MCP23008 works reliably using I2C without any additional external components, but is quite intollerant of noise on the Supply Lines, and has a habit of 'locking-up' pulling down the supply rail when this happens.

eggman
- 9th November 2008, 16:39
There is a newer version from microchip: MCP23017
It has an internal oscillator, no external C and R needed, also the pin layout is a bit nicer. I also had problems getting a MCP23016 to work reliably, finally it worked best without any timing C connected.

mychangl
- 12th November 2008, 15:34
Thanks, i'll try MCP23017.

I know what going on wrong with the code...

3 things been observed :
1. I do not put "$" to determine the address in HEX
2. Before initializing MCP23016, it need to have short delay ( i use 50ms ) otherwise the whole program will not work.
3. The code should be I2CWrite SDA,SCL,Address,CtrlDir1,[00] not I2CWrite SDA,SCL,CtrlDir1,Address,[00]. This is confusing because the manual shows the address come after Control, but it does not work.

It works fine after the correction.



I need help to evaluate my second code.
I use GP1 as input and GP0 as output.

However this is what happened :

Input Triggered | Output Respond
----------------+-----------------
GP1.0 | No Respond
GP1.1 | GP0.0
GP1.2 | GP0.1
GP1.3 | GP0.2
GP1.4 | GP0.3
GP1.5 | GP0.4
GP1.6 | GP0.5
GP1.7 | GP0.6

GP0.7 never respond at all.

Anyone can help ?




INCLUDE "modedefs.bas"

'*****STARTUP************************************* ****************************
TRISA=%00000
TRISB=%00000000

'*****PORT Setup********************************************* *****************
SDA VAR PORTA.1 'O Serial Data
SCL VAR PORTA.2 'O Serial Clock

'*****Constant************************************ ****************************
CtrlRW1 CON 00 'Set1
CtrlRW2 CON 01 'Set2
CtrlDir1 CON 06 'Set1
CtrlDir2 CON 07 'Set2


'**VARIABLES************************************** ****************************
Address VAR BYTE 'Address size
Set VAR BYTE 'Temporary place to put Data

Address=$40 'Set MCP23016 address as 01
Set=$00 'Clear Temporary Storage


'*****INITIALIZING MCP23016 **************************************************
Pause 50
I2CWrite SDA,SCL,Address,CtrlDir1,[00] 'Set as Output
Pause 10 'Delay 10ms
I2CWrite SDA,SCL,Address,CtrlDir2,[$FF] 'Set as Input
Pause 10 'Delay 10ms

Start :
I2CRead SDA,SCL,Address,CtrlRW2,[Set] 'Read from input, put in Set
Pause 10 'Delay 10ms

I2CWrite SDA,SCL,Address,CtrlRW1,[Set] 'Write data into Set
Pause 10 'Delay 10ms

GoTo Start

eggman
- 12th November 2008, 20:31
What values do you use for the timing R and C? I also had problems with some of the bits not reading well, finally I used 3900 Ohms for the resistor and no C at all. Also you could try to add this line: DEFINE I2C_HOLD 1 (see pbp manual), it worked for me when I increased the clock speed of my pic to 20MHz.

mychangl
- 20th November 2008, 14:56
Surprisingly, it works when i removed the capacitor. Resistor remains 3.9K.
The code also works fine with or without the capacitor.

Thanks again..