Adafruit Neopixel Ring turn off automatically

Hi,

I am quite new to Arduino and have no programming background so far. For a project in university we need to make something with Arduino. What I have isa Touch sensor, that when Touching it turns the Neopixel Ring on. What I want to do is to turn the Neopixel Ring on and make it turn off automatically again after 2-3 seconds. However so far, it only turns off, when I touch the touch sensor again. Any ideas on how I can achieve that? I provided the code below for reference:

#include <Adafruit_NeoPixel.h> //Include the NeoPixel library

#define NEO_PIN 6 // DIGITAL IO pin for NeoPixel OUTPUT from GEMMA
#define TOUCH_PIN 3 // DIGITAL IO pin for momentary touch sensor INPUT to GEMMA
#define PIXEL_COUNT 12 // Number of NeoPixels connected to GEMMA
#define DELAY_MILLIS 10 // delay between blinks, smaller numbers are faster
#define DELAY_MULT 8 // Randomization multiplier on the delay speed of the effect
#define BRIGHT 100 // Brightness of the pixels, max is 255

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number on Arduino (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_GRB Pixels are wired for GRB bitstream, correct for neopixel stick (most NeoPixel products)
// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)
// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(PIXEL_COUNT, NEO_PIN, NEO_GRB + NEO_KHZ800);

bool oldState = HIGH; //sets the initial variable for counting touch sensor button pushes
int showColor = 0; //color mode for cycling

void setup() {
pinMode(TOUCH_PIN, INPUT); //Initialize touch sensor pin as input using external pull-up resistor
pixels.begin();
pixels.setBrightness(BRIGHT);
pixels.show(); //Set all pixels to "off"
}

void loop() {
int RColor = 255; //color (0-255) values to be set by cylcing touch switch, initially GOLD
int GColor = 0 ;
int BColor = 0 ;

if (showColor==0) { // Black off
RColor = 0;
GColor = 0;
BColor = 0;
}
if (showColor==1) {// Alchemy Blue
RColor = 50;
GColor = 255;
BColor = 255;
}

if (showColor==2) {// Black off
RColor = 0;
GColor = 0;
BColor = 0;
}
if (showColor==3) {// Tinker Green
RColor = 0;
GColor = 255;
BColor = 40;
}
if (showColor==4) {//Black off
RColor = 0;
GColor = 0;
BColor = 0;
}

//sparkling
int p = random(PIXEL_COUNT); //select a random pixel
pixels.setPixelColor(p,RColor,GColor,BColor); //color value comes from cycling state of momentary switch
pixels.show();

//button check to cycle through color value sets
bool newState = digitalRead(TOUCH_PIN); //Get the current button state
// Check if state changed from high to low (button press).
if (newState == LOW && oldState == HIGH) {
// Short delay to debounce button.
delay(20);
// Check if button is still low after debounce.
newState = digitalRead(TOUCH_PIN);
if (newState == LOW) {
showColor++;
if (showColor > 3)
showColor=0;
}
}
// Set the last button state to the old state.
oldState = newState;

}

firstly, please use [code ] tags to make your post more readable.

Secondly, this can be achieved quite easily using millis()

#include <Adafruit_NeoPixel.h>  //Include the NeoPixel library

#define NEO_PIN 6        // DIGITAL IO pin for NeoPixel OUTPUT from GEMMA
#define TOUCH_PIN 3      // DIGITAL IO pin for momentary touch sensor INPUT to GEMMA
#define PIXEL_COUNT 12   // Number of NeoPixels connected to GEMMA
#define DELAY_MILLIS 10  // delay between blinks, smaller numbers are faster
#define DELAY_MULT 8     // Randomization multiplier on the delay speed of the effect
#define BRIGHT 100        // Brightness of the pixels, max is 255

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number on Arduino (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick (most NeoPixel products)
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(PIXEL_COUNT, NEO_PIN, NEO_GRB + NEO_KHZ800);

bool oldState = HIGH; //sets the initial variable for counting touch sensor button pushes
int showColor = 0;    //color mode for cycling

unsigned long pressTime; // timestamp when the button is pressed
int onTime = 2500; // interval leds stay on, in ms

void setup() {
  pinMode(TOUCH_PIN, INPUT);    //Initialize touch sensor pin as input using external pull-up resistor
  pixels.begin();
  pixels.setBrightness(BRIGHT);
  pixels.show();                //Set all pixels to "off"
}


void loop() {
  int RColor = 255; //color (0-255) values to be set by cylcing touch switch, initially GOLD
  int GColor = 0 ;
  int BColor = 0 ;
 
       if (showColor==0) { // Black off
         RColor = 0;
         GColor = 0;
         BColor = 0;
       }
       if (showColor==1) {// Alchemy Blue
         RColor = 50;
         GColor = 255;
         BColor = 255;
       }
       
       if (showColor==2) {// Black off
         RColor = 0;
         GColor = 0;
         BColor = 0;
       }
       if (showColor==3) {// Tinker Green
         RColor = 0;
         GColor = 255;
         BColor = 40;
       }
       if (showColor==4) {//Black off
         RColor = 0;
         GColor = 0;
         BColor = 0;
       }
 
  //sparkling
  int p = random(PIXEL_COUNT); //select a random pixel
  pixels.setPixelColor(p,RColor,GColor,BColor); //color value comes from cycling state of momentary switch
  pixels.show();

  //button check to cycle through color value sets
  bool newState = digitalRead(TOUCH_PIN); //Get the current button state
  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(TOUCH_PIN);
    if (newState == LOW) {

      pressTime = millis(); // record timestep when button was pressed

      showColor++;
      if (showColor > 3)
        showColor=0;
       }   
  }

  // Set the last button state to the old state.
  oldState = newState; 

  // advance the state of interval has passed
  if ((millis()-pressTime)>onTime) {
    showColor++;
    if (showColor > 3)
      showColor=0;
     } 
  }
 
}

