Trying to get certain neopixels to activate on a timer

pannekoek141:
Sweet! its working, only need to figure out why the color isnt changing after 540ul. working on that right now

I introduced a small bug when I changed for better color names

  if ((currentColor != STARTCOLOR) && (millis() >= timeColorChange)) {

it should have been

  if ((currentColor == STARTCOLOR) && (millis() >= timeColorChange)) {

or

  if ((currentColor != ENDCOLOR) && (millis() >= timeColorChange)) {

--> fixed it above in the code

Very very cool!! It actually works now, and it changes the color aswell. Now i've got the rest of the evening to trigger the pump to turn on/off on the 54000ul mark. I should be able to add that to the code, and i think i can do that with a simple digitalwrite, right?

Is there any place i could give you something? you've helped me so damn much, hehe

pannekoek141:
Very very cool!! It actually works now, and it changes the color as well. Now i've got the rest of the evening to trigger the pump to turn on/off on the 54000ul mark. I should be able to add that to the code, and i think i can do that with a simple digitalwrite, right?

Yes if your pump is driven through a mosfet or some sort of relay, just triggering the pin controlling the relay would do. A pump is an inductive load, so make sure there is free wheel/flyback diode to catch the spike when you'll switch power off.

pannekoek141:
Is there any place i could give you something? you've helped me so damn much, hehe

Appreciate the ask. I'm good - in my years of "payback time". I was fortunate to study and learn, if you want to do something good, feel free to give whatever feels appropriate to a charity helping kids go to school.

Alright that's cool, i'll look for a charity that makes sure all the funds go to the kids because i hate when big corporations take a 40% cut of the donation.

I also needed a third color change which i successfully added. Is there a simple way to make the neopixel strip blink after 99000 ul? No worries about the pump i think, it's powered via a 12v battery and the relais only switches the + on or off.

to blink you just need to add a constant at the top of the code:const unsigned long blinkPeriod = 1000ul; // 1 second

and a else section to the part when we test if all LEDs are on

  if (nextPixel < NUMPIXELS) {
    if (millis() - lastTick >= period) {
      lightingUpTo(nextPixel, currentColor);
      nextPixel++;
      lastTick += period;
    }
  } else {
    // all pixels are lit, we blink
    if (millis() - lastTick >= blinkPeriod) {
      static boolean turnStripOff = true;
      if (turnStripOff) {
        pixels.clear(); // all black
      } else {
        lightingUpTo(NUMPIXELS-1, currentColor);
      }
      turnStripOff = !turnStripOff; // for next time
      lastTick += blinkPeriod;
    }

that might actually work :slight_smile:

Hmmm to bad that didn't work, that's not to much of an issue tho.

I tried to add the pump by adding this function:

void pump() {
 digitalWrite(D5, LOW); // Relais off
 delay(54000); // pump is on until 54000
 digitalWrite(D5, HIGH); // Relais on
 delay(1000); // pump is off for a second
 digitalWrite(D5, LOW); // Relais off
 delay(56000); // pump starts again

}

to the loop by saying "pump();"
but that seems to break it

Can i use the const. also for the pump?

Simply adding digitalwrite into the existing if statement didn't work either :stuck_out_tongue:

pannekoek141:
Hmmm to bad that didn't work, that's not to much of an issue tho.

Yes - actually I probably need a   pixels.show();after the call to clear(); otherwise you won't see them becoming black :slight_smile:

#include <Adafruit_NeoPixel.h>
const byte ledPin = D3;
const uint16_t NUMPIXELS = 11;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, ledPin, NEO_GRB + NEO_KHZ800);
uint16_t nextPixel;

uint32_t currentColor = 0;
uint32_t STARTCOLOR;
uint32_t ENDCOLOR;


const unsigned long period = 90ul; // should be 9000ul for 9 seconds, here shorter for testing without waiting :)
const unsigned long timeColorChange = 540ul; // should be 54000ul for 54 seconds, here shorter for testing without waiting :)
const unsigned long blinkPeriod = 1000ul; // 1 second


unsigned long lastTick;



void lightingUpTo(uint16_t n, uint32_t stripColor)
{
  Serial.print("Lighting LED");
  for (uint16_t i = 0; i <= n; i++) {
    Serial.print(" #");  Serial.print(i);
    pixels.setPixelColor(i, stripColor);
  }
  Serial.print(" in color 0x");  Serial.println(stripColor, HEX);
  pixels.show();
}


void setup() {
  Serial.begin(115200);

  pixels.begin(); // This initializes the NeoPixel library.
  pixels.setBrightness(127); // half max brightness
  pixels.clear(); // all black
  pixels.show();

  nextPixel = 0;
  lastTick = millis();
  STARTCOLOR = pixels.Color(255, 0, 0); // RED
  ENDCOLOR = pixels.Color(0, 0, 255); // BLUE
  currentColor = STARTCOLOR;
}

void loop() {

  if ((currentColor == STARTCOLOR) && (millis() >= timeColorChange)) {
    currentColor = ENDCOLOR;
  }


  if (nextPixel < NUMPIXELS) {
    if (millis() - lastTick >= period) {
      lightingUpTo(nextPixel, currentColor);
      nextPixel++;
      lastTick += period;
    }
  } else {
    // all pixels are lit, we blink
    if (millis() - lastTick >= blinkPeriod) {
      static boolean turnStripOff = true;
      if (turnStripOff) {
        Serial.println(F("STRIP OFF"));
        pixels.clear(); // all black
        pixels.show();
      } else {
        Serial.println(F("STRIP ON"));
        lightingUpTo(NUMPIXELS - 1, currentColor);
      }
      turnStripOff = !turnStripOff; // for next time
      lastTick += blinkPeriod;
    }
  }
}

otherwise to your question - you can't use delay() anywhere or the code gets stuck there ....

you need the same millis() technique.

Now it says: blinkPeriod was not declared in this scope.

Here's the code im working with right now, i think i can get the pump to turn on and off in the used if functions those are also used for the lights

#include <Adafruit_NeoPixel.h>
const byte ledPin = D3;
const uint16_t NUMPIXELS = 11;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, ledPin, NEO_GRB + NEO_KHZ800);
uint16_t nextPixel;

uint32_t currentColor = 0;
uint32_t STARTCOLOR;
uint32_t SECONDCOLOR;
uint32_t THIRDCOLOR;



const unsigned long period = 900ul; // Elke led gaat aan om de 9 seconden
const unsigned long timeColorChange1 = 5400ul; // op de 54 seconden verandert de kleur van de ledstrip
const unsigned long timeColorChange2 = 8100ul; // op 81 seconden verandert de kleur nogmaals


unsigned long lastTick;



void lightingUpTo(uint16_t n, uint32_t stripColor)
{
  Serial.print("Lighting LED");
  for (uint16_t i = 0; i <= n; i++) {
    Serial.print(" #");  Serial.print(i);
    pixels.setPixelColor(i, stripColor);
  }
  Serial.print(" in color 0x");  Serial.println(stripColor, HEX);
  pixels.show();
}


void setup() {
  pinMode(D5, OUTPUT);
  Serial.begin(115200);
  digitalWrite(D5, HIGH); // Relais UIT
  

  pixels.begin(); // This initializes the NeoPixel library.
  pixels.setBrightness(127); // half max brightness
  pixels.clear(); // all black

  nextPixel = 0;
  lastTick = millis();
  STARTCOLOR = pixels.Color(0, 255, 0); // GREEN
  SECONDCOLOR = pixels.Color(255,140,0); // ORANGE
  THIRDCOLOR = pixels.Color(255,0,0); // RED
  currentColor = STARTCOLOR;
  
}


void loop() {

  

   if ((currentColor != SECONDCOLOR) && (millis() >= timeColorChange1)) {
    currentColor = SECONDCOLOR;
    digitalWrite(D5, LOW); // Relais UIT
    delay(1000); // wacht een seconde
    digitalWrite(D5, HIGH); // Relais UIT
  }

  if ((currentColor != THIRDCOLOR) && (millis() >= timeColorChange2)) {
    currentColor = THIRDCOLOR;
    digitalWrite(D5, LOW); // Relais UIT
    delay(1000); // wacht een seconde
    digitalWrite(D5, HIGH); // Relais AAN
  }


  if (nextPixel < NUMPIXELS) {
    if (millis() - lastTick >= period) {
      lightingUpTo(nextPixel, currentColor);
      nextPixel++;
      lastTick += period;
    }
  } else {
    // all pixels are lit, we blink
    if (millis() - lastTick >= blinkPeriod) {
      static boolean turnStripOff = true;
      if (turnStripOff) {
        Serial.println(F("STRIP OFF"));
        pixels.clear(); // all black
        pixels.show();
      } else {
        Serial.println(F("STRIP ON"));
        lightingUpTo(NUMPIXELS - 1, currentColor);
      }
      turnStripOff = !turnStripOff; // for next time
      lastTick += blinkPeriod;
    }
  }

Sorry about the weird language in the comments, thats dutch

this is your code a bit cleaned up (don't use D5 directly in code, give it a name :slight_smile: )

#include <Adafruit_NeoPixel.h>

const byte ledPin = D3; // to command the LED strip
const byte relayPin = D5; // to command the relay

const uint16_t NUMPIXELS = 11;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, ledPin, NEO_GRB + NEO_KHZ800);
uint16_t nextPixel;

uint32_t currentColor = 0;
uint32_t STARTCOLOR;
uint32_t SECONDCOLOR;
uint32_t THIRDCOLOR;

const unsigned long period = 900ul; // Elke led gaat aan om de 9 seconden
const unsigned long timeColorChange1 = 5400ul; // op de 54 seconden verandert de kleur van de ledstrip
const unsigned long timeColorChange2 = 8100ul; // op 81 seconden verandert de kleur nogmaals

const unsigned long blinkPeriod = 1000ul; // 1 second

unsigned long lastTick;



void lightingUpTo(uint16_t n, uint32_t stripColor)
{
  Serial.print("Lighting LED");
  for (uint16_t i = 0; i <= n; i++) {
    Serial.print(" #");  Serial.print(i);
    pixels.setPixelColor(i, stripColor);
  }
  Serial.print(" in color 0x");  Serial.println(stripColor, HEX);
  pixels.show();
}


void setup() {
  pinMode(relayPin, OUTPUT);
  Serial.begin(115200);
  digitalWrite(relayPin, HIGH); // Relais UIT


  pixels.begin(); // This initializes the NeoPixel library.
  pixels.setBrightness(127); // half max brightness
  pixels.clear(); // all black
  pixels.show();
  nextPixel = 0;
  lastTick = millis();
  STARTCOLOR = pixels.Color(0, 255, 0); // GREEN
  SECONDCOLOR = pixels.Color(255, 140, 0); // ORANGE
  THIRDCOLOR = pixels.Color(255, 0, 0); // RED
  currentColor = STARTCOLOR;

}


void loop() {

  if ((currentColor != SECONDCOLOR) && (millis() >= timeColorChange1)) {
    currentColor = SECONDCOLOR;
    digitalWrite(relayPin, LOW); // Relais UIT
    delay(1000); // wacht een seconde
    digitalWrite(relayPin, HIGH); // Relais UIT
  }

  if ((currentColor != THIRDCOLOR) && (millis() >= timeColorChange2)) {
    currentColor = THIRDCOLOR;
    digitalWrite(relayPin, LOW); // Relais UIT
    delay(1000); // wacht een seconde
    digitalWrite(relayPin, HIGH); // Relais AAN
  }


  if (nextPixel < NUMPIXELS) {
    if (millis() - lastTick >= period) {
      lightingUpTo(nextPixel, currentColor);
      nextPixel++;
      lastTick += period;
    }
  } else {
    // all pixels are lit, we blink
    if (millis() - lastTick >= blinkPeriod) {
      static boolean turnStripOff = true;
      if (turnStripOff) {
        Serial.println(F("STRIP OFF"));
        pixels.clear(); // all black
        pixels.show();
      } else {
        Serial.println(F("STRIP ON"));
        lightingUpTo(NUMPIXELS - 1, currentColor);
      }
      turnStripOff = !turnStripOff; // for next time
      lastTick += blinkPeriod;
    }
  }

}

the challenge with this approach is that

    digitalWrite(relayPin, LOW); // Relais UIT
    delay(1000); // wacht een seconde
    digitalWrite(relayPin, HIGH); // Relais UIT

will only get executed once when you change the color. so you are touching the relay only for 1 second. is that what you want to do?

instead of using the same lastTick for everything, you might want to have one for the LED and one for the relay, each with their own logic for time management

Yup, That's what i'm trying to do. it's basically a hint like "you're showering quite long now"

And after that second hint when the color changes to red its more like "get out of the shower, NOW!"
:smiley: :smiley:

Thanks for the cleaned up code

pannekoek141:
Yup, That's what i'm trying to do. it's basically a hint like "you're showering quite long now"

And after that second hint when the color changes to red its more like "get out of the shower, NOW!"
:smiley: :smiley:

Thanks for the cleaned up code

OK so you stop the water for 1 second as a signal - good idea

does it blink now?

Yup, Works as intended 8)

I'm really happy with you're help and obliviously wouldn't have been able to do it without your help. I'll upload a video in a few minutes, i'll post it here's so you can see the end result