Advanced on and off blinking patterns with Neopixel

Hello
I have seen brilliant code posted here:
https://forum.arduino.cc/t/random-blinking-without-delay-and-blinking-with-delay-in-1/522967/7?u=salacjus

It is posted by UKHeliBob

Here I present my failed attepmt to change it for my purpose:

#include <Adafruit_NeoPixel.h>

#define PIXEL_PIN    9  // Digital IO pin connected to the NeoPixels.
#define PIXEL_COUNT 12  // Number of NeoPixels

#define PIXEL_PIN_2    10  // Digital IO pin connected to the NeoPixels.
#define PIXEL_COUNT_2  3 // Number of NeoPixels

Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2(PIXEL_COUNT_2, PIXEL_PIN_2, NEO_GRB + NEO_KHZ800);

const long periods2[] = {100, 1000, 1000, 300, 100, 500, 1000, 0};
byte index2;
unsigned long startTime;
unsigned long currentTime;

 
 void setup()
 {
  strip2.begin(); // Initialize NeoPixel strip object (REQUIRED)
  strip2.show();  // Initialize all pixels to 'off'
 }

void loop()
{
currentTime = millis();
if (currentTime - startTime >= periods2[index2])
 {
   if (index2%2==0)
 {
strip2.setPixelColor(1, 255,   0,   0); 
 strip2.show(); 
}
 strip2.setPixelColor(1, 0,   0,   0); 
strip2.show(); 

index2 = ++index2 % 8;
startTime = currentTime;
 }
 }

Orginal code works fine with ordinary leds. Digital read and write funcions are obious for me. Somehow i dont know how to use them in neopixel strips.

Looks plausible. Can you run some Adafruit example code and get it to do anything? How are the strips powered?

I have no problem with neopixel liblary. Provided neopixel example codes work fine. I just cant use code above because I cant see any blinking. Maybe @UKHeliBob will give me some hint

Oh, I see. Put the bit that set pixel one to zero in an else clause. Right now it runs all the time.

THX @wildbill
the problem now is that second led on each strip is blinking but I have coded only stip2 to blink

Sounds like both strips are wired to the same signal pin.

 void setup()
 {
  strip.begin(); 
  strip.show();  
  strip2.begin(); 
  strip2.show();  
 }
void loop()
{
  currentTime = millis();
  if (currentTime - startTime >= periods2[index2])
  {
    if (index2%2==0)
    {
      strip2.setPixelColor(1, 255,   0,   0); 
    }

    else  // you seem to have forgotten this, without it you *always* turn the pixel off

    {
      strip2.setPixelColor(1, 0,   0,   0); 
    }

index2 = ++index2 % 8;
startTime = currentTime;
 }
 }

Why do you always set pixel 1?

I realy want to thank all of You. It works as I want it to. It wasnt wire problem. Adding proper else and setup commands for second stip solved the problem.

@GoForSmoke This code is a test code i will do diffrent blink patters on diffrent pixels. It will be for modeling purpose where I have to light up spaceship cockpit.

1 Like

I have written a small library for leds
https://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm

All the effects can be used with LEDs on discrete pins or you assign a pixel of the neopixel strip as "pin".

example to blink 3 pixels on the strip:

#include <Noiasca_led.h>               // download from: https://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm
#include <utility/Noiasca_neopixel.h>  // needed for Neopixel

#include <Adafruit_NeoPixel.h>         // use the Adafruit library for Neopixel
constexpr uint16_t pixelCount = 32;
constexpr byte pixelPin = 8;
Adafruit_NeoPixel strip(pixelCount, pixelPin, NEO_GRB + NEO_KHZ800);

BlinkPixel blinkPixelA(strip, 0);      // a blink LED on a Neopixel strip using pixel 0
BlinkPixel blinkPixelB(strip, 1);      // a blink LED on a Neopixel strip using pixel 1
BlinkPixel blinkPixelC(strip, 2);      // a blink LED on a Neopixel strip using pixel 2

void setup() {
  Serial.begin(115200);
  Serial.println(F("LED & Pixel Test"));
  strip.begin();
  strip.setBrightness(50);             // Set BRIGHTNESS to about 1/5 (max = 255)
  blinkPixelA.setOnInterval(250);      // set the on time of a pixel
  blinkPixelB.setOffInterval(250);     // set the off time of a pixel
  blinkPixelB.setOnColor(0xFF0000);    // set the on color of a pixel
  blinkPixelC.setOnColor(0x00FF00);
  blinkPixelC.setOffColor(0x000088);   // the "off" color can be different to black
}

void loop() {
  blinkPixelA.update();                // call .update() for your pixel object
  blinkPixelB.update();  
  blinkPixelC.update();
}

I have WS2812 led strips and WS2811 "tree lights"... 12mm dia diffuser bulbs with RGB led, the bulb lights up, solid any-color-you-want with about 75mm wires between each bulb. It's very easy to splice longer wire if lights need to be farther apart.

What they look like covering a floor. Looks like 5 50 led strings.

I use the FastLed library and IGNORE 99% of the features. I make the leds array, I fill it myself and call the myLeds.show() function, over and over.

I should have asked, cockpit of a model spaceship or full size simulator cockpit or movie set cockpit?

