millis() function does not work properly.

Hello, I’m new to this forum and I come here because I’ve got a problem using millis() in my code.

Recently I’ve started a project including 80 ws2812b leds, and 3 ttp223 touch sensors. What I want to achieve is when I touch the first sensor, the leds turn on and execute the first effect I made. When I press the second sensor, the brightness should change, and when I press the third sensor, the next effect should be executed. I already made the code and I thought it worked, because when I tested it with just simple colors instead of effects, everything worked fine. When I changed the code for simple colors to the code I made including millis(), the effect acted weird. When I upload only the effect code to the arduino, it works completely fine, but when I upload the complete code with the effects, it doens’t work the same. The effect seems to slow down and does not work smootly.

I’m guessing it has something to do with multiple millis(), because independently the effects act fine.

I spent a lot of time trying to figure it out, but I’m stuck. It would be great if you guys could help me! I’m pretty new to coding, so I’m sorry if the code is messy.

Here is the code:

#include <Adafruit_NeoPixel.h>

int LEDPIN = 6;
int NUMPIXELS = 80;

int j;
int k;
int m = 20;

// Effect3 variabelen
int t = 0;

int a = 81;
int b = 239;
int c = 165;

int d = 108;
int e = 89;
int f = 235;
// Effect3 variabelen

unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
unsigned long previousMillis3 = 0;

const long interval1 = 50;
const long interval2 = 20;
const long interval3 = 5;

long firstPixelHue = 0;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  Serial.begin(9600);

  pixels.begin();
  pixels.show();
//  pixels.setBrightness(150);  
}

void PixelsUit() {
  for(int i = 0; i < NUMPIXELS; i++){
    pixels.setPixelColor(i,0,0,0);
    pixels.show();
    pixels.clear();
  }
}

void Effect1() { //effect: Random
    pixels.setPixelColor(random(NUMPIXELS),random(0,255),random(0,255),random(0,255));
    pixels.show();
}

void Effect2() { //effect: Ronddraaiende regenboog
  firstPixelHue=firstPixelHue+=256;
  if(firstPixelHue < 65536) {
    for(int i=0; i<pixels.numPixels(); i++) { // For each pixel in strip...
      int pixelHue = firstPixelHue + (i * 65536L / pixels.numPixels());
      pixels.setPixelColor(i, pixels.gamma32(pixels.ColorHSV(pixelHue)));
    }
    pixels.show(); // Update strip with new contents
  } else {
    firstPixelHue = 0;
  }
}

void Effect3() { //effect: Twee kleuren om en om
  if(t==0){
    if (a<=108) {
      a=a+1;
    }
  
    if (b>=89) {
      b=b-1;
      if (b==89){
        t=1; //deze if statement doen bij de if statement die het langste duurt, die het vaakst +1 moet doen
      }
    }  
  
    if (c<=235) {
      c=c+1;
    }

    if (d>=81) {
      d=d-1;
    }
  
    if (e<=239) {
      e=e+1;
    }  
  
    if (f>=165) {
      f=f-1;
    }

    for(int i=0; i<NUMPIXELS; i=i+2){
      pixels.setPixelColor(i,a,b,c);
      pixels.setPixelColor(i+1,d,e,f);
      }
    pixels.show();

  
  } else if (t==1) {
    if (a>=81) {
      a=a-1;
    }
  
    if (b<=239) {
      b=b+1;
    }  
  
    if (c>=165) {
      c=c-1;
    }

    if (d<=108) {
      d=d+1;
    }
  
    if (e>=89) {
      e=e-1;
      if (e==89) { 
        t=0; //deze if statement doen bij de if statement die het langste duurt, die het vaakst +1 moet doen
      }
    }  
  
    if (f<=235) {
      f=f+1;
    }

    for(int j=0; j<NUMPIXELS; j=j+2){
      pixels.setPixelColor(j,a,b,c);
      pixels.setPixelColor(j+1,d,e,f);
    }
    pixels.show();
  }
}

void Effect4() {
  for(int i = 0; i < NUMPIXELS; i++){
    pixels.setPixelColor(i,150,0,0);
    pixels.show();
  }
}

void brightness(){
  pixels.setBrightness(m); 
  if (digitalRead(4) == HIGH) {
    m=m+5;
    delay(20);
  } else {
    m=m;
  }
  if (m==120) {
    m=20;
  }  
}

