MPR121 and FastLED animations

I want to start by saying I'm a beginner, I've been researching this issue for weeks now and haven't come up with a reliable solution yet.

I'm trying to use two pads on an MPR121 to trigger an animation while the pads is held down, and stop the animation when the pad is released. Each pad controls 12 LEDs on a ring of 24.
Right now I can press both pads simultaneously to turn the lights on and off, but instead of running an animation, it just turns on one light from each side. If I press the pads rapidly, it will turn random lights on and off, but never goes through the animation.
I'm not sure if the issue is with my code or something else.

Hardware:
Arduino Nano, MPR121, Neopixel ring w/ 24 LEDs.

I'm afraid that in my attempts to fix this, I overcomplicated my code for what I'm trying to achieve.
Both of the animations worked on their own without being controlled by the MPR121.
What am I missing to make this work?
This is what my code is now:

```cpp
#include <FastLED.h>
#include <Wire.h>
#include "Adafruit_MPR121.h"

#define NUM_LEDS 24
#define LED_PIN 7

#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif

Adafruit_MPR121 cap = Adafruit_MPR121();
CRGB leds[NUM_LEDS];
uint16_t lasttouched = 0;
uint16_t currtouched = 0;

void setup() {
  cap.begin(0x5a);
  FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(50);
}

void loop() {

  currtouched = cap.touched();
  int state = 0;

  for (uint8_t i = 0; i < 12; i++) {
    if ((currtouched & _BV(2)) && !(lasttouched & _BV(2))) {
      state = 1;
    }

    if ((currtouched & _BV(8)) && !(lasttouched & _BV(8))) {
      state = 2;
    }

    if (!(currtouched & _BV(2)) && (lasttouched & _BV(2))) {
      state = 3;
    }
    if (!(currtouched & _BV(8)) && (lasttouched & _BV(8))) {
      state = 4;
    }
    lasttouched = currtouched;
  }
  switch (state) {
    case 1:
      blueDot();
      break;

    case 2:
      orangeDot();
      break;

    case 3:
      blueStop();
      break;

    case 4:
      orangeStop();
      break;
  }
}

void blueDot() {
  uint8_t sinBeat = beatsin8(30, 0, 11, 0, 0);
  leds[sinBeat] = CHSV(120, 255, 150);
  fadeToBlackBy(leds, sinBeat, 10);

  FastLED.show();
}

void orangeDot() {
  uint8_t sinBeat2 = beatsin8(30, 12, 23, 0, 0);
  leds[sinBeat2] = CHSV(11, 255, 150);
  fadeToBlackBy(leds, sinBeat2, 10);
  FastLED.show();
}

void orangeStop() {
  for (int i = 12; i <= 23; i++) {
    leds[i] = CRGB::Black;
    FastLED.show();
  }
}

void blueStop() {
  for (int i = 0; i <= 11; i++) {
    leds[i] = CRGB::Black;
    FastLED.show();
  }
}
Thanks in advance.

Why do you execute this code 12 times? It would be quite tricky to get a state change exactly at the last run of this loop.

Your touch button reading code doesn't handle if you start touching or stop touching both buttons at the same time.

If you run the animations that way you cannot control them while they're running.

I deleted the line you quoted and everything is still the same, still only one led turns on with each button.
Even when I touch the buttons individually, the animation doesn't run. It only turns on one light. I also tried it with only one button and one animation; still doesn't trigger the full animation.
What do I need to change to trigger the animation with one of these buttons?

Why would you expect more than one LED to turn on? The code does activate only only one LED at a time and you reset state to 0 at the start of loop().

I guess what I am trying to ask is, How can I get 12 LEDs to turn on in sequence?
The animation is supposed to turn on 12 LEDs in a sequence. I thought that is what I programmed but apparently not. I am sorry for the confusion, again I am a beginner. I’m trying to figure out where I went wrong because I genuinely don’t know…

Don't reset your state in every loop() run.
Define it globally and initialize it there.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.