1/144 Milenium falcon My build documentation:

https://www.britmodeller.com/forums/index.php?/topic/235078308-1144-millenium-falcon-build-1-by-kp/

1 Like

You need smaller lights, have you looked at fiber optics?

yes i will use diffrent size fiber optics yet still i need to light them up with neopixels. i Have almost finished my testing circut soon I will post new images

I have realized that I have a problem with coding engine light sequence. My code needs to be "without using delay" and has low memory consumption.

for faiding a light i have found this code:

int periode = 5000;

 void setup()
 pinMode(6, OUTPUT);        // powering   red 3mm led diode                        [D],[PWM]

 void loop()
 value = 128+127*cos(2*PI/periode*current_TIME );
 analogWrite(6, value);  

It works greate. The problem is it makes full cos function from 1 to -1 and it means full fade in and fade out.

What I would like to have is:

  1. fade in for X millis from Y PWM value to Z PWM value
  2. fade in for X2 millis from Y2 PWM value to Z2 PWM value
  3. fade out for X3 millis from Y3 PWM value to Z3 PWM value
    ...

I know I should use some sort of arrays but I dont have enough knowlege how to make it work all together

const long PERIODS_PIN = {3000, 1000, 2000, 1500};  // the duration of each sequence
byte start_value        = {  0,  180, 1 80,   30};
byte end_value          = {180,  180,   30,  255};
byte INDEX; //this will allow me to move along arrays above

You send 3 bytes per led, you want to make bytes. 1 red 1 green 1 blue.
So you make a cos table, with 3 bytes for every fade value from fade low to fade high. At runtime you read em and feed em to the leds.

If you are using 1 color led(s) then 1 byte.

const long PERIODS_PIN[ 4 ] = {3000, 1000, 2000, 1500};  // the duration of each sequence
byte pinNum[ 4 ]             = ( ? }; 
byte start_value[  4 ]       = {  0,  180, 180,   30 };
byte end_value [ 4 ]         = { 180,  180,   30,  255 };
byte idx; //this will allow me to move along arrays above easy to type

I still dont know how to use mills to make it work on this simple 4 stage egazmple.
@noiasca can You show me how to write this test code on Your library?

in your first post you were talking about Neopixel, but now you want the fading effect on a PWM pin - is that correct?

furthermore I'm not sure what should happen after the last step? what should happen when the LED has reached 255 and/or the 1000ms are over?

For example I'm using the smoothLed:
The smoothLed takes for usual an on interval, an off interval (for dimming down) and a max brightness and doesn't need a time.

But if you need a precise time you could use a finite state machine, which switches over to the next state depending on millis:

#include <Noiasca_led.h>               // download library from https://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm

SmoothPin smoothLed {6};               // UNO PWM pins 3, 5, 6, 9, 10, 11

void doFSM()
{
  static byte state = 0;
  static uint32_t previousMillis = 0;
  uint32_t currentMillis = millis();
  switch (state)
  {
    case 0:           // fade up
      if (currentMillis - previousMillis > 3000)    // when n milliseconds are over
      {
        previousMillis = currentMillis;
        // change nothing on the LED itself - just change to next step/step1
        state++;
        Serial.print(F("new State=")); Serial.println(state);
      }
      break;
    case 1:           // do nothing for 1 s
      if (currentMillis - previousMillis > 1000)
      {
        previousMillis = currentMillis;
        // now the new limits for the next state:
        smoothLed.setOffInterval(5);     // you can modify the delay time for the smothing
        smoothLed.setMaxBrightness(30);  // you can limit the maximum brightness. Highest value on Arduino is 255. Default 255.
        state++;
        Serial.print(F("new State=")); Serial.println(state);
      }
      break;
    case 2:               // fade up full
      if (currentMillis - previousMillis > 2000)
      {
        previousMillis = currentMillis;
        // now the new limits for the next state:
        smoothLed.setOnInterval(10);     // you can modify the delay time for the smothing
        smoothLed.setMaxBrightness(255); // you can limit the maximum brightness. Highest value on Arduino is 255. Default 255.
        state++;
        Serial.print(F("new State=")); Serial.println(state);
      }
      break;
    case 3:
      if (currentMillis - previousMillis > 1500)
      {
        previousMillis = currentMillis;
        // now the new limits for the next state:
        smoothLed.setOnInterval(5);      // you can modify the delay time for the smothing
        smoothLed.setMaxBrightness(180); // you can limit the maximum brightness. Highest value on Arduino is 255. Default 255.
        state = 0;
        Serial.print(F("new State=")); Serial.println(state);
      }
      break;
  }
}

void setup() {
  Serial.begin(115200);
  smoothLed.begin();   // you have to call the .begin() method for the LED pair

  smoothLed.on();      // you can switch the LED on

  smoothLed.setOnInterval(5);     // you can modify the delay time for the smothing
  smoothLed.setOffInterval(5);     // you can modify the delay time for the smothing
  smoothLed.setMaxBrightness(240); // you can limit the maximum brightness. Highest value on Arduino is 255. Default 255.
}

void loop() {
  doFSM();
  smoothLed.update();   // you have to call update() for the LED
}