极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 20866|回复: 6

MPR121 触摸传感器模块

[复制链接]
发表于 2016-3-21 21:00:59 | 显示全部楼层 |阅读模式
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 上编译通过)

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

  3. #define SENSORS       13
  4. #define TOU_THRESH    0x1F
  5. #define REL_THRESH    0x1A
  6. #define PROX_THRESH   0x3f
  7. #define PREL_THRESH   0x3c

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

  13. void setup(){

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

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

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

  21. }

  22. void loop(){
  23.   readCapacitiveSensor();
  24. }

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

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

  45.     for (int i = 0; i < SENSORS; i++){  // Check what electrodes were pressed
  46.       if (activeSensors[i] == 0) continue;
  47.       char sensor_id [] = {'\0','\0','\0'};
  48.       switch (i) {
  49.         case 12:
  50.           sensor_id[0] = 'P';
  51.           break;
  52.         default:
  53.           if (i < 10) {
  54.             sensor_id[0] = char( i+48 );
  55.           }
  56.           else if (i < 12) {
  57.             sensor_id[0] = char('1');
  58.             sensor_id[1] = char( ( i % 10 ) + 48 );
  59.           }
  60.       }
  61.       if (sensor_id != '\0') {
  62.         // read the humidity level

  63.         // if current sensor was touched (check appropriate bit on touched var)
  64.         if(touched & (1<<i)){      
  65.           // if current pin was not previously touched send a serial message
  66.           if(touchStates[i] == 0){         
  67.             Serial.print(sensor_id);        
  68.             Serial.print(":");
  69.             Serial.println("1");
  70.           }
  71.           touchStates[i] = 1;      
  72.         } else {
  73.           // if current pin was just touched send serial message
  74.           if(touchStates[i] == 1){
  75.             Serial.print(sensor_id);
  76.             Serial.print(":");
  77.             Serial.println("0");
  78.           }
  79.           touchStates[i] = 0;
  80.         }        
  81.       }
  82.     }
  83.     newData = false;
  84.   }
  85. }

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

  92.   set_register(0x5A, ELE_CFG, 0x00);
  93.   
  94.   // Section A - filtering when data is > baseline.
  95.     // touch sensing
  96.     set_register(0x5A, MHD_R, 0x01);
  97.     set_register(0x5A, NHD_R, 0x01);
  98.     set_register(0x5A, NCL_R, 0x00);
  99.     set_register(0x5A, FDL_R, 0x00);

  100.     // prox sensing
  101.     set_register(0x5A, PROX_MHDR, 0xFF);
  102.     set_register(0x5A, PROX_NHDAR, 0xFF);
  103.     set_register(0x5A, PROX_NCLR, 0x00);
  104.     set_register(0x5A, PROX_FDLR, 0x00);

  105.   // Section B - filtering when data is < baseline.
  106.     // touch sensing
  107.     set_register(0x5A, MHD_F, 0x01);
  108.     set_register(0x5A, NHD_F, 0x01);
  109.     set_register(0x5A, NCL_F, 0xFF);
  110.     set_register(0x5A, FDL_F, 0x02);
  111.   
  112.     // prox sensing
  113.     set_register(0x5A, PROX_MHDF, 0x01);
  114.     set_register(0x5A, PROX_NHDAF, 0x01);
  115.     set_register(0x5A, PROX_NCLF, 0xFF);
  116.     set_register(0x5A, PROX_NDLF, 0xFF);

  117.   // Section C - Sets touch and release thresholds for each electrode
  118.     set_register(0x5A, ELE0_T, TOU_THRESH);
  119.     set_register(0x5A, ELE0_R, REL_THRESH);
  120.    
  121.     set_register(0x5A, ELE1_T, TOU_THRESH);
  122.     set_register(0x5A, ELE1_R, REL_THRESH);
  123.    
  124.     set_register(0x5A, ELE2_T, TOU_THRESH);
  125.     set_register(0x5A, ELE2_R, REL_THRESH);
  126.    
  127.     set_register(0x5A, ELE3_T, TOU_THRESH);
  128.     set_register(0x5A, ELE3_R, REL_THRESH);
  129.    
  130.     set_register(0x5A, ELE4_T, TOU_THRESH);
  131.     set_register(0x5A, ELE4_R, REL_THRESH);
  132.    
  133.     set_register(0x5A, ELE5_T, TOU_THRESH);
  134.     set_register(0x5A, ELE5_R, REL_THRESH);
  135.    
  136.     set_register(0x5A, ELE6_T, TOU_THRESH);
  137.     set_register(0x5A, ELE6_R, REL_THRESH);
  138.    
  139.     set_register(0x5A, ELE7_T, TOU_THRESH);
  140.     set_register(0x5A, ELE7_R, REL_THRESH);
  141.    
  142.     set_register(0x5A, ELE8_T, TOU_THRESH);
  143.     set_register(0x5A, ELE8_R, REL_THRESH);
  144.    
  145.     set_register(0x5A, ELE9_T, TOU_THRESH);
  146.     set_register(0x5A, ELE9_R, REL_THRESH);
  147.    
  148.     set_register(0x5A, ELE10_T, TOU_THRESH);
  149.     set_register(0x5A, ELE10_R, REL_THRESH);
  150.    
  151.     set_register(0x5A, ELE11_T, TOU_THRESH);
  152.     set_register(0x5A, ELE11_R, REL_THRESH);

  153.   // Section D - Set the touch filter Configuration
  154.     set_register(0x5A, FIL_CFG, 0x04);  

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

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

  160.   // Section G - Set Auto Config and Auto Reconfig for prox sensing
  161.     set_register(0x5A, ATO_CFGU, 0xC9);  // USL = (Vdd-0.7)/vdd*256 = 0xC9 @3.3V   
  162.     set_register(0x5A, ATO_CFGL, 0x82);  // LSL = 0.65*USL = 0x82 @3.3V
  163.     set_register(0x5A, ATO_CFGT, 0xB5);  // Target = 0.9*USL = 0xB5 @3.3V
  164.     set_register(0x5A, ATO_CFG0, 0x0B);

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

  168. /**
  169. * set_register Sets a register on a device connected via I2C. It accepts the device's address,
  170. *   register location, and the register value.
  171. * @param address The address of the I2C device
  172. * @param r       The register's address on the I2C device
  173. * @param v       The new value for the register
  174. */
  175. void set_register(int address, unsigned char r, unsigned char v){
  176.   Wire.beginTransmission(address);
  177.   Wire.write(r);
  178.   Wire.write(v);
  179.   Wire.endTransmission();
  180. }
