Using millis with neopixel

Hello everybody, I wanted to make this timer with Neopixels. The timer works by pressing a button that has to be kept pressed otherwise the timer should stop. The thing is that this is (this is probably obvious to you lol) that this is not achivable with the delay function as its a blocking function. So i wanted to switch to a millis function instead, but this way i can't make the timer work.

I only tried with the function called colorWipeWork which i pasted right here but below you can find the full code. If you can help me it would be awesome.

void colorWipeWork(uint32_t color, int wait) 
{
  
  for(int i=0; i<strip.numPixels(); i++) 
  { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    const long interval = 93750;
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > interval)
    {
      previousMillis == currentMillis;
    }                          
  }
}

but here you can finde the full code if you wish


#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> 
#endif


#define LED_PIN    2
#define Button 7
#define Buzzer 6
#define LED_COUNT 16

String start25 = "start";
long previousMillis = 0;

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(9600);
  pinMode(Button, INPUT);
  pinMode(Buzzer, OUTPUT);
    strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
    strip.show();            // Turn OFF all pixels ASAP
    strip.setBrightness(10); // Set BRIGHTNESS to about 1/5 (max = 255)
}

void loop() {
  int buttonState = 0;
  Serial.println("Please enter a command: ");
  buttonState = digitalRead(Button);
while(buttonState == HIGH)
  {
    Serial.println("25 min timer started");
  colorWipeWork(strip.Color(150,   0,   0), 100); // Work Red
  Serial.println("Timer finished");
        strip.clear(); 
             theaterChaseRainbow(1);
             delay(150);
             theaterChaseRainbow(1);
             theaterChaseRainbow(1);
             delay(150);
             theaterChaseRainbow(1);
             delay(100); // Rainbow-enhanced theaterChase variant
      strip.clear();         //   Set all pixels in RAM to 0 (off)

    colorWipePause(strip.Color(0,   100,   0), 100); // PauseGreen
    strip.clear();
  
  }
if (buttonState == LOW)
{
  strip.clear();
  ClearLEDS();
  }
}
  


void colorWipeWork(uint32_t color, int wait) 
{
  
  for(int i=0; i<strip.numPixels(); i++) 
  { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    const long interval = 93750;
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > interval)
    {
      previousMillis == currentMillis;
    }                          
  }
}

void colorWipePause(uint32_t color, int wait) 
{
  for(int i=0; i<strip.numPixels(); i++) 
  { 
    strip.setPixelColor(i, color);         
    strip.show();                          
    delay(150);                           
  }
}
void theaterChaseRainbow(int wait) 
{
  int firstPixelHue = 0;     
  for(int a=0; a<30; a++) 
  {  
    for(int b=0; b<3; b++) 
    { 
      strip.clear();         
      
      for(int c=b; c<strip.numPixels(); c += 3) 
      {
        
        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue));
        strip.setPixelColor(c, color); 
      strip.show();                
      delay(wait);                 
      firstPixelHue += 65536 / 90; 
      }
    }
  }
}

void ClearLEDS() {
  for (uint16_t i=0; i<LED_COUNT; i++) strip.setPixelColor(i,0);  
}




Hello giod2000

Post your sketch, well formated, with comments and in so called code tags "</>" and schematic to see how we can help.

ahah i was figuring out how to do it, now should be completed

Maybe using an interrupt on pin change is what you want? This guy does a great job explaining how this works...

very good idea to post the full code.
To learn about non-blocking timing read this tutorial

best regards Stefan

I want to ask:

it is your explicit wish that the user has to press down continiously the button for minutes ?

Is this a kind of

"how-much-endurance-do-you-have-in-holding-down-a-button-game" ?

or is your button not a button but some kind of input-signal that is created by another device or a switch?

I have two ideas to make your code repsonsive again all the time:

Idea 1: coding an interrupt where the interrupt-function (this is calles the Interrupt Service Routine in short ISR)
is setting a flag-variable

adding conditional abortion to each and every for-loop you have in your code

idea 2: using each and everywhere in your code non-blocking timing.
This means rewrite your code in a way that state-machines are used.
The state-machines replace each and evey for-loop / while-loop

If you keep a single for-loop or while-loop this loop is again blocking

This is an interesting application. You are using 6 for-loops where 3 for-loops were direct nested and two are indirect nested (= a function "A" calls a function "B" and inside function "B" is a for-loop)

replacing 6 for-loops with state-machines will change a lot of things in your code. For me this is an interesting challenge. I'm working on the rewrite.

I estimate if I just post the non-blocking rewritten code you will have a lot of questions how this code-version works.

Well your all in all functionality is pretty complex. And adding to this functionality beeing completely non-blocking which is a must if you want the code to be responsive to a button-press all the time

Is like trying to practice backflips with a BMX-bike in a halfpipe from a skill-level
with which you are only able to do small jumps over a small ramp.
You don't switch to backflips immidiately. You practise some trainings that require a skill-level lower than backflip-saltos.

Somehow I got the feeling that this can be done in a more elegant way than I rewrite the code. After posting my code-version it will be very interesting to see
if somebody can come up with a more elegant solution.

best regards Stefan

thank you very much this article is very useful

basically the code is about a charger that knows when the phone is charging and as soon as it start charing it should start a timer that monitors how much time your phone has been there

So please describe in normal words what kind of functionality ypou want to have.

You lay down your phone on the charger and the weight of the phone presses the button?

As soon as the button is pressed a timer shall start to count up?
And displaying the charging time?
On what kind of display?

How is the lightshow of your neopixels related to the timer?

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