16 Touch Sensors - its working [code] but I wonder ...

So, I wanted to push this tutorial to its limits, making 16 touch sensors (I'm using screws for that)

http://www.arduino.cc/playground/Code/CapacitiveSensor

And using a 16 channel analog multiplexer (this is the one I actually tested with)

So far so good, it works. But I just want to double check things out, to be sure it won't burn something after hours of usage. :wink:

Here's the test code I created, I'm just using an Arduino UNO + the multiplexer, nothing else. Thanks for any advice! 8)

#include "pins_arduino.h" // Arduino pre-1.0 needs this
volatile uint8_t* port;
volatile uint8_t* ddr;
volatile uint8_t* pin;
byte bitmask;
#define pinToMeasure 8
uint8_t values[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
uint8_t buttons[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
uint8_t buttonEvent[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; // 1 == normal push, 2 == hold push //
char printOut[16*2];
uint8_t counterIdle = 0;
#define oversample 8
#define sensitivity (4*oversample)

void setup()
{
  for (char x=2; x<12; x++) pinMode(x, OUTPUT);
  for (char x=2; x<12; x++) digitalWrite(x, LOW);
  Serial.begin(9600);
  
  port = portOutputRegister(digitalPinToPort(pinToMeasure));
  ddr = portModeRegister(digitalPinToPort(pinToMeasure));
  bitmask = digitalPinToBitMask(pinToMeasure);
  pin = portInputRegister(digitalPinToPort(pinToMeasure)); 
}

void loop()
{
  memset(values, 0, sizeof(values));
  for (uint8_t y=0; y<oversample; y++)
  {
    for (uint8_t x=0; x<16; x++)
    {
      digitalWrite(2, bitRead(x,0)); digitalWrite(3, bitRead(x,1));
      digitalWrite(4, bitRead(x,2)); digitalWrite(5, bitRead(x,3));
      
      values[x] += readCapacitivePin();
    }
  }

  uint8_t buttonchanged = 0;
  for (uint8_t x=0; x<16; x++)
  {   
    if (values[x] <= (sensitivity/2) && buttons[x] > 0)
    {
      if (buttons[x] < 99) { buttonEvent[x] = 1; buttonchanged = 1;  }
      buttons[x] = 0;
    }
    else if (values[x] > sensitivity && buttons[x] < 120)
    { 
      buttons[x]++;
      if (buttons[x] == 99) { buttonEvent[x] = 2; buttonchanged = 1; }
    }
  }
  
  if (buttonchanged)
  {
    Serial.print(":");
    for (uint8_t x=0; x<16; x++)
    {
      if (buttonEvent[x] == 1) Serial.print("#:"); 
        else if (buttonEvent[x] == 2) Serial.print("@:"); 
        else Serial.print("_:");

        buttonEvent[x] = 0;
    }
    Serial.println("");
    counterIdle = 0;
  }
  
  counterIdle++;
  if (counterIdle > 100)
  {
    Serial.println("");
    counterIdle = 0;
  }
}


uint8_t readCapacitivePin() 
{
  *ddr &= ~(bitmask); // Make the pin an input with the internal pull-up on
  *port |= bitmask;
  uint8_t cycles = 6;
  for(uint8_t i = 0; i < 6  ; i++)  // Now see how long the pin to get pulled up
  {
    if (*pin & bitmask){ cycles = i; break; }
  }
   
  *port &= ~(bitmask); // Discharge the pin again by setting it low and output
  *ddr  |= bitmask;

  return cycles;
}
volatile uint8_t* port;
volatile uint8_t* ddr;
volatile uint8_t* pin;

Why are these volatile? Are you expecting the values to change, in an interrupt, after being set in setup()?

I don't see your code using interrupts.

    for (uint8_t x=0; x<16; x++)
    {
      digitalWrite(2, bitRead(x,0)); digitalWrite(3, bitRead(x,1));
      digitalWrite(4, bitRead(x,2)); digitalWrite(5, bitRead(x,3));
      
      values[x] += readCapacitivePin();
    }

I don't see the value of multiple statements on one line. It makes the code much harder to read.

      if (buttons[x] == 99) { buttonEvent[x] = 2; buttonchanged = 1; }

Ditto here (and other places). What is the magic value 99 for? A #define with a meaningful name would be better.

I'm interested in knowing how this works out!

What are you mounting the screws to? What are you planning for the sensors to control?

Good luck!

Well, I will be building the prototype soon, it will handle 16 ultra bright LEDs, so one sensor per LED. I will check some nice screws this week, to see something I like. :wink: Once I have something nicer to show, I will post pictures.

I was thinking about doing the same thing, but instead of LED's I'm going to be switching relays.

Please keep us all posted!