I need to use multiple(4) MPR121 breakout boards to get 48 sensor pins. There is a possibility to use 4 boards by different addresses with single Arduino. However I can not find any instructions beyond this initial statement. Adafruit has the addresses according to ADD pull-up listed at least.
My first question is: as by default ADD pin is connected to GRD with 100k resistor do I need to unsolder it(if I find it) and connect it to the other pins as instructed. Or I just connect pins without the resistor?
The MPR121 ADDR pin is pulled to ground and has a default I2C address of 0x5A
You can adjust the I2C address by connecting ADDR to other pins:
ADDR not connected: 0x5A
ADDR tied to 3V: 0x5B
ADDR tied to SDA: 0x5C
ADDR tied to SCL: 0x5D
Secondly: the CapSens board connects to 2 analog A4 & A5
SCL - I2C clock pin, connect to your microcontrollers I2C clock line.
SDA - I2C data pin, connect to your microcontrollers I2C data line
and 1 digital pin D2
IRQ is the Interrupt Request signal pin. It is pulled up to 3.3V on the breakout and when the sensor chip detects a change in the touch sense switches, the pin goes to 0V until the data is read over i2c
on the Arduino.
Do additional boards need 2 analog and 1 dig. pin of their own?
I've had a quick look at the data sheet, although I have not used this board :
In the case that you are using multiple MPR121 boards, you simply make the required connections to give each board a unique I2C address. You do not remove any resistors. The value of 100K has been chosen to be high enough that a pin can be pulled high with 100K and the same pin also connected directly to ground (or elsewhere) without doing any harm.
IC2 is a shared bus so from your Uno, a connection from A4 is made to the SDA pin on each MPR121 board. A5 likewise is conneced to the SCL on each MPR121 board.
The interrupt pin is not well described, but I guess that that multiple MPR121 boards can share the same pin on the (D2) on the Uno. I guess it is also optional. The example breadboard layout did not show it in use
When you are defining the MPR121 boards in your sketch, you'll do something like this:
For me Adafruit MPR121 library forks the best(also with Sparkfun and clone boards).
When using Chinese clones you need to note that most of these are hardwired ADD to GND, so for multiple board setup you need to cut these connections. The best is to cut between two solder-pads at ADD pin and connect accordingly to 3.3V; SCL; SDA to get different addresses.
Original Adafruit MPR121 board need no cutting - just wire ADD....
Here is a test code to check if your boards are working. To get touch info you need to create function for each board in void loop()
/*********************************************************
This is a library for the MPR121 12-channel Capacitive touch sensor
Designed specifically to work with the MPR121 Breakout in the Adafruit shop
----> https://www.adafruit.com/products/
These sensors use I2C communicate, at least 2 pins are required
to interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
**********************************************************/
#include <Wire.h>
#include "Adafruit_MPR121.h"
// You can have up to 4 on one i2c bus but one is enough for testing!
Adafruit_MPR121 cap1 = Adafruit_MPR121();
Adafruit_MPR121 cap2 = Adafruit_MPR121();
Adafruit_MPR121 cap3 = Adafruit_MPR121();
Adafruit_MPR121 cap4 = Adafruit_MPR121();
void setup() {
Serial.begin(9600);
Serial.println("TEST");
// Default address is 0x5A, if tied to 3.3V its 0x5B
// If tied to SDA its 0x5C and if SCL then 0x5D
if (!cap1.begin(0x5A)) {
Serial.println("A no");
if (1);
}
Serial.println("A yes");
if (!cap2.begin(0x5B)) {
Serial.println("B no");
if (1);
}
Serial.println("B yes");
if (!cap3.begin(0x5C)) {
Serial.println("C no");
if (1);
}
Serial.println("C yes");
if (!cap4.begin(0x5D)) {
Serial.println("D no");
if (1);
}
Serial.println("D yes");
}
void loop() {
return;
}
I had big problem with my installation where all 4 boards were inside separate objects connected to Arduino with 5 lead cables. People were mucking with the cables resulting nothing to work. To avoid this and to be able to plug in boards on the fly I did this:
I altered the Adafruit_MPR121.cpp - replaced while() with if() in board responds section. while() made the system hang if it found any board missing.
Also I put board checking routine into void loop() so this will enable to remove and add boards on the fly (hot plugin).
#include <Wire.h>
#include "Adafruit_MPR121.h"
//MPR121 library is altered to avoid hangup if board is missing
//in Adafruit_MPR121.ccp while() is replaced with if()
// You can have up to 4 on one i2c bus
Adafruit_MPR121 cap = Adafruit_MPR121();
Adafruit_MPR121 cap2 = Adafruit_MPR121();
Adafruit_MPR121 cap3 = Adafruit_MPR121();
Adafruit_MPR121 cap4 = Adafruit_MPR121();
// Keeps track of the last pins touched
// so we know when buttons are 'released'
uint16_t lasttouched = 0;
uint16_t currtouched = 0;
uint16_t lasttouched2 = 0;
uint16_t currtouched2 = 0;
uint16_t lasttouched3 = 0;
uint16_t currtouched3 = 0;
uint16_t lasttouched4 = 0;
uint16_t currtouched4 = 0;
////////////////////////////////////
void setup() {
Serial.begin(9600);
}
void loop() {
// this is inside the loop so you can plug boards hot
// if you do not need hot plugin you may put it in setup()
cap.begin(0x5A);
cap2.begin(0x5C);
cap4.begin(0x5B);
cap3.begin(0x5D);
// Get the currently touched pads
currtouched = cap.touched();
currtouched2 = cap2.touched();
currtouched3 = cap3.touched();
currtouched4 = cap4.touched();
for (uint8_t i=0; i<12; i++) {
if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
//when sensor is touched do something
}
if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
//when sensor in no longer touched do something
}
//2///////////////////////////////////////////////////
if ((currtouched2 & _BV(i)) && !(lasttouched2 & _BV(i)) ) {
//when sensor is touched do something
}
if (!(currtouched2 & _BV(i)) && (lasttouched2 & _BV(i)) ) {
//when sensor in no longer touched do something
}
//3///////////////////////////////////////////////////
if ((currtouched3 & _BV(i)) && !(lasttouched3 & _BV(i)) ) {
//when sensor is touched do something
}
if (!(currtouched2 & _BV(i)) && (lasttouched2 & _BV(i)) ) {
//when sensor in no longer touched do something
}
//4///////////////////////////////////////////////////
if ((currtouched4 & _BV(i)) && !(lasttouched4 & _BV(i)) ) {
//when sensor is touched do something
}
if (!(currtouched2 & _BV(i)) && (lasttouched2 & _BV(i)) ) {
//when sensor in no longer touched do something
}
}
// reset our state
lasttouched = currtouched;
lasttouched2 = currtouched2;
lasttouched3 = currtouched3;
lasttouched4 = currtouched4;
return;
}
Hi!
I know it's been a while since someone posted here but I tried the examples you gave above and I'm getting the following output:
TEST
A no
A yes
B no
B yes
C no
C yes
D no
D yes
Do you have any idea of what is causing this?
I've tried multiple libraries and multiple sketches and the problem appears to be the address but I don't know what else to do.