英文原文地址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产品的选择。您可以将它连接到您想要的任何类型的电极上,而且由于它是一个简单的分线板,没有它喜欢的特定微控制器占用空间。
SEN-09695
退休
分线板有 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 打印出句子。
其他代码参考:
#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[SENSORS];    // holds the current touch/prox state of all sensors
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)
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[i] == 0) continue;
      char sensor_id [] = {'\0','\0','\0'};
      switch (i) {
        case 12:
          sensor_id[0] = 'P';
          break;
        default:
          if (i < 10) {
            sensor_id[0] = char( i+48 );
          } 
          else if (i < 12) {
            sensor_id[0] = char('1');
            sensor_id[1] = 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[i] == 0){          
            Serial.print(sensor_id);        
            Serial.print(":");
            Serial.println("1");
          } 
          touchStates[i] = 1;      
        } else {
          // if current pin was just touched send serial message
          if(touchStates[i] == 1){
            Serial.print(sensor_id);
            Serial.print(":");
            Serial.println("0");
          }
          touchStates[i] = 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();
}
| NDF网站建设淘宝店 | 联系我们 | 
| ©2007-2025 NDF Corporation |