void onoff(){
  if (digitalRead(3) == HIGH){
    j=j+1;
    Serial.println("Aangeraakt");
    Serial.println(j);
    delay(200);
  } else {
    Serial.println("Niet Aangeraakt");
    Serial.println(j);
    j=j;
    }
    
  if (j==4){
    j=0;
  }

  if (j==0){
    unsigned long currentMillis1 = millis();
    if(currentMillis1-previousMillis1>=interval1){
      previousMillis1 = currentMillis1;
      Effect1(); //effect: Random
    }
    
  } else if (j==1) {
    unsigned long currentMillis2 = millis();
    if(currentMillis2-previousMillis2>=interval2){
      previousMillis2 = currentMillis2;
    Effect2(); //effect: Ronddraaiende regenboog
    }
    
  } else if (j==2) {
    unsigned long currentMillis3 = millis();
    if(currentMillis3-previousMillis3>=interval3){
      previousMillis3 = currentMillis3;
      Effect3(); //effect: Twee kleuren om en om
    }

  } else if (j==3) {
    Effect4();
  }
}

void loop() {
  brightness();
  
  if (digitalRead(5) == HIGH) {
    k=k+1;
    Serial.println("Aangeraakt");
    Serial.println(k);
    delay(20);
  } else {
    Serial.println("Niet Aangeraakt");
    Serial.println(k);
    k=k;
  }
  
  if (k==0) {
    PixelsUit();
  } else if (k==2) {
    k=0;
  } else if (k==1) {
    onoff();
  }
}

A few things:

  1. These should be unsigned long:
const long interval1 = 50;
const long interval2 = 20;
const long interval3 = 5;
  1. I note that if digitalRead(3) == HIGH you delay for 200ms. All of your intervals are 50 ms or less

  2. For all of your sensors you are checking to see if the state is HIGH and if so you increment a variable. You wouldn't have to hold down a sensor very long for it to exceed the maximum value you want. For example, this code sequence:

  if (digitalRead(5) == HIGH) {
    k = k + 1;
    Serial.println("Aangeraakt");
    Serial.println(k);
    delay(20);
  } else {
    Serial.println("Niet Aangeraakt");
    Serial.println(k);
    k = k;
  }

  if (k == 0) {
    PixelsUit();
  } else if (k == 2) {
    k = 0;
  } else if (k == 1) {
    onoff();
  }

If k ever exceeds 2 you will be in a state where you never reset k to 0!

This is repeated for other sensors.

  1. Why do you have the following code in some places?
    k = k;

In general I suspect you need to check whether the sensors have CHANGED state rather than their actual state. In other words, has the sensor BEEN touched rather than IS the sensor touched.

You should not have currentMIlis1, currentMillis2 and currentMillis3. Just use a single currentMIllis variable and set it equal to millis() as the first thing in loop()

Think about it - you don't need 3 clocks in your kitchen to time the cooking of your dinner.

...R

millis() works just fine. You call the millis() function and you get the number of milliseconds since the processor started. Works every time.

Unless you are using neopixels, which shuts off interrupts whilst refreshing the string.

a7

alto777:
Unless you are using neopixels, which shuts off interrupts whilst refreshing the string.

Does that take more than 1 millisec?

…R

Yes, a full string of 256 WS2812B can take almost 8ms to update.

Datasheet says
"When the refresh rate is 30fps, cascade number are not less than1024 points."

30 fps = new data every 33.3mS.
256 = 1/4 of 1024
So 8.33mS for 256.

"Send data at speeds of 800Kbps." I wonder if the libraries support that?

What does NEO_KHZ800 mean then?

Neopixels have to be fed a steady stream of bits with some challenging timing constraints, the specs and a glance at one library sauce code suggests that it is doing it at that rate.

SPI smart pixels allow for a greater flexibility and of course easier code.

And no impact on millis();

a7

Check out my tutorial on How to Code Timers and Delays in Arduino
it uses a millisDelay class to handle the individual timers

dannyzwart:
Hello, I'm new to this forum and I come here because I've got a problem using millis() in my code.

I must always smile, when newbies got problems using millis() in their code and write as title:
"millis() function does not work properly."

It is like the guy hearing the warning on the radio "Reckless driver on the wrong side of the highway"

One reckless driver on the wrong side? I see hundreds!
:stuck_out_tongue:

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