• Arduino UNO驱动MPR121接近电容式触摸传感器控制WS2812彩灯


    简介

      MPR121芯片功能强大可用作触摸,电容检测,驱动LED等等.在低速扫描下可以将功 耗降低到8μA,可以处理多达12个独立的触摸板。支持I2C,几乎可以用任何微控 制器连接。可以使用ADDR引脚选择4个地址中的一个,一个I2C2线总线上共有48 个电容触摸板。使用该芯片比使用模拟输入进行电容式感应要容易得多,并且可以 配置灵敏度。

    参数特性

    1. 工作电压:2.5V-3.6VDC
    2. 采样频率:采样间隔时间为16ms时,电源电流为29μA,停止模式电流3μA
    3. 输出接口:12个电容传感输入
    4. 输入接口:8个输入为LED驱动器和GPIO多功能
    5. 完整的触摸检测:每个传感输入的自动配置自动校准
    6. 触摸/释放阈值和去抖动以进行触摸检测
    7. I2C接口,带中断输出
    8. 工作温度范围:-40℃至+85℃
    9. 尺寸:30.5*20.6mm

    引脚定义

    名称描述
    IRQ开路集电极中断输出引脚,低电平激活
    SCLI 2C时钟
    SDAI2C数据
    ADDRI 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 / WS2812Arduino UNO
    MPR121-SCLA5
    MPR121-SDAA4
    WS2812-IOIO8
    MPR121-3.3V3.3V
    WS2812-5V5V
    GNDGND

    示例代码

    #include 
    #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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164

    示例演示

  • 相关阅读:
    手把手教会你微前端开发(vue-qiankun)
    4、建造者模式
    拆贡献+统计非法可能不统计非法贡献:ARC150D
    ICO操作Bean管理的(bean的作用域和生命周期)
    Nacos配置中心HelloWorld入门实例
    windows 中, bash: conda: command not found(已解决)
    如何写出让人抓狂的代码?
    RabbitMQ消费者消失与 java OOM
    基于Pytorch的CNN手写数字识别
    chatgpt 接口 和 jupyter版本安装
  • 原文地址:https://blog.csdn.net/qq_42250136/article/details/137879774