Capacitive Touch Sensor Keypad

capacitive touch sensor key padAs a more reliable alternative to mechanical keypads, this pcb with an integrated touch sensor controller provides a numeric keypad and requires only the two i2c signal lines (plus optionally an interrupt line to the microprocessor to signal a keystroke) and runs on 3.3V. Depending on the polling interval, current consumption is 70µA to 1 or 2 mA.

Connections:
• GND
• 3.3V
• SDA - i2c data
• SCL - i2c clock
• INT - interrupt signal to mcu
• LED - for user feedback since there is no mechanical click

It can be mounted behind a transparent plexiglass panel as long as it is glued without air bubbles (for example with silicon compound or two-sided adhesive tape).

70 x 53 mm pcb with gold-finished contact pads for connections, 0.1" pitch.
Circuit consists of the AD7147 controller and supply decoupling capacitors. i2c pull-up resistors not included: SDA and SCL require ca 4.7 kOhm pull-ups on mcu side.

This version uses the Analog Devices AD7147 with i2c.

The pcb can also be fitted with the SPI version on request.

An alternative with the Freescale MPR121 is coming soon.

  23 euros  

C Sample Code for MPR121:


/****************************************************************************/
/*               MPR121 sample code - www.flashgenie.net                    */
/*               any feedback is welcome at  genie < at > flashgenie.net    */
/****************************************************************************/


byte resA,MPR_OK; //global 

#define MPR_i2cAddress 0x5a //0x4D

#define TouchedOK 13 //code for Ok key of touch pad
#define TouchedESC 8 //code of ESC key of touch pad
#define NoTouch 0 

#define ADmsg 60

#define NUM_TOUCH_KEYS 13 //including eleProx

#define DATA_BLOCK_SIZE 43 //include baseline values
#define ADC_TouchRegister 0
#define ADC_ResultRegister 4
#define BaselineRegister 30

void initMPR(void);


byte DecodeButtons(void);

byte ReadFromMPR( byte RegAdr,  byte NumberOfRegistersToRead, byte *DataBuffer);
void MPR121_WriteRegister(byte adr, byte val);


void initMPR(void)
{
#define InitBlockSize 27    //send sequential registers as one long block: address then vals
  byte Thresholds[InitBlockSize] =  {0x41,15,10,15,10,15,10,15,10,15,10,15,
                                 10,15,10,15,10,15,10,15,10,15,10,15,10,15,10};
  word sent;
    IIC1_Init();//lo-level init
    I2C1_Init();
    I2C1_SelectSlave(MPR_i2cAddress);
  MPR_OK = 1;
  MPR121_WriteRegister(0x2B,1); // MAX HALF DELTA Rising
  MPR121_WriteRegister(0x2C,1); // NOISE HALF DELTA Rising
  MPR121_WriteRegister(0x2D,0); // NOISE COUNT LIMIT Rising
  MPR121_WriteRegister(0x2E,0); // DELAY LIMIT Rising
  MPR121_WriteRegister(0x2F,1); // MAX HALF DELTA Falling
  MPR121_WriteRegister(0x30,1); // NOISE HALF DELTA Falling
  MPR121_WriteRegister(0x31,0xFF); // NOISE COUNT LIMIT Falling
  MPR121_WriteRegister(0x32,2); // DELAY LIMIT Falling

  resA = I2C1_SendBlock(&Thresholds, (word)InitBlockSize, &sent);  // send block, with address
  if (resA)
      ErrorMsg(resA, "i2cSendBlockErr");  
  if (sent < InitBlockSize)//sending failed
    {
      MPR_OK=0;//set global error flag to indicate that touch pad is not available
      return;
    }
  MPR121_WriteRegister(0x5C,0x0B); // AFE CONFIG  FFI   CDC %1011  AN3889
  MPR121_WriteRegister(0x5D,0x04); //TOUCH DETECTION CONFIG last 3 bits=sample interval; 4:5ms 
  MPR121_WriteRegister(0x7B,0x0B); // %1011 AUTOCONFIG enable
  MPR121_WriteRegister(0x7D,156); //196 was 156 AUTOCONFIG upper limit USL 196 for 3V
  MPR121_WriteRegister(0x7E,101); //127 was 101  AUTOCONFIG lower limit LSL  65% of USL
  MPR121_WriteRegister(0x7F,140); //176 was 140  AUTOCONFIG target level  90% of USL
  MPR121_WriteRegister(0x5E,0x0c); // START PESCE (number of electrodes )
}

void MPR121_WriteRegister(byte adr, byte val)
 { byte blk[2];
    word sent;
  blk[0]=adr;// copy register address and value into a two-byte block and send it
  blk[1]=val;
  resA = I2C1_SendBlock(&blk, 2, &sent);  // send 1 byte to set read address
  if (resA)
      ErrorMsg(resA, "i2cSendBlockErr");  
 }
  
//return true if success
byte ReadFromMPR( byte RegAdr,  byte NumberOfRegistersToRead, byte *DataBuffer){  word sent;   
   resA = I2C1_SendBlock(&RegAdr, (word)1, &sent);  // send 1 byte to set read address
   if (resA)
    {
      ErrorMsg(resA, "i2cSendBlockErr");  
      return 0;//fail
    }

   resA = I2C1_RecvBlock(DataBuffer, NumberOfRegistersToRead, &sent);    // number of bytes
   if (resA)
    {
      ErrorMsg(resA, "i2cReadBlockErr");  
    }
    
    return (resA==ERR_OK);// success
  }
  

//call this routine when the interrupt line from the MPR121 signals a touch event
byte DecodeButtons(void) //decode bitmap of MPR touch register and return ascii code of key
{ word mask = 0x0001;
 byte i;
 if (ReadFromMPR(ADC_TouchRegister, 2, (byte *)(&TouchBits)))
  {
   for (i=0;i<10;i++)// test for 10 digits:
    {  
      if (TouchBits == mask)
        return '0'+i;//return character value of digit: '0', '1' etc
      mask <<=1;//shift left 1 to test next bit
    }
   if (TouchBits == 0x0400)
      return TouchedESC;
   else if (TouchBits == 0x0800)
      return TouchedOK;
   else 
   return NoTouch;
   }
   else return NoTouch;
} 
//end mpr121
 
 
   
      © 2010 Issole Informatique, France -                             Pour les ventes en France, ajouter 19,6 TVA.