MPR121 Capacitive Touch Sensor Synth

I want to build a very simple synth using the MPR121 capacitive touch sensor breakout and the tone values stored in ‘pitches.h’.

I followed the tutorial here (bildr Sensing Capacitive Touch - MPR121 + Arduino - bildr) to get the capacitance sensors working and they work fine using this code

#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[i] == 0){
     //pin i was just touched
     Serial.print("pin ");
     Serial.print(i);
     Serial.println(" was just touched");
    
    }else if(touchStates[i] == 1){
     //pin i is still being touched
    } 
   
    touchStates[i] = 1;   
   }else{
    if(touchStates[i] == 1){
     Serial.print("pin ");
     Serial.print(i);
     Serial.println(" is no longer being touched");
     
     //pin i is no longer being touched
   }
    
    touchStates[i] = 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)/vdd*256 = 0xC9 @3.3V  set_register(0x5A, ATO_CFGL, 0x82); // LSL = 0.65*USL = 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();
}

The problem is, the tutorial says that you can use the sensors to trigger specific events (like sound) with the following addition to the code and I cant get it to compile…

if(touchStates[i] == 0){
  //pin i was just touched
  Serial.print("pin ");
  Serial.print(i);
  Serial.println(" was just touched");


  switch (i) {
    case 0:
      //0 was touched

      break;
    case 1:
      //1 was touched

      break; 
    case 2:
      //2 was touched

      break; 
    case 3:
      //3 was touched
  }

}

I really like the code that was written for the sensors because they can read multiple sensors at on time so I would be able to play chords.

The problem is, the tutorial says that you can use the sensors to trigger specific events (like sound) with the following addition to the code

Where did you put that extra code?

and I cant get it to compile...

It's pretty simple really. Click Verify. Fix any errors. Repeat until there are no errors.

Since you didn't post any errors, I'll have to assume that there were none, so I can't imagine what your problem is.

Heres the modified code:

#include "mpr121.h"
#include <Wire.h>
#include "pitches.h"
#define speaker 11

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[i] == 0){
  //pin i was just touched
  Serial.print("pin ");
  Serial.print(i);
  Serial.println(" was just touched");


  switch (i) {
    case 0:
      //0 was touched

      break;
    case 1:
      //1 was touched

      break; 
    case 2:
      //2 was touched

      break; 
    case 3:
      //3 was touched
  }

}
    
    }else if(touchStates[i] == 1){
     //pin i is still being touched
    } 
   
    touchStates[i] = 1;   
   }else{
    if(touchStates[i] == 1){
     Serial.print("pin ");
     Serial.print(i);
     Serial.println(" is no longer being touched");
     
     //pin i is no longer being touched
   }
    
    touchStates[i] = 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)/vdd*256 = 0xC9 @3.3V  set_register(0x5A, ATO_CFGL, 0x82); // LSL = 0.65*USL = 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();
}

And here are the error messages I’m getting:

Arduino: nightly (Mac OS X), Board: “Arduino Leonardo”

Capacitive_Touch.ino: In function ‘void readTouchInputs()’:
Capacitive_Touch:61: error: expected primary-expression before ‘}’ token
Capacitive_Touch:61: error: expected ;' before '}' token Capacitive_Touch:70: error: expected }’ before ‘else’
Capacitive_Touch:71: error: ‘i’ was not declared in this scope
Capacitive_Touch:79: error: ‘i’ was not declared in this scope
Capacitive_Touch.ino: At global scope:
Capacitive_Touch:84: error: expected declaration before ‘}’ token

This report would have more information with
“Show verbose output during compilation”
enabled in File > Preferences.

Put EVERY { on a new line. Put EVERY } on a new line. Get rid of the excessive blank lines. Use Tools + Auto Format to properly format the code.

You'll notice that you can't use it now, because you have a mismatch between the number of { and } in your code. YOU need to figure out which ones don't belong.