ndfweb.cn

MPR121連接Arduino指南


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



英文原文地址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网站建设淘宝店 | ICO图标在线生成 | 外贸网站建设 | 联系我们
©2007-2025 NDF Corporation 鲁ICP备08005967号 Sitemap - RSSRSS订阅