简介
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 RGB
CRGB 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 0x5D
if (!cap.begin(0x5A)) {
Serial.println("MPR121 not found, check wiring?");
while (1);
}
Serial.println("MPR121 found!");
}
void loop() {
// Get the currently touched pads
currtouched = 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 state
lasttouched = currtouched;
// comment out this line for detailed data from the sensor!
return;
// debugging info, what
Serial.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 overwhelming
delay(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();
}