ndfweb.cn

MPR121连接Arduino指南


2021-06-20 11:00:04 (8489)


英文原文地址https://learn.sparkfun.com/tutorials/mpr121-hookup-guide

MPR121QR2 是一款电容式触摸传感器控制器,可以非常轻松地将电容式触摸感应集成到您的项目中。它通过I 2 C 进行通信,并通过测量十二个电极点的电容来工作。当物体靠近电极连接器时,测得的电容会发生变化。这向 MPR121 发出信号,表明某物触及了“按钮”。该 IC 还能够驱动电极引脚 4 到 11 上的 LED 或基本 GPIO 功能,为您设置项目提供了很大的自由。传感器的工作电压为 1.6V 至 3.3V。该传感器不是很耗电,每 16 毫秒采样时仅消耗约 29 µA。

材料

要完成本教程,您将需要 MPR121 传感器的三个版本之一:

您还需要一个烙铁、一些连接线和一个能够进行 I 2 C 通信的微控制器对于我们的示例,我们将使用 Arduino Uno。您还需要某种材料来充当电容感应表面(也称为电极,不要与字符Electrode混淆。通常,铝箔效果很好。但是,您也可以使用硬币、导电涂料,或铜带。

推荐阅读

MPR121 非常容易上手,尤其是示例代码。但是,如果您以前没有使用过 Arduino 或不熟悉 I 2 C 通信,您应该查看下面的教程。

电容式触摸传感器分线板

SparkFun电容式触摸传感器接口板是最通用的三个MPR121产品的选择。您可以将它连接到您想要的任何类型的电极上,而且由于它是一个简单的分线板,没有它喜欢的特定微控制器占用空间。

SparkFun 电容式触摸传感器突破 - MPR121

SparkFun 电容式触摸传感器突破 - MPR121

SEN-09695

     5 退休

分线板有 4 个引脚,至少需要连接到您的微控制器才能进行通信:电源线和 I 2 C 线。但是,对于我们的示例,我们还将连接 IRQ 引脚以更轻松地检测其中一个电极的变化。

连接

MPR121 Breakout → Arduino Uno

  • 3.3V → 3.3V

  • SCL → A5

  • SDA → A4

  • GND→GND

  • IRQ → D2

您还需要将电极/LED 引脚连接到您之前选择的电极材料。您需要确保材料和电路板之间有良好、牢固的连接,因此请确保彻底焊接连接。

查看下面的弗里茨图,了解您的连接应该是什么样子。黄色方块代表您决定用于电极的任何材料。


分线板连接


与分线板沟通

要与您的分线板通信,您需要在此处以 zip 文件形式提供 Arduino 草图或者,您还可以在GitHub找到用于使用分线板的最新固件让我们看一看,看看代码到底在做什么。

复制代码    #include "mpr121.h"
    #include <Wire.h>
    int irqpin = 2;  // Digital 2
    boolean touchStates[12]; //to keep track of the previous touch states

在代码的第一部分中,初始化了 MPR121 库和 Wire 库。Wire 库使 I 2 C 通信易于在 Arduino 上使用。该草图还将数字引脚 2 定义为 IRQ 引脚连接,并创建布尔变量 touchStates 的 12 个实例。

对于代码的第二部分,我们将 定义irqpin为 INPUT,告诉 Arduino 监视通过该引脚传入的数字信号。串行通信也以 9600 bps 以及 Wire 和 mpr121 库开始。

复制代码    void setup(){        pinMode(irqpin, INPUT);        digitalWrite(irqpin, HIGH); //enable pullup resistor
        Serial.begin(9600);
        Wire.begin();
        mpr121_setup();
    }

代码的主循环非常简单,因为它只调用了一个函数。

复制代码    void loop(){        readTouchInputs();
    }

该功能实际上在代码的下一部分中描述。Arduino 在第一部分向传感器请求电极状态,并为传感器定义了最低有效位和最高有效位。

复制代码void readTouchInputs(){  if(!checkInterrupt()){
    //read the touch state from the MPR121
    Wire.requestFrom(0x5A,2); 
    byte LSB = Wire.read();
    byte MSB = Wire.read();
    uint16_t touched = ((MSB << 8) | LSB); //16bits that make up the touch states
    for (int i=0; i < 12; i++){  // Check what electrodes were pressed
      if(touched & (1<<i)){
        if(touchStates[i] == 0){          //pin i was just touched
          Serial.print("pin ");
          Serial.print(i);
          Serial.println(" was just touched");
        }else if(touchStates[i] == 1){          //pin i is still being touched
        }  
        touchStates[i] = 1;      
      }else{        if(touchStates[i] == 1){
          Serial.print("pin ");
          Serial.print(i);
          Serial.println(" is no longer being touched");
          //pin i is no longer being touched
       }
        touchStates[i] = 0;
      }
    }
  }}

Arduino 扫描每个电极并在电极被触发时通过串行打印出一条消息。一旦不再接触电极,Arduino 就会打印出一条消息。

代码的最后一个主要部分定义了每个电极的阈值。每个电极必须有一个触摸阈值和一个释放阈值,以便 Arduino 比较电极的当前状态。

复制代码void mpr121_setup(void){
  set_register(0x5A, ELE_CFG, 0x00); 
  // Section A - Controls filtering when data is > baseline.
  set_register(0x5A, MHD_R, 0x01);  set_register(0x5A, NHD_R, 0x01);  set_register(0x5A, NCL_R, 0x00);  set_register(0x5A, FDL_R, 0x00);
  // Section B - Controls filtering when data is < baseline.
  set_register(0x5A, MHD_F, 0x01);  set_register(0x5A, NHD_F, 0x01);  set_register(0x5A, NCL_F, 0xFF);  set_register(0x5A, FDL_F, 0x02);
  // 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 Filter Configuration
  // Set ESI2
  set_register(0x5A, FIL_CFG, 0x04);
  // Section E
  // Electrode Configuration
  // Set ELE_CFG to 0x00 to return to standby mode
  set_register(0x5A, ELE_CFG, 0x0C);  // Enables all 12 Electrodes
  // Section F
  // Enable Auto Config and auto Reconfig
  /*set_register(0x5A, ATO_CFG0, 0x0B);
  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, ELE_CFG, 0x0C);}

它看起来像很多代码,但它只是重复为每个电极引脚设置阈值的过程。

示例草图中的最后两个函数只是检查 的状态irqpin以确定 IC 是否发出电极已被触摸的信号。最后一个函数set_register只是通过 Wire 库中的标准步骤运行 Arduino,将寄存器写入 IC。

复制代码boolean checkInterrupt(void){
  return digitalRead(irqpin);}void set_register(int address, unsigned char r, unsigned char v){
    Wire.beginTransmission(address);
    Wire.write(r);
    Wire.write(v);
    Wire.endTransmission();}

现在您对代码有了基本的了解,让我们开始阅读数据。从您之前下载的文件中打开草图,并将其上传到您的 Arduino。上传后,在 Arduino IDE 中打开串行监视器。如果您按下任何电极或释放任何电极,您应该开始看到 Arduino 打印出句子。


其他代码参考:

  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. }


了解更多请访问:http://www.ndfweb.cn/news-869.html
  NDF俱乐部
  国际域名注册
  建站咨询
合作伙伴:万网 | 新网 | 新网互联 NDF网站建设淘宝店 | 实用工具 | 外貿網站建設 | 联系我们
鲁公网安备 37110202000336号 鲁ICP备2021027697号-1 Sitemap - RSSRSS订阅