zoologist 发表于 2016-3-21 21:00:59

MPR121 触摸传感器模块

MPR121 是一款触摸传感器芯片,原理是通过检测电容变化来判断当前是否有触摸(接近)。

主要电器特性如下【参考1】:
1. 工作电压1.71-3.6v(芯片工作电压)
2. 通讯接口为 I2C
3. 12个检测端口
4. 带有1个 IRQ端口

我是在Taobao购买的模块,价格是16元【参考3】。经过搜索,这是仿sparkfun的,更多资料可以在【参考2】看到。

模块长得下面这样,有一个降压芯片,看起来可以直接使用 5V 供电。上面有12个口,可以接12个触摸按钮。IRQ 的作用是发出中断通知上面有触摸。ADD是芯片的I2C地址选择,接GND VDD SDA或者 SCL 地址分别是 0x5A 0x5B 0x5C 和 0x5D【来自参考4】。



图片来自【参考2】

下面的代码可以正常工作(卖家的例程,有一些修改可以在 1.6.0 上编译通过)

#include "mpr121.h"
#include <Wire.h>

#define SENSORS       13
#define TOU_THRESH    0x1F
#define REL_THRESH    0x1A
#define PROX_THRESH   0x3f
#define PREL_THRESH   0x3c

// variables: capacitive sensing
bool touchStates;    // holds the current touch/prox state of all sensors
bool activeSensors = {1,1,1,1,1,1,1,1,1,1,1,1,1}; // holds which sensors are active (0=inactive, 1=active)
bool newData = false;         // flag that is set to true when new data is available from capacitive sensor
int irqpin = 2;               // pin that connects to notifies when data is available from capacitive sensor

void setup(){

// attach interrupt to pin - interrupt 1 is on pin 2 of the arduino (confusing I know)
attachInterrupt(0, dataAvailable, FALLING);

// set-up the Serial and I2C/Wire connections
Serial.begin(9600);
Wire.begin();

// set the registers on the capacitive sensing IC
setupCapacitiveRegisters();

}

void loop(){
readCapacitiveSensor();
}

/**
* dataAvailable Callback method that runs whenever new data becomes available on from the capacitive sensor.
*   This method was attached to the interrupt on pin 2, and is called whenever that pins goes low.
*/
void dataAvailable() {
newData = true;
}

/**
* readCapacitiveSensor Reads the capacitive sensor values from the MP121 IC. It makes a request to
*   the sensor chip via the I2C/Wire connection, and then parses the sensor values which are stored on
*   the first 13 bits of the 16-bit response msg.
*/
void readCapacitiveSensor(){
if(newData){   
            Serial.println("yes");      
    //read the touch state from the MPR121
    Wire.requestFrom(0x5A,2);
    byte tLSB = Wire.read();
    byte tMSB = Wire.read();
    uint16_t touched = ((tMSB << 8) | tLSB); //16bits that make up the touch states

    for (int i = 0; i < SENSORS; i++){// Check what electrodes were pressed
      if (activeSensors == 0) continue;
      char sensor_id [] = {'\0','\0','\0'};
      switch (i) {
      case 12:
          sensor_id = 'P';
          break;
      default:
          if (i < 10) {
            sensor_id = char( i+48 );
          }
          else if (i < 12) {
            sensor_id = char('1');
            sensor_id = char( ( i % 10 ) + 48 );
          }
      }
      if (sensor_id != '\0') {
      // read the humidity level

      // if current sensor was touched (check appropriate bit on touched var)
      if(touched & (1<<i)){      
          // if current pin was not previously touched send a serial message
          if(touchStates == 0){         
            Serial.print(sensor_id);      
            Serial.print(":");
            Serial.println("1");
          }
          touchStates = 1;      
      } else {
          // if current pin was just touched send serial message
          if(touchStates == 1){
            Serial.print(sensor_id);
            Serial.print(":");
            Serial.println("0");
          }
          touchStates = 0;
      }      
      }
    }
    newData = false;
}
}

