Making Navigation Chart with Neopixel LEDs

Hi,
I've recently started working on putting 12 neopixels behind a navigation chart used in sailing.
I am using a ESP32 Huzzah Feather board and Arduino IDE to code the lights. Each light has a different flashing pattern, and some are red, some green, and some white.
(Ex. one light will flash red every 4s, another white every 10s)
I have the chart built now, and I just need to code the lights to have them all flashing with the right period. This is my first time coding something like this, and I am not sure how I can get each neopixel to be blinking simultaneously.
There is an older thread on this, and a user (@marco_c ) shared some code that may work,

However, I am unsure how to make it work with neopixels. Can anyone steer me in the right direction? I'm looking forward to making this work. Thanks!

To begin with, read and practise the advise in this link: How to get the best out of this forum - Using Arduino / Project Guidance - Arduino Forum

Useful topics are "Do several things at the same time", "Blink without delay.".

1 Like

Look at the MultiBlink5_Neo sketch for neopixels. MajicDesigns/MultiBlink: Blink LEDs in different configurable patterns (github.com)

1 Like

Thank you for sharing that, I had just realized you had a more recent version for neopixels. I will look into using that.

as alternative:

I have a small "Tool Kit" which contains several LED effects. The effects can be used also for Neopixels.

https://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm

For a pixel on the strip you just handover the object name of the strip and the pixel you would like to effect.

A short demo with 3 pixels on one strip looks like:

/*
   Blink Neopixel - Marine
   blinks 3 pixel on a strip

   by noiasca
   
   2023-02-20 https://forum.arduino.cc/t/making-navigation-chart-with-neopixel-leds/1092324
 */
#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 = 12;
constexpr byte pixelPin = 8;
Adafruit_NeoPixel strip(pixelCount, pixelPin, NEO_GRB + NEO_KHZ800);

BlinkPixel pixelA(strip, 0);      // a blink LED on a Neopixel strip using pixel 0
BlinkPixel pixelB(strip, 1);      // a blink LED on a Neopixel strip using pixel 1
RhythmPixel pixelC(strip, 2);     // a rhythm LED on a Neopixel strip using pixel 2

void setup() {
  Serial.begin(115200);
  Serial.println(F("LED & Pixel - Marine"));
  strip.begin();
  strip.setBrightness(50);             // Set BRIGHTNESS to about 1/5 (max = 255)
  
  pixelA.setOnInterval(500);      // set the on time of a pixel
  pixelA.setOffInterval(4000);    // set the off time of a pixel
  pixelA.setOnColor(0xFF0000);    // set the on color of a pixel

  pixelB.setOnInterval(500);      // set the on time of a pixel
  pixelB.setOffInterval(10000);   // set the off time of a pixel
  pixelB.setOnColor(0xFFFFFF);    // set the on color of a pixel
  pixelB.setOffColor(0x000080);   // the off color could be different to black ... here a blue
  
  pixelC.setOnColor(0x00FF00);
  pixelC.setInterval(25, 25, 25, 25, 25, 375);         // a sequence of ON/OFF... up to 4 pairs. The example shows a HELLA 3 (ambulance warning light)
  
}

void loop() {
  pixelA.update();                // call .update() for your pixel object
  pixelB.update();  
  pixelC.update();
}
1 Like

Thank you for sharing that, I think it will work!
multiple lights are on the same pattern, however, I don't want them to all be synced. How can I delay the start of some of the sequences so they are not all flashing at the same time? I've tried adding a delay in the setup function but I haven't been able to make it work.

i think the easiest way is to handover a slightly "manipulated" timestamp.
3 blink LEDs with the same interval, but now they have different time to deal with.

#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 = 12;
constexpr byte pixelPin = 8;
Adafruit_NeoPixel strip(pixelCount, pixelPin, NEO_GRB + NEO_KHZ800);

