connecting 3 units of MPR121 to MEGA

ey,

ive managed to connect a sparkfun MPR121 breakout board and make it work.
now in a bit of challenge to connect 3 units of MPR121 breakout boards to an Arduino Mega.

wiring - what should i do ? - a diagram could help.

code - what should i add in the code in order to make all the electrodes work ?
im using the original example code :
https://cdn.sparkfun.com/assets/d/f/3/7/9/524ef2da757b7f8e178b4568.zip

/*Copyright (c) 2010 bildr community

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "mpr121.h"
#include <Wire.h>

int irqpin = 2; // Digital 2
boolean touchStates[12]; //to keep track of the previous touch states

void setup(){
pinMode(irqpin, INPUT);
digitalWrite(irqpin, HIGH); //enable pullup resistor

Serial.begin(9600);
Wire.begin();

mpr121_setup();
}

void loop(){
readTouchInputs();
}

void readTouchInputs(){
if(!checkInterrupt()){

//read the touch state from the MPR121
Wire.requestFrom(0x5A,2);

byte LSB = Wire.read();
byte MSB = Wire.read();

uint16_t touched = ((MSB << 8) | LSB); //16bits that make up the touch states

for (int i=0; i < 12; i++){ // Check what electrodes were pressed
if(touched & (1<<i)){

if(touchStates == 0){

  • //pin i was just touched*
  • Serial.print("pin ");*
  • Serial.print(i);*
  • Serial.println(" was just touched");*

_ }else if(touchStates == 1){_
* //pin i is still being touched*
* } *

_ touchStates = 1;
}else{

if(touchStates == 1){
* Serial.print("pin ");
Serial.print(i);
Serial.println(" is no longer being touched");*_

* //pin i is no longer being touched*
* }*

_ touchStates = 0;
* }*_

* }*

* }*
}
void mpr121_setup(void){
* set_register(0x5A, ELE_CFG, 0x00);*

* // Section A - Controls filtering when data is > baseline.*
* set_register(0x5A, MHD_R, 0x01);
set_register(0x5A, NHD_R, 0x01);
set_register(0x5A, NCL_R, 0x00);
set_register(0x5A, FDL_R, 0x00);
_ // Section B - Controls filtering when data is < baseline._
set_register(0x5A, MHD_F, 0x01);
set_register(0x5A, NHD_F, 0x01);
set_register(0x5A, NCL_F, 0xFF);
set_register(0x5A, FDL_F, 0x02);*

* // Section C - Sets touch and release thresholds for each electrode*
* set_register(0x5A, ELE0_T, TOU_THRESH);
set_register(0x5A, ELE0_R, REL_THRESH);*

* set_register(0x5A, ELE1_T, TOU_THRESH);
set_register(0x5A, ELE1_R, REL_THRESH);*

* set_register(0x5A, ELE2_T, TOU_THRESH);
set_register(0x5A, ELE2_R, REL_THRESH);*

* set_register(0x5A, ELE3_T, TOU_THRESH);
set_register(0x5A, ELE3_R, REL_THRESH);*

* set_register(0x5A, ELE4_T, TOU_THRESH);
set_register(0x5A, ELE4_R, REL_THRESH);*

* set_register(0x5A, ELE5_T, TOU_THRESH);
set_register(0x5A, ELE5_R, REL_THRESH);*

* set_register(0x5A, ELE6_T, TOU_THRESH);
set_register(0x5A, ELE6_R, REL_THRESH);*

* set_register(0x5A, ELE7_T, TOU_THRESH);
set_register(0x5A, ELE7_R, REL_THRESH);*

* set_register(0x5A, ELE8_T, TOU_THRESH);
set_register(0x5A, ELE8_R, REL_THRESH);*

* set_register(0x5A, ELE9_T, TOU_THRESH);
set_register(0x5A, ELE9_R, REL_THRESH);*

* set_register(0x5A, ELE10_T, TOU_THRESH);
set_register(0x5A, ELE10_R, REL_THRESH);*

* set_register(0x5A, ELE11_T, TOU_THRESH);
set_register(0x5A, ELE11_R, REL_THRESH);*

* // Section D*
* // Set the Filter Configuration*
* // Set ESI2*
* set_register(0x5A, FIL_CFG, 0x04);*

* // Section E*
* // Electrode Configuration*
* // Set ELE_CFG to 0x00 to return to standby mode*
* set_register(0x5A, ELE_CFG, 0x0C); // Enables all 12 Electrodes*

* // Section F*
* // Enable Auto Config and auto Reconfig*
/set_register(0x5A, ATO_CFG0, 0x0B);
set_register(0x5A, ATO_CFGU, 0xC9); // USL = (Vdd-0.7)/vdd256 = 0xC9 @3.3V set_register(0x5A, ATO_CFGL, 0x82); // LSL = 0.65USL = 0x82 @3.3V
set_register(0x5A, ATO_CFGT, 0xB5);/ // Target = 0.9*USL = 0xB5 @3.3V

* set_register(0x5A, ELE_CFG, 0x0C);*

}
boolean checkInterrupt(void){
* return digitalRead(irqpin);*
}
void set_register(int address, unsigned char r, unsigned char v){
* Wire.beginTransmission(address);*
* Wire.write(r);*
* Wire.write(v);*
* Wire.endTransmission();*
}
Thanks

Please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum Your code is too long to study quickly without copying to a text editor.

Please tell us what an MPR121 is and provide a link to its datasheet.

...R

It appears that the MPR121 is an I2C device. If you can adjust the I2C address on the device, set them to three different addresses. If the chip only supports one address, add an I2C multiplexer chip so you can switch between them.

The pin Number 4 (ADDR) of the MPR121 is the one used for selecting an I2C address. If you connect that PIN 4 to VSS (Ground), VDD, SDA, SCL then you set the board address to be 0x5A, 0x5B, 0x5C, 0x5D respectively.

When you purchase the SParkfun board an address jumper ties the ADD pin to ground (VSS), meaning the default I2C address of the chip will be 0x5A.

In order to use 2 other boards, You will need to change their addresses to something else by shorting ADD to a different pin. What you need to do is cut the existing trace of the ADD jumper (the one that connects ADD to ground and thus makes the address 0x5A) and then solder a wire (insulated) or plug a wire between the ADD connector and SDA on your breadboard (the pin next to ADD) to get address 0x5C

On your third unit repeat the operation but connect to SCL instead of SDA (the next pin) to get 0x5D

from a wiring perspective, connect the 2 new units with the different addresses exactly at the same arduino pins as the first one except for the IRQ wire. instead of going to pin 2, go to other pins - let's call them pinA and pinB

Now you have your devices with 3 different I2C address and the Wire library will let you address each of them separately

Note that in the existing sample code you have this line:

  if(!checkInterrupt()){

which is defined as

boolean checkInterrupt(void){
  return digitalRead(irqpin);
}

so just reading pin2 actually and checking if it is HIGH or LOW.

That means the code you have does not use interrupts, just polls the pins to see if something has been pressed.

Your code also uses this later on

    //read the touch state from the MPR121
    Wire.requestFrom(0x5A,2);

that means that if pin2 was high, some data was waiting on that device and you want to read 2 bytes from the I2C device with address 0x5A.

So now that we know how this works - you need to duplicate that a bit and come up with code that:

check pin 2 as today to see if it's high. if it is, do what is in the example

check pinA to see if it's high. if it is, duplicate what is in the example and read from slave unit at 0x5C instead

check pinB to see if it's high. if it is, duplicate what is in the example and read from slave unit at 0x5D instead

hope this helps

Would be interesting to hear back from you. Did that work?