Go Down

Topic: i2c port expander PCF8574 as input (Read 5 times) previous topic - next topic

Federico

Hi, I have a PCF8574p and I am using it with an lcd. This works fine.
The library that I use let a pin of the PCF, the 13, free.
I wish to use this pin of the port expander as an input pin, to read the pressure of a button, but I can't understand how, through the wire library (i think that i need this).
Is it possible to do this? Does anyone knows where I can look for understanding how to do this? Thanks, Fede
Federico - Sideralis
Arduino &C: http://www.sideralis.org
Foto: http://blackman.amicofigo.com

Nachtwind

Basically reading the pcf8574 is not so hard. I would need to dig up the code when i get home later, but basically it's described in the datasheet.
You might have problems IF you had to read a analog button - in that case its far mor difficult..
Believe me, Mike, I calculated the odds of this succeeding against the odds I was doing something incredibly stupid[ch8230] and I went ahead

Federico

I will be absolutly fine with a normal digital button :)
I need this button to change the state of the visualization on the lcd, but looks like every example on the forum is about using the expander as output, and not as input (on a single pin)
Federico - Sideralis
Arduino &C: http://www.sideralis.org
Foto: http://blackman.amicofigo.com

Mario_H

Federico,

Pin 13 is the interrupt output pin of the PCF.
(See page 11 of the PCF datasheet in the library download for details)
You can not reconfigure it for your use.

I suggest you don't use pin 12 for controlling the LCD backlight but instead use it for you button.
You may have to tweak the LCD library so it doesn't use pin 12 for output.

Federico

Hi Mario,
I have already planned not to use the backlight with your library because I will always need the backlight on. I could use the pin 12, but still I have to understand how. I am working on it...
Thanks, Fede
Federico - Sideralis
Arduino &C: http://www.sideralis.org
Foto: http://blackman.amicofigo.com

Yot

#5
Nov 01, 2009, 09:42 pm Last Edit: Nov 01, 2009, 09:42 pm by Yot Reason: 1
hi all,

In my project i use a pcf8574 as input for some buttons and use this code. It uses external interrupt 5 on my arduino. (edited: arduino Mega) The detach in the isr (expanderInterrupt()) gave me a somewhat debounced button.

hope it helped,

Jeroen

Quote

#include <Wire.h>
#define expander B00100000  //expander address

volatile byte count = 0;

void setup() {
 Wire.begin();
 Serial.begin(9600);
 expanderWrite(B11111111);
 attachInterrupt(5, expanderInterrupt, LOW);
}

void loop() {
  if(count = 1) {
    Serial.println(expanderRead(), BIN);
    count = 0;
    attachInterrupt(5, expanderInterrupt, LOW);
  }
}

void expanderInterrupt() {    
  detachInterrupt(5);
  count = 1;
}

void expanderWrite(byte _data ) {
  Wire.beginTransmission(expander);
  Wire.send(_data);
  Wire.endTransmission();
}

byte expanderRead() {
  byte _data;
  Wire.requestFrom(expander, 1);
  if(Wire.available()) {
    _data = Wire.receive();
  }
  return _data;
}


Federico

With the help of your code as test I have read a bit of documentation from the arduino site and now I am doing some test.
If I understand it right when I press the button, connected to ground, I receve a different binary number, so I can hook this to actions. Am I right?

Still have to test it, but can you tell me if the pin used from the arduino to the external interrupt is still usable?

Federico
Federico - Sideralis
Arduino &C: http://www.sideralis.org
Foto: http://blackman.amicofigo.com

Grumpy_Mike

Quote
when I press the button, connected to ground, I receve a different binary number


Yes but make sure that the input pin is also connected to +5V through a resistor of value 1K to 10K. This is called a pull up resistor and ensures that the number read back contains a logic one when the button is not pressed. When the button is pressed that bit of the number will read as a logic zero.

Yot

In addition to grumpy_mike also make sure you have a pull up resistor on the interrupt line coming from the pcf8574. I'm using 10K ohms connected to +5V.

Quote
but can you tell me if the pin used from the arduino to the external interrupt is still usable?


You could use it for other external interrupts but then you don't know what caused the interrupt. To keep it simple; No, the pin is not usable for anything else.

Grumpy_Mike

Quote
You could use it for other external interrupts but then you don't know what caused the interrupt.


Form the data sheet:-
Quote
An interrupt is generated by any rising or falling edge of the
port inputs in the input mode. After time tiv the signal INT is
valid.
Resetting and reactivating the interrupt circuit is achieved
when data on the port is changed to the original setting or
data is read from or written to the port which has generated
the interrupt.
Resetting occurs as follows:
· In the READ mode at the acknowledge bit after the rising
edge of the SCL signal
· In the WRITE mode at the acknowledge bit after the
HIGH-to-LOW transition of the SCL signal
· Interrupts which occur during the acknowledge clock
pulse may be lost (or very short) due to the resetting of
the interrupt during this pulse.
Each change of the I/Os after resetting will be detected
and, after the next rising clock edge, will be transmitted as
INT. Reading from or writing to another device does not
affect the interrupt circuit.


So in short if an input pin changes state this line goes low. You can then put this into one of the normal arduino pins and monitor that to see if an input has changed. This is a lot quicker than reading the I2C device itself.


Mario_H

@ Yot:
I assume
Code: [Select]
if(count = 1) {
in the code above is a typo?

Yot

#11
Nov 02, 2009, 06:50 pm Last Edit: Nov 02, 2009, 06:57 pm by Yot Reason: 1
yes it is (in shame) it should be ==

at Grumpy_Mike;

I know the expander can 'draw attention' by generating an interrupt on an arduino pin. I meant to say that in that setup you could use another device to generate an interrupt on the same arduino pin but then it wont be clear wich device caused the interrupt.

Jeroen

Federico

Thank you for discussing about this topic, I am learning many things.
By the way, still I can't undestanding I am doing it right. Following the code of Yot, in my serial debug I have
Code: [Select]

11001001
11001001
11001001
11001001
11001001

no stop (well, I have some wire attached to the expander)
When I press the button for less than one sec i have
Code: [Select]

1001001
1001001
1001001
1001001
1001001
1001001

So I can see that something change, and when I release my button I have again, over and over :) the code inserted at the top (11001001).
Is this supposed to be correct? It will be a little tricky to hook...

Federico
Federico - Sideralis
Arduino &C: http://www.sideralis.org
Foto: http://blackman.amicofigo.com

Yot

you did change
Code: [Select]
if(count = 1) {
to
Code: [Select]
if(count == 1) { ?

Terrible typo that gets me time and time again.

Also it took me a while to realise i didn't have a pullup resistor on the int. wire to the arduino external int. pin. That gave a lot of weard interrupts aswell. You have one in place?

Jeroen

Federico

I have correct the "==" typo, but my pullup resistor (10k) is from the +5v line to the INT on che PCF, I thought it was to set like this reading your post... I will change if connecting the pullup to the pin "2" on my arduino diecimila and test again tonight. I have changed the external interrupt from 5 to 0 if I can remeber exactly. I will check as soon as I came back home! Fede
Federico - Sideralis
Arduino &C: http://www.sideralis.org
Foto: http://blackman.amicofigo.com

Go Up