Learn to code

ARDUINO & CODES

Previous Post
Detecting Moisture with Soil Moisture Sensor and Arduino
Next Post
RFID door Lock with multiple RFID readers for Arduino

Create multiple proximity buttons with MPR121 for Arduino

in Arduino Project

We are going to create a LED that turns on when you approach a piece of conductive material such as aluminum or copper with the MPR121 controller. In another project, ,we created a touch button. However, if you are creating a touch button that is behind material you will need a proximity code. This tutorial, uses the MPR121 touch sensor controller to control 1-12 touch / proximity buttons. If you touch the conductive material a LED will turn on. If you touch the conductive material again the LED will turn off. 

To be able to make a proximity sensor with conductive material, we will use the touch sensor controller MPR121. This wil make things much easier than wiring everything from the conductive material directly to the Arduino Board. In this tutorial you will use copper foil that is soldered to a wire that is connected with the MPR121. As you get closer to the conductive material, in this tutorial copper, an LED will light up. This proximity code can be used for many proximity projects.

MPR121 Touch Sensor Controller

The little chip in the middle of the PCB is the actual MPR121 sensor that does all the capacitive sensing and filtering. We add all the extra components you need to get started, and ‘break out’ all the other pins you may want to connect to onto the PCB. For more details you can check out the schematics in the Downloads page.

MPR121 Power Pins

The sensor on the breakout requires 3V power. Since many customers have 5V microcontrollers like Arduino, we tossed a 3.3V regulator on the board. Its ultra-low dropout so you can power it from 3.3V-5V just fine.

  • Vin – this is the power pin. Since the chip uses 3 VDC, we have included a voltage regulator on board that will take 3-5VDC and safely convert it down. To power the board, give it the same power as the logic level of your microcontroller – e.g. for a 5V micro like Arduino, use 5V
  • 3Vo – this is the 3.3V output from the voltage regulator, you can grab up to 100mA from this if you like
  • GND – common ground for power and logic
12C Pins
  • SCL – I2C clock pin, connect to your microcontrollers I2C clock line.
  • SDA – I2C data pin, connect to your microcontrollers I2C data line
IRQ and ADDR Pins
  • ADDR is the I2C address select pin. By default this is pulled down to ground with a 100K resistor, for an I2C address of 0x5A. You can also connect it to the 3Vo pin for an address of 0x5B, the SDA pin for 0x5C or SCL for address 0x5D
  • 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
Assembly of MPR121

Prepare the Header Pins: cut the header strip if that is neccessary. It will be must easier to solder if you insert the pins into the breadboard before soldering. The long pins should be down into the breadboard.

Add MPR121 breakout board : cut the header strip if that is neccessary. It will be must easier to solder if you insert the pins into the breadboard before soldering. The long pins should be down into the breadboard. Be sure to solder all pins for reliable electrical contact.

Make the Proximity Buttons : To be able to sense proximty behind a object you are going to use copper sheets. Make sure that they are connected. After applying the copper you can solder wire to it. It is quite easy.

Parts Required

Arduino Uno Rev3 Arduino Uno Rev3 × 1
Breadboard 400 point Breadboard 400 point × 1
Dupont Wires Dupont Wires × 15
220 ohm resistor 220 ohm resistor × 3
Copper / Aluminum foil Copper / Aluminum foil × 1
LED LED × 3
MPR121 Breakout Board MPR121 Breakout Board ×

Arduinoplatform is a participant in several affiliate programs. This means that I will earn a commision if you buy a product from the affiliated websites through clicking on the links provided above.

Circuit Diagram

Circuit Diagram –  place the MPR121 board on the left of the half-sized breadboard. The IRQ pin of the MPR121 is connected to pin 4 of the Arduino Uno. Pin A5 of the Arduino board is connected to the SCL pin. SDA is connected to A4 of the Arduino Uno Board. GND is connected to GND of the Arduino Board and the 3V pin is connected to the 3.3V pin of the Arduino Board.

Next, you are going to connect all the LEDs. 220 ohm resistors are used to ensure that the LED does not receive to much voltage.

Your electrode pads are connected to pins 0,1 and 2.

The Code

#include <MPR121.h>
#include <Wire.h>

#define numElectrodes 3
#define DELIMITER ","

boolean oldSwitchState[] = {LOW,LOW, LOW};
boolean newSwitchState[] = {LOW,LOW, LOW};


boolean code[] = {LOW, LOW, LOW};

boolean LEDstatus[] = {LOW, LOW, LOW};

int pin_LED[] = {11, 12, 13};

void setup() {
 
  Serial.begin( 9600 );
  Wire.begin();
   for(int y=0; y<numElectrodes; y++){
    pinMode(pin_LED[y], OUTPUT);
   }
   pinMode(pin_LED, OUTPUT);

  // Setup MPR121
  MPR121.begin( 0x5A );
  MPR121.setInterruptPin( 4 );
  MPR121.setTouchThreshold( 10 );
  MPR121.setReleaseThreshold( 10 );
}