/**
* setupCapacitiveRegisters Updates all of configurations on the MP121 capacitive sensing IC. This includes
*   setting levels for all filters, touch and proximity sensing activation and release thresholds, debounce,
*   and auto-configurations options. At the end it activates all of the electrodes.
*/
void setupCapacitiveRegisters(){

set_register(0x5A, ELE_CFG, 0x00);

// Section A - filtering when data is > baseline.
    // touch sensing
    set_register(0x5A, MHD_R, 0x01);
    set_register(0x5A, NHD_R, 0x01);
    set_register(0x5A, NCL_R, 0x00);
    set_register(0x5A, FDL_R, 0x00);

    // prox sensing
    set_register(0x5A, PROX_MHDR, 0xFF);
    set_register(0x5A, PROX_NHDAR, 0xFF);
    set_register(0x5A, PROX_NCLR, 0x00);
    set_register(0x5A, PROX_FDLR, 0x00);

// Section B - filtering when data is < baseline.
    // touch sensing
    set_register(0x5A, MHD_F, 0x01);
    set_register(0x5A, NHD_F, 0x01);
    set_register(0x5A, NCL_F, 0xFF);
    set_register(0x5A, FDL_F, 0x02);

    // prox sensing
    set_register(0x5A, PROX_MHDF, 0x01);
    set_register(0x5A, PROX_NHDAF, 0x01);
    set_register(0x5A, PROX_NCLF, 0xFF);
    set_register(0x5A, PROX_NDLF, 0xFF);

// 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 touch filter Configuration
    set_register(0x5A, FIL_CFG, 0x04);

// Section E - Set proximity sensing threshold and release
    set_register(0x5A, PRO_T, PROX_THRESH);   // sets the proximity sensor threshold
    set_register(0x5A, PRO_R, PREL_THRESH);   // sets the proximity sensor release

// Section F - Set proximity sensor debounce
    set_register(0x59, PROX_DEB, 0x50);// PROX debounce

// Section G - Set Auto Config and Auto Reconfig for prox sensing
    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, ATO_CFG0, 0x0B);

// Section H - Start listening to all electrodes and the proximity sensor
    set_register(0x5A, ELE_CFG, 0x3C);
}

/**
* set_register Sets a register on a device connected via I2C. It accepts the device's address,
*   register location, and the register value.
* @param address The address of the I2C device
* @param r       The register's address on the I2C device
* @param v       The new value for the register
*/
void set_register(int address, unsigned char r, unsigned char v){
Wire.beginTransmission(address);
Wire.write(r);
Wire.write(v);
Wire.endTransmission();
}


运行结果:


完整代码下载


参考:
1. http://wenku.baidu.com/link?url=77EtEpflHOBF9LmqwOvIwe5ONZ6I548h4BcBk4Ep1XWVO_RVDj9fycwoku44RENseV48lzvnrnDasY3UAMHsBuuU7yVdxFsAfxq-zbDiEhy MPR121中文数据手册
2. https://learn.sparkfun.com/tutorials/mpr121-hookup-guide
3. https://item.taobao.com/item.htm?spm=a1z09.2.0.0.kpoNRc&id=19968128319&_u=pkf8s90f4c
4. MPR121 DataSheet

本文 LTS 在 http://www.lab-z.com/mpr121/

li23108 发表于 2016-3-24 19:41:06

正在完这个芯片,打算做一个水位识别的,不知道多触摸同时如何工作。

zoologist 发表于 2016-3-24 20:09:32

li23108 发表于 2016-3-24 19:41 static/image/common/back.gif
正在完这个芯片,打算做一个水位识别的,不知道多触摸同时如何工作。

我觉得水位测试还是非接触式的比较靠谱吧?

li23108 发表于 2016-3-25 13:28:11

zoologist 发表于 2016-3-24 20:09 static/image/common/back.gif
我觉得水位测试还是非接触式的比较靠谱吧?

我在优酷看到有用电容式的,类似薄膜按键那种,挺好的。今天试用了一下代码,是有点误动作,不知道灵敏度应该可以调吧,采样率之类的,资料比较少,官网的E文有些看不懂。正在研究呢。实在不行在试试超声波的。

li23108 发表于 2016-3-26 08:16:56



外部粘一层塑料薄膜没问题,就是程序初始化时不输出,必须有动作时才有变化显示,看来真是不行啊,研究研究电感式的吧,这个做成音乐玩具还是很好的。

zoologist 发表于 2016-3-26 13:06:03

li23108 发表于 2016-3-26 08:16 static/image/common/back.gif
外部粘一层塑料薄膜没问题,就是程序初始化时不输出,必须有动作时才有变化显示,看来真是不行啊,研究 ...

恩 我打算用它作个石头剪子布的游戏看看

莫斯科匪徒 发表于 2016-5-14 21:05:03

哥们! 在么 你之前那个用arduino做PPT遥控器的帖子还记得吧,我想问问 里面是用的atmage8U2的单片机 ?
我看淘宝现在都是16U2的啊?是ARDUINO UNO么?
求助哥们!!
页: [1]
查看完整版本: MPR121 触摸传感器模块