复制代码


运行结果:


完整代码下载


参考:
1. http://wenku.baidu.com/link?url= ... 7yVdxFsAfxq-zbDiEhy MPR121中文数据手册
2. https://learn.sparkfun.com/tutorials/mpr121-hookup-guide
3. https://item.taobao.com/item.htm ... 9&_u=pkf8s90f4c
4. MPR121 DataSheet

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2016-3-24 19:41:06 | 显示全部楼层
正在完这个芯片,打算做一个水位识别的,不知道多触摸同时如何工作。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-24 20:09:32 | 显示全部楼层
li23108 发表于 2016-3-24 19:41
正在完这个芯片,打算做一个水位识别的,不知道多触摸同时如何工作。

我觉得水位测试还是非接触式的比较靠谱吧?
回复 支持 反对

使用道具 举报

发表于 2016-3-25 13:28:11 | 显示全部楼层
zoologist 发表于 2016-3-24 20:09
我觉得水位测试还是非接触式的比较靠谱吧?

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

使用道具 举报

发表于 2016-3-26 08:16:56 | 显示全部楼层


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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

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

恩 我打算用它作个石头剪子布的游戏看看
回复 支持 反对

使用道具 举报

发表于 2016-5-14 21:05:03 | 显示全部楼层
哥们! 在么 你之前那个用arduino做PPT遥控器的帖子还记得吧,我想问问 里面是用的atmage8U2的单片机 ?
我看淘宝现在都是16U2的啊?  是ARDUINO UNO么?
求助哥们!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 00:10 , Processed in 0.048212 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表