PCF8574 INT pin question - Rewritten for clarity
Please read update 2 for most current findings.
Update 1:
I currently have 2 PCF8974 IC2 Bus Expander chips wired up on pins 8, 9 for IC2 com and Pins 10 and 11 for their respective INT pins. I finally got the first chip to trigger Pin 10 but the second chip still will not trigger Pin 11. I have swaped the chips and have replaced them several times. The wiring is correct, also chip 1 is at %000 and chip 2 is at %001 for their addresses. They each have a 4.7K Pullup resistor for the INT pin 13.
Both chips can read their pins on a read routine. Chip 1 can run its read routine using an "if Pin10 = 0" statement with no problem. I dug up my old Logic probe and found that when I Make a change to the state of Bus 1 that I get 2 pulses and one LOW. I expect this as per the datasheet. On Bus 2 I get nothing, it stays High all the time, With one exeption and I find this quite strange:
1.) if I make a change to bus 1, bus 1 triggers PIN10 and I get 2 pulses and 1 LOW on my probe at Bus 1's INT pin
2.) then I make a change to bus 2 I trigger PIN11 but I only get one pulse and I do not get a Low on my probe at bus 2's INT pin.
3.) If I make another change to bus 2 I get no INT, No pules
Note I do get data back from #1 and #2 and nothing back from #3.
Once data has changed on bus 1 I can only get bus 2 to trigger 1 time until I trigger bus 1 again
Update 2:
I left my probe on Bus 2 INT Pin and when I make a change to bus 1 I get the 2 pulses and a low. I am now assuming that only the lowest addressed chip is in control of the INTerrupt. This will make my coding a bit more complex I'm thinking.
this is an example of my code:
Post Edited (RickH) : 5/26/2008 12:43:19 PM GMT
Update 1:
I currently have 2 PCF8974 IC2 Bus Expander chips wired up on pins 8, 9 for IC2 com and Pins 10 and 11 for their respective INT pins. I finally got the first chip to trigger Pin 10 but the second chip still will not trigger Pin 11. I have swaped the chips and have replaced them several times. The wiring is correct, also chip 1 is at %000 and chip 2 is at %001 for their addresses. They each have a 4.7K Pullup resistor for the INT pin 13.
Both chips can read their pins on a read routine. Chip 1 can run its read routine using an "if Pin10 = 0" statement with no problem. I dug up my old Logic probe and found that when I Make a change to the state of Bus 1 that I get 2 pulses and one LOW. I expect this as per the datasheet. On Bus 2 I get nothing, it stays High all the time, With one exeption and I find this quite strange:
1.) if I make a change to bus 1, bus 1 triggers PIN10 and I get 2 pulses and 1 LOW on my probe at Bus 1's INT pin
2.) then I make a change to bus 2 I trigger PIN11 but I only get one pulse and I do not get a Low on my probe at bus 2's INT pin.
3.) If I make another change to bus 2 I get no INT, No pules
Note I do get data back from #1 and #2 and nothing back from #3.
Once data has changed on bus 1 I can only get bus 2 to trigger 1 time until I trigger bus 1 again
Update 2:
I left my probe on Bus 2 INT Pin and when I make a change to bus 1 I get the 2 pulses and a low. I am now assuming that only the lowest addressed chip is in control of the INTerrupt. This will make my coding a bit more complex I'm thinking.
this is an example of my code:
I2Cpin CON 8 ' SDA on 0; SCL on 1 DevType CON %0111 << 4 ' Device type DevAddr1 CON %000 << 1 DevAddr2 CON %001 << 1 DevAddr3 CON %010 << 1 Rd8574_1 CON DevType | DevAddr1 | 1 ' read from PCF8574 Rd8574_2 CON DevType | DevAddr2 | 1 ' read from PCF8574 Wr8574_3 CON DevType | DevAddr3 ' write to PCF8574 IC2Inputs CON %11111111 IC2Outputs CON %00000000 ioByte1 VAR Byte ' i/o byte for PCF8574 ioByte2 VAR Byte ioByteArray VAR Bit(16) idx VAR Nib storage VAR Byte idxa VAR Nib INT1 PIN 10 INT2 PIN 11 Main: GOSUB Scan1 IF INT1 = 0 THEN DEBUG HOME DEBUG BIN INT1,CR GOSUB Buttons ENDIF IF INT2 = 0 THEN DEBUG HOME DEBUG BIN INT2,CR GOSUB Buttons2 ENDIF GOTO Main Buttons: I2CIN I2Cpin, Rd8574_1, (IC2Inputs), [noparse][[/noparse]ioByte1] ioByte1 = ~ioByte1 DEBUG HOME idxa = 0 FOR idx = 7 TO 0 storage = ioByte1 << idx storage = storage >> 7 ioByteArray(idxa) = storage idxa = idxa + 1 NEXT DEBUG CLS FOR idx = 0 TO 7 CCMod = idx + 16 IF ioBytearray(idx)= 1 THEN GOSUB MIDI_Output ENDIF DEBUG "bit: ", DEC idx, " Data: ", BIN ioBytearray(idx),CR NEXT I2COUT I2Cpin, Wr8574_3, (IC2Outputs), [noparse][[/noparse]ioByte1] RETURN Buttons2: I2CIN I2Cpin, Rd8574_2, (IC2Inputs), [noparse][[/noparse]ioByte2] ioByte2 = ~ioByte2 idxa = 8 FOR idx = 7 TO 0 storage = ioByte2 << idx storage = storage >> 7 ioByteArray(idxa) = storage idxa = idxa + 1 NEXT DEBUG CLS FOR idx = 8 TO 15 IF ioBytearray(idx)= 1 THEN GOSUB MIDI_Output ENDIF DEBUG "bit: ", DEC idx, " Data: ", BIN ioBytearray(idx),CR NEXT RETURN
Post Edited (RickH) : 5/26/2008 12:43:19 PM GMT
Comments
1.) Push a button on chip 1 (any of the 8) I get 2 pulses from my probe and a low on Input 10, nothing on Input 11
2.) Push a button on chip 2 (any of the 8) I get 1 Pulse and 1 low 1 time, it will not triger a second time until Chip 1 Changes state. I also get the same 1 low and 1 pulse from Pin 10 at the same time.
This is really messing my project up and I can not see using this IC2 chips without the INT working properly. If anyone has any suggestions I would be grateful.
There is supposed to be absolutely no interaction between the two chips from a hardware perspective.
I've not used these chips with a Stamp for a long time, but I use them with a Propeller currently and they appear to work the way the datasheet says.
My %000 chip works the way the data sheet says. Even if I swap the chips the first one works. Just not the second one.
Post Edited (RickH) : 5/26/2008 12:45:17 PM GMT
1) Do not include the state of the R/W bit in the I2C address. I think the statements strip this out, but they may not.
2) For some reason, you're using the register address field to write an output state to the PCF8574. This is unnecessary on an output cycle since (in your case) it will briefly force all the output pins to low, then set the output pins to the state you want. In the case of the I2CIN, you're writing an all ones value to the PCF8574, which does make the pins work as inputs, then doing a read cycle to fetch the pin states. Note that this forcing the output state first to zero, then back to one will cause an /INT pulse or two.
I would not use the register address field at all and just set the state of the PCF8574s during initialization
During the program initialization you'd do:
I2COUT I2Cpin, DevType | DevAddr1, [noparse][[/noparse]%11111111] ' Set device 1 to inputs
I2COUT I2Cpin, DevType | DevAddr2, [noparse][[/noparse]%11111111] ' Set device 2 to inputs
I2COUT I2Cpin, DevType | DevAddr3, [noparse][[/noparse]%00000000] ' Set device 3 to zero outputs
Note that you could also set device 3 to one bits if that's the output state you want.
Now to read the input state of either device 1 or device 2, you'd just do:
I2CIN I2Cpin, DevType | DevAddr1, [noparse][[/noparse]ioByte] ' Read the current state of device 1
I2CIN I2Cpin, DevType | DevAddr2, [noparse][[/noparse]ioByte] ' Read the current state of device 2
To change the current output state of device 3, you'd just do:
I2COUT I2Cpin, DevType | DevAddr3, [noparse][[/noparse]ioByte] ' Update the current state of device 3
The reason I put the direction in the register address field for directions is that is what is explained in N&V 79:
The suggestion from N&V#79 is not bad. It just mixes up several functions and, as in your situation, may cause things to not work or to work in strange and mysterious ways. In addition, it doesn't work as expected with writes (I2COUT).
Make sure you've wired the address pins (A0-A2) correctly.
Also, you don't need to include the R/W bit in your device addresses. The I2CIN and I2COUT statements force the bit value that's needed for the operation being performed.
I found this:
Post Edited (RickH) : 5/26/2008 3:19:37 PM GMT
as initalizing the chips and then:
But I still need to use the IC2OUT in every Subroutine or I will not get a proper INT back.
Also It gives me nothing when I initalize them with IC2OUT, I must use IC2IN to initialize them.