On second thought, I don't like the idea of having the "black offs" in the list of states, since now, there is no (elegant) way of knowing inside the loop, whether the lights are on or off. I'd suggest adding a "are the leds on" boolean.

For example:

On second thought, I don't like the idea of having the "black offs" in the list of states, since now, there is no (elegant) way of knowing inside the loop, whether the lights are on or off. I'd suggest adding a "are the leds on" boolean.

For example:

#include <Adafruit_NeoPixel.h>  //Include the NeoPixel library

#define NEO_PIN 6        // DIGITAL IO pin for NeoPixel OUTPUT from GEMMA
#define TOUCH_PIN 3      // DIGITAL IO pin for momentary touch sensor INPUT to GEMMA
#define PIXEL_COUNT 12   // Number of NeoPixels connected to GEMMA
#define DELAY_MILLIS 10  // delay between blinks, smaller numbers are faster
#define DELAY_MULT 8     // Randomization multiplier on the delay speed of the effect
#define BRIGHT 100        // Brightness of the pixels, max is 255

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number on Arduino (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick (most NeoPixel products)
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(PIXEL_COUNT, NEO_PIN, NEO_GRB + NEO_KHZ800);

bool oldState = HIGH; //sets the initial variable for counting touch sensor button pushes
int showColor = 0;    //color mode for cycling

bool ledsOn = 0; // are the LEDs on?

unsigned long pressTime; // timestamp when the button is pressed
int onTime = 2500; // interval leds stay on, in ms

void setup() {
  pinMode(TOUCH_PIN, INPUT);    //Initialize touch sensor pin as input using external pull-up resistor
  pixels.begin();
  pixels.setBrightness(BRIGHT);
  pixels.show();                //Set all pixels to "off"
}


void loop() {

  // what does this do? it is never used.
  int RColor = 255; //color (0-255) values to be set by cylcing touch switch, initially GOLD
  int GColor = 0 ;
  int BColor = 0 ;

  if (ledsOn) {
    if (showColor == 0) { // Alchemy Blue
      RColor = 50;
      GColor = 255;
      BColor = 255;
    }
    else if (showColor == 1) { // Tinker Green
      RColor = 0;
      GColor = 255;
      BColor = 40;
    }
  }
  else { // black off
    RColor = 0;
    GColor = 0;
    BColor = 0;
  }
  
  //sparkling
  int p = random(PIXEL_COUNT); //select a random pixel
  pixels.setPixelColor(p, RColor, GColor, BColor); //color value comes from cycling state of momentary switch
  pixels.show();

  //button check to cycle through color value sets
  bool newState = digitalRead(TOUCH_PIN); //Get the current button state
  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(TOUCH_PIN);

    if (newState == LOW) {

      ledsOn = true; // turn leds on

      pressTime = millis(); // record timestep when button was pressed

      showColor++;
      if (showColor > 1)
        showColor = 0;
    }
  }

  // Set the last button state to the old state.
  oldState = newState;

  // turn leds off if interval has passed
  if (((millis() - pressTime) > onTime) && ledsOn) {
    ledsOn = false;
  }
}

}

this will prevent weird behaviour if one would press the button while the leds are still on