简介
MPR121芯片功能强大可用作触摸,电容检测,驱动LED等等.在低速扫描下可以将功 耗降低到8μA,可以处理多达12个独立的触摸板。支持I2C,几乎可以用任何微控 制器连接。可以使用ADDR引脚选择4个地址中的一个,一个I2C2线总线上共有48 个电容触摸板。使用该芯片比使用模拟输入进行电容式感应要容易得多,并且可以 配置灵敏度。
参数特性
- 工作电压:2.5V-3.6VDC
- 采样频率:采样间隔时间为16ms时,电源电流为29μA,停止模式电流3μA
- 输出接口:12个电容传感输入
- 输入接口:8个输入为LED驱动器和GPIO多功能
- 完整的触摸检测:每个传感输入的自动配置自动校准
- 触摸/释放阈值和去抖动以进行触摸检测
- I2C接口,带中断输出
- 工作温度范围:-40℃至+85℃
- 尺寸:30.5*20.6mm
引脚定义
名称 | 描述 |
---|---|
IRQ | 开路集电极中断输出引脚,低电平激活 |
SCL | I 2C时钟 |
SDA | I2C数据 |
ADDR | I 2C地址选择输入引脚。将ADDR引脚连接到VSS、VDD、SDA或SCL线,得到I2C地址分别为0x5A、0x5B、0x5C和0x5D |
VREG | 内部调节器节点 |
VSS | 地 |
REXT | 外部电阻器-将一个75 kΩ1%的电阻器连接到VSS,以设置内部参考电流 |
ELE0 - 11 | 电极0 - 11 |
VDD | 电源输入 |
典型应用实例及电极图案
硬件准备
Arduino UNO板、MPR121电容触摸模块、WS2812模块。
引脚接线
MPR121 / WS2812 | Arduino UNO |
---|---|
MPR121-SCL | A5 |
MPR121-SDA | A4 |
WS2812-IO | IO8 |
MPR121-3.3V | 3.3V |
WS2812-5V | 5V |
GND | GND |
示例代码
#include <Wire.h>
#include "Adafruit_MPR121.h"
#include "FastLED.h"
#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif#define NUM_LEDS 9
#define LED_DT 8
#define LED_TYPE WS2812
#define COLOR_ORDER RGBCRGB leds[NUM_LEDS];
CHSV myHSVcolor(45, 255, 200);// You can have up to 4 on one i2c bus but one is enough for testing!
Adafruit_MPR121 cap = Adafruit_MPR121();// Keeps track of the last pins touched
// so we know when buttons are 'released'
uint8_t parseNum = 0;
uint8_t paletteNum = 0;
uint8_t startIndex = 0;
uint8_t chromatism = 50;
uint16_t lasttouched = 0;
uint16_t currtouched = 0;void setup() {LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);FastLED.setBrightness(128);Serial.begin(9600);while (!Serial) { // needed to keep leonardo/micro from starting too fast!delay(10);}Serial.println("Adafruit MPR121 Capacitive Touch sensor test");// Default address is 0x5A, if tied to 3.3V its 0x5B// If tied to SDA its 0x5C and if SCL then 0x5Dif (!cap.begin(0x5A)) {Serial.println("MPR121 not found, check wiring?");while (1);}Serial.println("MPR121 found!");
}void loop() {// Get the currently touched padscurrtouched = cap.touched();for (uint8_t i = 0; i < 12; i++) {// it if *is* touched and *wasnt* touched before, alert!if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {switch (i) {case 0:stateLed_ON(parseNum++);if (parseNum > 10) {parseNum = 0;}break;case 1: stateLed_OFF(); break;case 2:dynamicLED(paletteNum, startIndex);paletteNum++;if (paletteNum > 1) {paletteNum = 0;}break;}}}// reset our statelasttouched = currtouched;// comment out this line for detailed data from the sensor!return;// debugging info, whatSerial.print("\t\t\t\t\t\t\t\t\t\t\t\t\t 0x"); Serial.println(cap.touched(), HEX);Serial.print("Filt: ");for (uint8_t i = 0; i < 12; i++) {Serial.print(cap.filteredData(i)); Serial.print("\t");}Serial.println();Serial.print("Base: ");for (uint8_t i = 0; i < 12; i++) {Serial.print(cap.baselineData(i)); Serial.print("\t");}Serial.println();// put a delay so it isn't overwhelmingdelay(100);
}void stateLed_ON(uint8_t parseNum) { //点亮单色调颜色switch (parseNum) {case 0: fill_solid(leds, NUM_LEDS, CRGB::Crimson); FastLED.show(); break;case 1: fill_solid(leds, NUM_LEDS, CRGB::Aqua); FastLED.show(); break;case 2: fill_solid(leds, NUM_LEDS, CRGB::Amethyst); FastLED.show(); break;case 3: fill_solid(leds, NUM_LEDS, CRGB::Blue); FastLED.show(); break;case 4: fill_solid(leds, NUM_LEDS, CRGB::Chartreuse); FastLED.show(); break;case 5: fill_solid(leds, NUM_LEDS, CRGB::DarkOrange); FastLED.show(); break;case 6: fill_solid(leds, NUM_LEDS, CRGB::DeepPink); FastLED.show(); break;case 7: fill_solid(leds, NUM_LEDS, CRGB::GhostWhite); FastLED.show(); break;case 8: fill_solid(leds, NUM_LEDS, CRGB::Gold); FastLED.show(); break;case 9: fill_solid(leds, NUM_LEDS, CRGB::GreenYellow); FastLED.show(); break;case 10: fill_solid(leds, NUM_LEDS, CRGB::MediumSpringGreen); FastLED.show(); break;}FastLED.show();
}void stateLed_OFF() {fill_solid(leds, NUM_LEDS, CRGB::Black);FastLED.show();
}void dynamicLED(uint8_t paletteNum, uint8_t colorIndex) {switch (paletteNum) {case 0: gradientflowingLED(); break;case 1: FillLEDsFromPaletteColors(colorIndex); break;}
}void gradientflowingLED() {for (int i = 0; i < NUM_LEDS; i++) {fill_solid(leds + i, 1, myHSVcolor);FastLED.show();myHSVcolor.h += 10;delay(50);fill_solid(leds + i, 1, CRGB::Black);FastLED.show();delay(50);}for (int i = NUM_LEDS; i > 0; i--) {fill_solid(leds + i, 1, myHSVcolor);FastLED.show();myHSVcolor.h += 10;delay(50);fill_solid(leds + i, 1, CRGB::Black);FastLED.show();delay(50);}
}void FillLEDsFromPaletteColors(uint8_t colorIndex)
{for (int i = 0; i < chromatism; i++) {colorIndex++;for ( int j = 0; j < NUM_LEDS; ++j) {leds[j] = ColorFromPalette(RainbowColors_p, colorIndex, 255, LINEARBLEND);colorIndex += 3;FastLED.show();FastLED.delay(10);}}fill_solid(leds, NUM_LEDS, CRGB::Black);FastLED.show();
}