BlinkPixel pixelA(strip, 0);      // a blink LED on a Neopixel strip using pixel 0
BlinkPixel pixelB(strip, 1);      // a blink LED on a Neopixel strip using pixel 1
BlinkPixel pixelC(strip, 2);      // a blink LED on a Neopixel strip using pixel 2

void setup() {
  Serial.begin(115200);
  Serial.println(F("LED & Pixel - Marine"));
  strip.begin();
  strip.setBrightness(50);             // Set BRIGHTNESS to about 1/5 (max = 255)

  pixelA.setOnInterval(500);      // set the on time of a pixel
  pixelA.setOffInterval(2000);     // set the off time of a pixel
  pixelA.setOnColor(0xFF0000);    // set the on color of a pixel

  pixelB.setOnInterval(500);      // set the on time of a pixel
  pixelB.setOffInterval(2000);   // set the off time of a pixel
  pixelB.setOnColor(0xFFFFFF);    // set the on color of a pixel

  pixelC.setOnColor(0x00FF00);
  pixelC.setOnInterval(500);      // set the on time of a pixel
  pixelC.setOffInterval(2000);     // set the off time of a pixel
}

void loop() {
  uint32_t currentMillis = millis();
  pixelA.update(currentMillis);                // call .update() for your pixel object
  pixelB.update(currentMillis + 300);
  pixelC.update(currentMillis + 900);
}
1 Like

An alternative,
the library also contains a very simple timer - called LittleTimer.

So you could start with some LEDs switched .off(), and switch them .on() later during runtime.
Just keep in mind that the timer interval has to be larger than the .setOffInterval() of that LED, otherwise the timer would start the blinking during the off phase and the LEDs are in sync again.
If you keep the the timer large enough - it will be ok.

But so it is working:

#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 <Noiasca_timer.h>    // also part of the Noiasca Tool Kit

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

BlinkPixel pixelA(strip, 0);      // a blink LED on a Neopixel strip using pixel 0
BlinkPixel pixelB(strip, 1);      // a blink LED on a Neopixel strip using pixel 1
BlinkPixel pixelC(strip, 2);      // a blink LED on a Neopixel strip using pixel 2

// here you create your timer object
// you need two parameters:
// the first parameter is the interval
// the optional second parameter is a limit how often you want that trigger
//               interval limit
LittleTimer timerB {2300,   1};
LittleTimer timerC {2900,   1};

void setup() {
  Serial.begin(115200);
  Serial.println(F("LED & Pixel - Marine"));
  strip.begin();
  strip.setBrightness(50);             // Set BRIGHTNESS to about 1/5 (max = 255)

  pixelA.setOnInterval(500);      // set the on time of a pixel
  pixelA.setOffInterval(2000);     // set the off time of a pixel
  pixelA.setOnColor(0xFF0000);    // set the on color of a pixel

  pixelB.setOnInterval(500);      // set the on time of a pixel
  pixelB.setOffInterval(2000);   // set the off time of a pixel
  pixelB.setOnColor(0xFFFFFF);    // set the on color of a pixel
  pixelB.off();

  pixelC.setOnColor(0x00FF00);
  pixelC.setOnInterval(500);      // set the on time of a pixel
  pixelC.setOffInterval(2000);     // set the off time of a pixel
  pixelC.off();
}

void loop() {
  pixelA.update();                // call .update() for your pixel object
  pixelB.update();
  pixelC.update();

  if (timerB.hasEnded()) {             // fires one time after the timer has ended
    Serial.println(F("timerB has ended"));
    pixelB.on();
  }
  
  if (timerC.hasEnded()) {             // fires one time after the timer has ended
    Serial.println(F("timerC has ended"));
    pixelC.on();
  }
}

What's next? do you need to switch on / off signals? There is a simple button class also ... just in case you were asking :wink:

1 Like

Thanks again, using the adjusted timestamp worked great! For now, I think I am all set, I just need to add a physical switch to turn the board on and off.

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