Pages: [1] 2   Go Down
Author Topic: i2c port expander PCF8574 as input  (Read 5510 times)
0 Members and 1 Guest are viewing this topic.
Milano, Italy
Offline Offline
Faraday Member
**
Karma: 11
Posts: 3091
Sideralis Arduino!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

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

Bonn, Germany
Offline Offline
God Member
*****
Karma: 2
Posts: 903
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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..
Logged

Believe me, Mike, I calculated the odds of this succeeding against the odds I was doing something incredibly stupid[ch8230] and I went ahead

Milano, Italy
Offline Offline
Faraday Member
**
Karma: 11
Posts: 3091
Sideralis Arduino!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I will be absolutly fine with a normal digital button smiley
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)
Logged

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

NL
Offline Offline
Newbie
*
Karma: 0
Posts: 37
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Milano, Italy
Offline Offline
Faraday Member
**
Karma: 11
Posts: 3091
Sideralis Arduino!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

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

Global Moderator
The Netherlands
Offline Offline
Sr. Member
*****
Karma: 1
Posts: 287
don't panic...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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;
}

« Last Edit: November 01, 2009, 03:42:58 pm by Yot » Logged

Milano, Italy
Offline Offline
Faraday Member
**
Karma: 11
Posts: 3091
Sideralis Arduino!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

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

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34726
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Global Moderator
The Netherlands
Offline Offline
Sr. Member
*****
Karma: 1
Posts: 287
don't panic...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34726
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Logged

NL
Offline Offline
Newbie
*
Karma: 0
Posts: 37
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
The Netherlands
Offline Offline
Sr. Member
*****
Karma: 1
Posts: 287
don't panic...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: November 02, 2009, 12:57:30 pm by Yot » Logged

Milano, Italy
Offline Offline
Faraday Member
**
Karma: 11
Posts: 3091
Sideralis Arduino!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
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 smiley the code inserted at the top (11001001).
Is this supposed to be correct? It will be a little tricky to hook...

Federico
Logged

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

Global Moderator
The Netherlands
Offline Offline
Sr. Member
*****
Karma: 1
Posts: 287
don't panic...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

you did change
Code:
if(count = 1) {

to
Code:
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
Logged

Milano, Italy
Offline Offline
Faraday Member
**
Karma: 11
Posts: 3091
Sideralis Arduino!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

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

Pages: [1] 2   Go Up
Jump to: