2 mpr121 sensors in one arduino -> serial communication

cancel
Showing results for 
Search instead for 
Did you mean: 

2 mpr121 sensors in one arduino -> serial communication

858 Views
Contributor I

I am trying to connect 2(0x5A, 0x5B)addresses.

In the code and  datasheet,  it says just connecting addr pin to (default, 3.3v) allows communication.

Arduino recognizes other sensors, however, it cannot read the two touch sensor at one time. just tells me i=0 ~ 11

how can I make the i=12~23 run?

and how can I differentiate 2 sensors in code?

Is it possible to communicate mpr121 sensor to mpr121 sensor ? 

I really want to know how to connect two sensors in one arduino.

I also tried i2c scanner to check the wiring

and weird thing is that serial monitor only tells me just one sensor.

here's my code

should i add some define in the first to differentiate?

or 

change loop 

for{

}

please enlighten me asap X(

------------------------------------------------------------------------------------------------------------------------------------

#include "SoftwareSerial.h"

//#define defaultPatch 15 //악기 초기화 버튼 설정 악기번호

SoftwareSerial mySerial(2, 3); //SW시리얼핀 정의 D3이 MIDI신호 전송용, D2는 미사용

byte note = 0; //The MIDI연주될 note(음계)
byte resetMIDI = 4; // VS1053 Reset용 핀
byte ledPin = 13; //MIDI 트래픽 표시용 LED

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

#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif


Adafruit_MPR121 cap = Adafruit_MPR121();

#define MPR121addr 0x5A
#define MPR121addr 0x5B

uint16_t lasttouched = 0;
uint16_t currtouched = 0;

#include <Adafruit_MPR121.h>
int btn[]={60, 62, 64, 65, 67,69, 71, 72, 74, 76, 77, 79,
81, 83, 84, 86, 88, 89, 91, 93, 95, 96, 98, 100};

byte byteData;

void setup() {
Serial.begin(9600);
mySerial.begin(9600);
/* while (!Serial) { // needed to keep leonardo/micro from starting too fast!
delay(10);
}
*/

Serial.println("Adafruit MPR121 Capacitive Touch sensor test");

// Default address is 0x5A, if tied to 3.3V its 0x5B
// If tied to SDA its 0x5C and if SCL then 0x5D
if (!cap.begin(0x5A)) {
Serial.println("MPR121-A not found, check wiring?");
while (1);
}
Serial.println("MPR121-A found!");
//
if (!cap.begin(0x5B)) {
Serial.println("MPR121-B not found, check wiring?");
while (1);
}
Serial.println("MPR121-B found!");



//Reset the VS1053
pinMode(resetMIDI, OUTPUT);
digitalWrite(resetMIDI, LOW);
delay(100);
digitalWrite(resetMIDI, HIGH);
delay(100);

}


void loop() {

currtouched = cap.touched();

for (uint8_t i=0; i<12; i++) {
// it if *is* touched and *wasnt* touched before, alert!
if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
Serial.print(i); Serial.println(" touched");
// tone(0, btn[i],100);
noteOn(0, btn[i],100);
//tone(buzzerPin, frequency[i], 330);

}
}


for (uint8_t i=12; i<24; i++) {
// it if *is* touched and *wasnt* touched before, alert!
if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
Serial.print(i); Serial.println(" touched");
// tone(0, btn[i],100);
noteOn(0, btn[i],100);
//tone(buzzerPin, frequency[i], 330);

}
}

//*************** MIDI LOOPBACK ******************//
if(Serial.available() > 0)
{
byteData = Serial.read();
mySerial.write( byteData);
}

lasttouched = currtouched;

return;


}

//Send a MIDI note-on message. Like pressing a piano key
//channel ranges from 0-15
void noteOn(byte channel, byte note, byte attack_velocity) {
talkMIDI( (0x90 | channel), note, attack_velocity);
}

//Send a MIDI note-off message. Like releasing a piano key
void noteOff(byte channel, byte note, byte release_velocity) {
talkMIDI( (0x80 | channel), note, release_velocity);
}

//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that data values are less than 127
void talkMIDI(byte cmd, byte data1, byte data2) {
digitalWrite(ledPin, HIGH);
mySerial.write(cmd );
mySerial.write(data1 );

//Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes
//(sort of: http://253.ccarh.org/handout/midiprotocol/)
if( (cmd & 0xF0) <= 0xB0)
mySerial.write(data2 );

digitalWrite(ledPin, LOW);
}

Labels (1)
0 Kudos
3 Replies

282 Views
NXP TechSupport
NXP TechSupport

Hi Jin,

Yes, it is possible to communicate with two MPR121 sensors on the same I2C bus in order expand the number of touch buttons up to 24.

Actually you can assign four I2C addresses to the MPR121 depending on the connection of the ADDR pin:

pastedImage_2.png 

 

For instance, one MPR121 slave will have the 7-bit I2C address of 0x5A when ADDR=VDD (which translates to 0xB4 for a write and 0xB5 for a read) and the other one 0x5B when ADDR=GND (which translates to 0xB6 for a write and 0xB7 for a read).

 

I hope it helps!

Best regards,

Tomas

282 Views
Contributor I

Mr. Vacerka 

Thank you so much!!

I was relieved by the possibility of connection.

