adressing MPR121 sensors through PCF8575 breakoutboard

I now want to connect four MPR121 sensor boards to the PCF8575 breakoutboard. (Sparkfun)
Without the PCF8575, the mpr121 code worked perfect. (http://code.bildr.org/download/1010.zip) However with the PCF8575 board I need to alter the addressing within the code. The SDA and SCL lines of the MPR121 boards I have connected to the PCF8575 board. See image. (http://forum.bildr.org/download/file.php?id=174)

But how should I address and read these pins?

The MPR121 (http://www.freescale.com/files/sensors/doc/data_sheet/MPR121.pdf) is a I2C capacitive touch sensor chip and the PCF8575 (http://www.ti.com/lit/ds/symlink/pcf8575.pdf) is a I2C to 16 GPIO expander (did you notice the links? Should have been added by you!). Both can be at the I2C at the same time and I don't see why the MPR121 has to be connected over the PCF8575, it won't work the way you're doing it. You can connect 4 MPR121 directly to the I2C by selecting the address with different connections of the ADDR pin.

BTW: you should use external pull-ups for the I2C (4k7).

Thanks for your response and my excuses for not adding the links.

What I will do is change the addresses of the boards by shorting the ADD to a different pin.
However to change the address of the chip (by shorting ADD to a different pin), I have to open the jumper first. How do I open the jumper? Which trace should be cut?

On the bottom of the breakout you have two solder pads with a thin connection between them. Cut that through (it connects ADD to GND) for the three modules you want to change the address for. Then connect the pin with Vcc, SCL or SDA (for the three versions).
Also the modules have pull-ups for the I2C installed. Cut these (also on the bottom aside the pins) for all but one module (or all if you install pull-ups yourself).

I cut the connection between the solder pads. (ADD to GND) Then connected the pin with Vcc, SCL or SDA (for the different versions). I tested each of the boards and this seems to work fine.

I have not yet cut the pull-ups for the I2C installed. Is this really necessary? If so, are these the four shorter lines which have the little whole at the end of it? Or the three which are longer and move to the side of the board?

If so, are these the four shorter lines which have the little whole at the end of it? Or the three which are longer and move to the side of the board?

On the bottom of the module you have four pairs of solder pads, each connected with a thin line of copper. One is the connection of the ADD to GND, the others are the pull-ups of SCL, SDA and INT. Cut the copper line for SDA and SCL.

I have not yet cut the pull-ups for the I2C installed. Is this really necessary?

On a I2C bus you should have the pull-up resistors only once per bus. The modules have 10k pull-ups, the Arduino internal pull-up is about the same value. Together that results in a total of 2k pull-up resistor for each line. That results in a current the active bus device has to sink that is over the I2C specification. That means the device may be harmed by the bus operation. Although I don't think that the small over-limit current destroys one of your devices, it's better to do it right, isn't it?

Thanks, that makes sense. I will cut the pull-ups for SCL and SDA!

I want to connect four MPR121 boards (SparkFun Capacitive Touch Sensor Breakout - MPR121 - SEN-09695 - SparkFun Electronics) to an arduino uno. I changed the jumpers and have tested the address of each individual board and these work. (Test code: http://code.bildr.org/download/1010.zip)

However, when I try to use the code (attachment) to address and read all of the four sensors, it doesn't work. Even if I only attach one sensor using this code, it will not work. Any suggestions what can be wrong?

mpr121_touch.ino (11.2 KB)

I would expect that the first sensor does work with this code, all the other don't.

boolean checkInterrupt(void){
  return digitalRead(irqpin1);
  return digitalRead(irqpin2);
  return digitalRead(irqpin2);
  return digitalRead(irqpin4);
}

Only irqpin1 is checked, the other digitalRead()s are never reached.

Try to integrate your readTouchInputs1-4 functions into one. Learn to use arrays:

byte irqpin[] = { 2, 3, 4, 5 };
byte sensoraddr[] = { 0x5A, 0x5B, 0x5C, 0x5D };

void readTouchInputs(byte sensor) {
  if (! checkInterrupt(sensor)) {
    Wire.beginTransmission(sensoraddr[sensor]);
    Wire.write(0x00); // choose register 0 (start of touch status)
    Wire.endTransmission();
    Wire.requestFrom(sensoraddr[sensor], 2); // the second parameter is the number of bytes to read!
    byte LSB = Wire.read();
    byte MSB = Wire.read();
    uint16_t touched = ((MSB << 8) | LSB);
    // rest of your code
...

Fixed it!
Here's the code, for those interested:

mpr121_touch.ino (4.54 KB)

I am now however facing a different problem.
For some reason the serial communication between Arduino and Max sometimes seems to miss some data.
This results in sensors staying high, even though they are not touched anymore.

Therefore I would like to alter the arduino code, so the status for each sensor get continuously updated.
For example every 40ms the output of every sensor gets printed. How should I alter the code to print the data continuously?

mpr121_touch.ino (4.69 KB)

For example every 40ms the output of every sensor gets printed. How should I alter the code to print the data continuously?

"Every 40 seconds" is NOT "continuously".

That's correct.
I would prefer the data to be send continuously.
However, that would probably give an information overload as the data will be transported to Max/MSP, and the serial object has some trouble receiving all the data.
So I'll be more than happy with every 40ms.

  pinMode(irqpin[0], INPUT);
  pinMode(irqpin[1], INPUT);
  pinMode(irqpin[2], INPUT);
  pinMode(irqpin[3], INPUT);
  
  digitalWrite(irqpin[0], HIGH); //enable pullup resistor
  digitalWrite(irqpin[1], HIGH); //enable pullup resistor
  digitalWrite(irqpin[2], HIGH); //enable pullup resistor
  digitalWrite(irqpin[3], HIGH); //enable pullup resistor

You've met the for loop?

void loop(){
  readTouchInputs(0x5A, 1);
  readTouchInputs(0x5B, 2);
  readTouchInputs(0x5C, 3);
  readTouchInputs(0x5D, 4);
}


void readTouchInputs(int sensorAddress, int sensor){
  if(!checkInterrupt(sensor - 1)){

Wouldn't it make more sense to pass 0, 1, 2, and 3 to the function?

Shouldn't the function argument know, by having a meaningful name for the argument, whether the value is a pin number or an array index or the temperature in London last week?

      }else{

Ican'treadcodethatcontainsstufflikethis. In my opinion, NOTHING follows the } on the same line, except at the end of a do/while statement (which I never use).

Therefore I would like to alter the arduino code, so the status for each sensor get continuously updated.

Just remove the check for checkInterrupt() and you have a continuous update.

My opinion: fix the serial communication issue and don't introduce much unnecessary traffic.

I was wondering if you could answer my question.

http://forum.arduino.cc/index.php?topic=248970.msg1779209

I was just wondering how to change the address. I'm in need of a visual to help me understand what and where to connect.

Thanks

the same problem have been sloved here: MPR121 breakout - #5 by Elecrow - Sensors - Arduino Forum