https://www.sparkfun.com/products/9695

The Capacitive Sensor I used for this project is the MPR121. The MPR121 is a capacitive touch sensor controller driven by an I2C interface (in this case the master controller is an Arduino). The chip can control up to twelve individual electrodes. As in my project I was using 20 pins (for 20 buttons), I used 2 sensors: I used the 12 electrodes of the 1st and 8 electrodes of the second. There is a very helpful hookup guide on the sparkfun website, which will make it easier to understand how to use this sensor. I recommend to download the code they use and modify it four your needs. If you want to make more advanced stuff than what is explained in this guide, I recommend to take a look at its datasheet to know how to make it communicate with the Arduino via I2C.

Hookup guide:

https://learn.sparkfun.com/tutorials/mpr121-hookup...

Datasheet:

https://www.sparkfun.com/datasheets/Components/MPR...

If you looked at the Fritzing file schematic that I attached, you will find out that lots of the connections of the schematic (pull-up resistors, capacitors....) are already soldered when you buy the MPR121 sensor at Sparkfun.

Next, I will remark some important notes on how to setup the sensor for this project:

1) Vdd:

Be careful!! the MPR121 works with Vdd = 3.3V. You will burn it if you connect it to the 5V output of Arduino.

2) The Setup:

In the hookup guide, you will find this:

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

What it does is to set up the MPR121 sensor correctly: select the number of electrodes used, choose the charge/discharge current and time for each sensor, set the touch/treshold release for each electrode... You do not need to know exactly what it is about: you can just copy it and change some of the lines for your project. You just need to call this function on your Arduino Setup, and do it again everytime you want to change the sensor setup (in my case, when I adjust the buttons or change the templates, for example). I will explain some aspects about the sensor setup in the next points.

The 'set_register' function basically makes the I2C communication between the sensor and the Arduino. It is defined like this:

void set_register(int address, unsigned char r, unsigned char v) { Wire.beginTransmission(address); Wire.write(r); Wire.write(v); Wire.endTransmission(); }

Two of the most important registers are the AFE Configuration registers 1 and 2 (registers 0x5C and 0x5D). See page 13 of the datasheet for more detail. Changing the values of this registers will define the charge/discharge current and time for the electrodes, the filtering iterations, and so on. I recommend playing a little bit with the CDT and CDC values so that you can find suitable ones for correct touch/release detection in your project (maybe they will not need to be modified, but maybe they will).





3) The address of each sensor:

There is a problem when you want to use two or more MPR121 sensors at a time, because all of them have the same default address for the I2C communication: it is the 0x5A address. If you look at the datasheet, it says that 4 different addresses can be chosen, depending on where you solder the address pin: Vdd, Vss, SDA or SCL. By default, the board comes with the address pin soldered to Vss (ground), so if you want to use more than one sensor, you have to cut this connection: next to the address pin you will find two small metallic squares that are connected with a very thin line: this line is the connection between the address pin and ground. You should cut this small line of one of the sensors with a cutter, and solder the address pin to Vdd, for example, so that the new address of this sensor is not 0x5A anymore: instead, it will be 0x5B.

This is exactly what I did for this project, so I had two sensors: the first one's address was 0x5A and the second one's was 0x5B.

4) Touch/Release Treshold setup:

The touch and release threshold setup is done inside the MPR121 setup. if you follow the hookup guide and look at the mpr121.h library, the default values are 0xA0 for touch_threshold and 0xB0 for release threshold. One possibility is to change the value of the touch and release threshold for each pin, using a byte variable for it. For example, for one sensor:

<p>byte touch_treshold_1st_sensor[12] = { 0xA0, 0X94, 0xB2.... //random values for example<br>byte release_treshold_1st_sensor[12] = { 0xB0,0xC3, 0xA8.... ...... ..... void mpr121_1st_sensor_setup(void) { ....... set_register(0x5A, ELE0_T, touch_treshold_1st_sensor[0]); set_register(0x5A, ELE0_R, release_treshold_1st_sensor[0]); set_register(0x5A, ELE1_T, touch_treshold_1st_sensor[1]); set_register(0x5A, ELE1_R, release_treshold_1st_sensor[1]); ........</p>

I find this the simplest way to define different touch/release threshold values for each template: you can save the values on the Arduino EEPROM and just load them into the sensor, depending on the template you are using.

However, I was having problems with this: some of the buttons I drew on some templates were out of range, so I could not make a correct setup. So instead of changing the treshold values, I was changing the Charge/Discharge current for each individual pin of the sensor. You can learn how to do this on page 14 of the datasheet. This worked better for me, becouse the range of touch/release detection for each electrode was greater. This is an example of how I did it:

<p>// 20 byte array: 12 values for 1st sensor and 8 for 2nd sensor. Initial value: 0x28<br>byte CDC_sensor[20] = {0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28};</p><p>.......</p><p>//Then I used the encoder to select the CDC_sensor[i] value for each pin</p><p>for (int i=0; i<20; i++)</p><p>{</p><p> //encoder stuff</p><p> if... //if encoder position is increased</p><p> {CDC_sensor[i] ++;}</p><p> else...//if encoder position is decreased</p><p> {CDC_sensor[i] --;}</p><p>}</p><p> //finally, everytime a CDC_sensor value is changed, you need to make the setup again:</p><p>void mpr121_1st_sensor_setup(void)<br>{ ....... </p><p> set_register(0x5A, 0x5F, CDC_sensor[0]); //el 0<br> set_register(0x5A, 0x60, CDC_sensor[1]); //el 1 set_register(0x5A, 0x61, CDC_sensor[2]); //el 2</p><p> ........</p>

You should try to use the way that is most suitable for you: changing the electrode threshold values or the individual charge current values.

5) Arduino interrupt:

The MPR121 sensor has an IRQ pin, which has to be set with a pull-up resistor, and goes to LOW everytime the sensor detects a touch or a release in one of its electrodes. So I recommend to solder this pins to the Arduino interrupt pins, which are digital 2 and 3. This way you can use the Arduino Attachinterrupt function:

http://arduino.cc/en/Reference/AttachInterrupt

But be careful!! not many code stuff must be done inside the interrupt: for example, the serial port does not work (therefore, the MIDI messages do not work either, becouse the serial port is used for their transmission). I only used the interrupts to change the value of a boolean variable, which determined whether one pin was being touched or not. Then, I did the corresponding changes in the general loop program. See the code:

//interrupt variables static boolean touch_1st = false; static boolean touch_2nd = false; //in the setup: //interrupts attachInterrupt(0, touching_1st_sensor, FALLING); attachInterrupt(1, touching_2nd_sensor, FALLING); //outside the loop void touching_1st_sensor() { touch_1st = true; } void touching_2nd_sensor() { touch_2nd = true; } //in the loop if(touch_1st) { //check for electrodes... touch_1st = false; } if(touch_2nd) { //check for electrodes... touch_2nd = false; }<br>

With all of this, I think you have enough information to do some beginner and medium level stuff with the MPR121 sensor.