For your kind reply, I succeeded in connecting all 4 mpr121 sensors!!

One last problem I am facing is that "expand the number of touch buttons up to 24."

Every touch sensor gives me value of  0 to 11.

How can I make it to 0-11, 12-23, 24-35, 36-47 ?

----------------------------------------------------------------------------------------------------------------------------------------------------- 

#include "SoftwareSerial.h"

//#define defaultPatch 15 //악기 초기화 버튼 설정 악기번호

SoftwareSerial mySerial(2, 3); //SW시리얼핀 정의 D3이 MIDI신호 전송용, D2는 미사용

byte note = 0; //The MIDI연주될 note(음계)
byte resetMIDI = 4; // VS1053 Reset용 핀
byte ledPin = 13; //MIDI 트래픽 표시용 LED

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

#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif

// You can have up to 4 on one i2c bus but one is enough for testing!
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;

int btn[]={21, 23, 24, 26, 28, 29, 31, 33, 35, 36, 38, 40,
41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60,
62, 64, 65, 67,69, 71, 72, 74, 76, 77, 79, 81,
83, 84, 86, 88, 89, 91, 93, 95, 96, 98, 100, 101};

byte byteData;

void setup() {
Serial.begin(9600);
mySerial.begin(9600);
while (!Serial) { // needed to keep leonardo/micro from starting too fast!
delay(10);
}

Serial.println("Adafruit MPR121 Capacitive Touch sensor test");

// Default address is 0x5A, if tied to 3.3V its 0x5B
// If tied to SDA its 0x5C and if SCL then 0x5D
if (!cap.begin(0x5A)) {
Serial.println("MPR121-A not found, check wiring?");
while (1);
}
Serial.println("MPR121-A found!");
//

if (!cap2.begin(0x5B)) {
Serial.println("MPR121-B not found, check wiring?");
while (1);
}
Serial.println("MPR121-B found!");
//

if (!cap3.begin(0x5C)) {
Serial.println("MPR121-C not found, check wiring?");
while (1);
}
Serial.println("MPR121-C found!");
//

if (!cap4.begin(0x5D)) {
Serial.println("MPR121-D not found, check wiring?");
while (1);
}
Serial.println("MPR121-D found!");


//Reset the VS1053
pinMode(resetMIDI, OUTPUT);
digitalWrite(resetMIDI, LOW);
delay(100);
digitalWrite(resetMIDI, HIGH);
delay(100);


// 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(0x5B);
cap3.begin(0x5C);
cap4.begin(0x5D);

}


void loop() {

// Get the currently touched pads
currtouched = cap.touched();
currtouched2 = cap2.touched();
currtouched3 = cap3.touched();
currtouched4 = cap4.touched();



for (uint8_t i=0; i<48; i++) {
// it if *is* touched and *wasnt* touched before, alert!
if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
Serial.print(i); Serial.println(" touched");
// tone(0, btn[i],100);
noteOn(0, btn[i],100);
//tone(buzzerPin, frequency[i], 330);
}

//2///////////////////////////////////////////////////
if ((currtouched2 & _BV(i)) && !(lasttouched2 & _BV(i)) ) {
//when sensor is touched do something
Serial.print(i); Serial.println(" touched");
noteOn(0, btn[i],100);
}
//3///////////////////////////////////////////////////
if ((currtouched3 & _BV(i)) && !(lasttouched3 & _BV(i)) ) {
//when sensor is touched do something
Serial.print(i); Serial.println(" touched");
noteOn(0, btn[i],100);
}
//4///////////////////////////////////////////////////
if ((currtouched4 & _BV(i)) && !(lasttouched4 & _BV(i)) ) {
//when sensor is touched do something
Serial.print(i); Serial.println(" touched");
noteOn(0, btn[i],100);
}
}

// reset our state
lasttouched = currtouched;
lasttouched2 = currtouched2;
lasttouched3 = currtouched3;
lasttouched4 = currtouched4;
return;


//*************** MIDI LOOPBACK ******************//
if(Serial.available() > 0)
{
byteData = Serial.read();
mySerial.write( byteData);
}

}

//Send a MIDI note-on message. Like pressing a piano key
//channel ranges from 0-15
void noteOn(byte channel, byte note, byte attack_velocity) {
talkMIDI( (0x90 | channel), note, attack_velocity);
}

//Send a MIDI note-off message. Like releasing a piano key
void noteOff(byte channel, byte note, byte release_velocity) {
talkMIDI( (0x80 | channel), note, release_velocity);
}

//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that data values are less than 127
void talkMIDI(byte cmd, byte data1, byte data2) {
digitalWrite(ledPin, HIGH);
mySerial.write(cmd );
mySerial.write(data1 );

//Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes
//(sort of: http://253.ccarh.org/handout/midiprotocol/)
if( (cmd & 0xF0) <= 0xB0)
mySerial.write(data2 );

digitalWrite(ledPin, LOW);
}

 

0 Kudos

282 Views
NXP TechSupport
NXP TechSupport

Hi Jin,

Glad to hear you managed to connect all four MPR121 sensors on the same I2C bus.

 

I am not sure about your current question, I assume it can be done easily in your sw depending on the address of the sensor you are currently communicating with.  

 

Best regards,

Tomas

0 Kudos