void loop() 

  {
 
            
  if(MPR121.touchStatusChanged()){
    MPR121.updateTouchData();
    for(int i=0; i<numElectrodes; i++){

      
      
      if(MPR121.isNewTouch(i)){

       
        newSwitchState[i] = MPR121.isNewTouch(i);
        Serial.print("electrode ");
        Serial.print(i, DEC);
        Serial.print(" was just touched ");
        Serial.print(" New Switch state is:  ");
        Serial.println(newSwitchState[i]); 
        if (newSwitchState[i] != oldSwitchState[i]){
          if ( LEDstatus[i] == LOW ) { digitalWrite(pin_LED[i], HIGH);  LEDstatus[i] = HIGH; code[i] = HIGH; }


           
           else                    { digitalWrite(pin_LED[i], LOW);   LEDstatus[i] = LOW;  code[i] = LOW; }

       if ( (code[0] == HIGH) && (code[1] == HIGH)&& (code[2] == HIGH))
      
      
      { 
            Serial.print(" Solved  ");
            }
   
       }
          oldSwitchState[i] = newSwitchState[i];



          
      } else if(MPR121.isNewRelease(i)){
        newSwitchState[i] = MPR121.isNewTouch(i);
       
        Serial.print("electrode ");
        Serial.print(i, DEC);
        Serial.println(" was just released"); 
        Serial.print(" New Switch state is:  ");
        Serial.println(newSwitchState[i]); 
        oldSwitchState[i] = newSwitchState[i]; 
      }
    }
    
  }
  
}

Code Explanation

Import the mpr121 and wire library

At the beginning of your program, include the MPR121 library and the Wire library. Since, you are using SDA and SCL pin of the Arduino Board you will need the wire.h library. For the funtioning the mpr121 board another library is needed. You can get the mpr121 library on github: https://github.com/BareConductive/mpr121 and the wire.h library is standard installed if you have the latest Arduino IDE.

#include <MPR121.h>
#include <Wire.h>

 

Define variables

In the code, numElectrodes corresponds to the amount of proximity sensors that you use.  Remember, the proximity sensors act as a switch so you should keep track of the state of the switch. At the beginning of the program every state should be LOW. This is acheived by using the array function. Furthermore, a boolean variable is created for the LED. Also, at the beginning of the program every LED should be turned off. The integer pin_LED[] is an array to store the pins that are connected to the LEDs.

#define numElectrodes 3
#define DELIMITER ","

boolean oldSwitchState[] = {LOW, LOW, LOW};
boolean newSwitchState[] = {LOW, LOW, LOW};
boolean LEDstatus[] = {LOW, LOW, LOW};

int pin_LED[] = {11, 12, 13};

 

Setup of MPR121

First, you need to start Serial Communication and start the Wire library. Secondly, you will need to set the pinModes of the LEDs to an output mode. Next, you set up the MPR121. MPR121.begin can be used for 12C Adresses. You are using the default adress. The tresholds are used for detecting proximity. Higher numbers require that you touch the electrodes. In the code the number 10 is used. You have to decide by trial and error, depending on your conductive material, which number is best for you.

   Serial.begin( 9600 );
  Wire.begin();
   for(int y=0; y<numElectrodes; y++){
    pinMode(pin_LED[y], OUTPUT);
   }
   pinMode(pin_LED, OUTPUT);

  // Setup MPR121
  MPR121.begin( 0x5A );
  MPR121.setInterruptPin( 4 );
  MPR121.setTouchThreshold( 10 );
  MPR121.setReleaseThreshold( 10 );

 

Sensing Touch 

You arrived at the void loop() part of the sketch. This is where the magic is happing! The code is using a couple of functions from the library. The first one is touchStatusChanged. This function is allowing you to know whether the electrode is touched or not. The second function that you are using is to update the touch data. In other words, is the “switch” touched or closed? After the data is updated, the for loop is created to loop through all the electrodes/touchpads.

if (MPR121.touchStatusChanged()) {
    MPR121.updateTouchData();
    for (int i = 0; i < numElectrodes; i++)

 

Detect Touch

After the touch data is updated you are going to determine in the code whether the switch is “touched” or not. If the switch is touched somelines are printed to the Serial Monitor.

 if (MPR121.isNewTouch(i)) {
        newSwitchState[i] = MPR121.isNewTouch(i);
        Serial.print("electrode ");
        Serial.print(i, DEC);
        Serial.print(" was just touched ");

 

Turn LED on

If the condition is met that the switch is touched, the corresponding LED is going to light up. Therefore, we will need to know whether the switch is already been pushed to determine if the LED should be on or off. By checking if the new state of the electrode is not equal to the old state of the electrode we know that the electrode is touched. After this, we are going to check if the LED corresponding to the electrode is LOW. If that is the case the LED is turned on and the ledStatus changes to HIGH.

  if (newSwitchState[i] != oldSwitchState[i]) {
          if ( LEDstatus[i] == LOW ) {
            digitalWrite(pin_LED[i], HIGH);
            LEDstatus[i] = HIGH;
          }

 

Turn LED off

If the LEDstatus is HIGH the condition above is not true the LED is going to be turned off. Remeber, if the electrode is touched the LED will light up and stays on if the electrode is released. If the electrode is touched again the LED will turn off. Since there was a new touch the oldSwitchState is replaced by the value of the newSwitchstate.

 else                    {
            digitalWrite(pin_LED[i], LOW);
            LEDstatus[i] = LOW;
          }
        }
        oldSwitchState[i] = newSwitchState[i];
}

 

Turn LED off

You are arriving at the last part of the code. In this part the code is determining whether the electrode is released. If this is true, the state of the switch is changed and some lines are printed to the Serial Monitor. As explained above, you are going to need information about the state of the swith / electrode. Therefore, is the electrode is released the state of the switch is also updated.

 else if (MPR121.isNewRelease(i)) {
        newSwitchState[i] = MPR121.isNewTouch(i);
        Serial.print("electrode ");
        Serial.print(i, DEC);
        Serial.println(" was just released");
        oldSwitchState[i] = newSwitchState[i];
      }
    }
  }

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.
You need to agree with the terms to proceed

Menu