Problem with multiple sensors with CAP1188, using millis() + arrays technique


I’m having trouble getting multiple readings from a CAP1188 circuit. I’m building a musical instrument—a mBira, or thumb piano, with an arduino (feather 32u4 to be precise) inside. I soldered directly to each key to turn them into capacitive touch sensors.

Everything works on the hardware side of things, and I was able to get the example code running so that I am able to detect “on/off” switchings for each key independently.

I’m now trying to do something more sophisticated than on/off—I want to measure the time between button presses, to get a range of values rather than binary. The reason I want to do this has something to do with musicality—to play louder notes on the Mbira you have to “dig in” and therefore the finger spends longer time on the key. So quieter, shorter notes acoustically have shorter on/off time in milliseconds, and louder, longer notes have a longer value in milliseconds.

I got one key working this way! but now in trying to address all keys, I’m stumped. I don’t really understand how the code inside the cap1188 library works. the normal way I’d implement this, turning each variable into an array and iterating with a for loop with millis(), doesn’t seem to make contact with the cap.touched() program.

can anyone help?

another question i’m having is improving the speed of this program—right now, i can’t seem to get a faster response than 60 milliseconds per key press…i feel like something is bogging down the code…

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_CAP1188.h>

// Reset Pin is used for I2C or SPI
#define CAP1188_RESET  5

// CS pin is used for software or hardware SPI
//#define CAP1188_CS  10

// These are defined for software SPI, for hardware SPI, check your 
// board's SPI pins in the Arduino documentation
//#define CAP1188_MOSI  10
//#define CAP1188_MISO  11
//#define CAP1188_CLK  9

// For I2C, connect SDA to your Arduino's SDA pin, SCL to SCL pin
// On UNO/Duemilanove/etc, SDA == Analog 4, SCL == Analog 5
// On Leonardo/Micro, SDA == Digital 2, SCL == Digital 3
// On Mega/ADK/Due, SDA == Digital 20, SCL == Digital 21

// Use I2C, no reset pin!
//Adafruit_CAP1188 cap = Adafruit_CAP1188();

// Or...Use I2C, with reset pin
Adafruit_CAP1188 cap = Adafruit_CAP1188(CAP1188_RESET);

// Or... Hardware SPI, CS pin & reset pin 
// Adafruit_CAP1188 cap = Adafruit_CAP1188(CAP1188_CS, CAP1188_RESET);

// Or.. Software SPI: clock, miso, mosi, cs, reset
//Adafruit_CAP1188 cap = Adafruit_CAP1188(CAP1188_CLK, CAP1188_MISO, CAP1188_MOSI, CAP1188_CS, CAP1188_RESET);

unsigned long startTime[8] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned long endTime[8] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned long duration[8] = {0, 0, 0, 0, 0, 0, 0, 0};
byte timerRunning[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t touched[8] =  {0, 0, 0, 0, 0, 0, 0, 0};

void setup() {
  Serial.println("CAP1188 test!");

  // Initialize the sensor, if using i2c you can pass in the i2c address
  if (!cap.begin(0x28)) {
 // if (!cap.begin()) {
    Serial.println("CAP1188 not found");
    while (1);
  Serial.println("CAP1188 found!");

uint8_t reg = cap.readRegister( 0x1f ) & 0x0f;
cap.writeRegister( 0x1f, reg | 0x4F ); // or whatever value you want

void loop() {
 uint8_t touched = cap.touched();

for (uint8_t i=0; i<8; i++) 

 touched[i] = cap.touched();
if (timerRunning[i] == 0 && touched[i] == 1){ // button pressed & timer not running already
  startTime[i] = millis();
  timerRunning[i] = 1;

if (timerRunning[i] == 1 && touched[i] == 0){ // timer running, button released
  endTime[i] = millis();
  timerRunning[i] = 0;
  duration[i] = endTime[i] - startTime[i];
  Serial.println (duration[i]);

....anyone have any ideas?

another question i'm having is improving the speed of this program--right now, i can't seem to get a faster response than 60 milliseconds per key press...i feel like something is bogging down the code..

Do you know how a capacitive sensor works? You charge a capacitor (the plate to your finger) and then wait to see how long it takes to discharge. No part of that should sound fast or responsive.

hi! thanks for your reply.

okay, that makes sense, but maybe you can help me with the rest of my code. even 60 ms will be fine for this prototype, but right now i'm not getting multiple sensors to work simultaneously.