NeoPixel Ring - Phase shift

Zápisník experimentátora

Hierarchy: WS2812

In the previous article, we programmed the class Rotator and now we will use it to create an interesting animation. We will use 3x NeoPixel Ring and with the help of a phase shift we will create an effect in which three glowing dots with a colored tail will seem to move against each other. It's just an illusion, all three points are moving in the same direction.


The illusion is created using three NeoPixel Rings. The rings are attached to the foam brick with pins. In the picture they can be seen as two small metal heads, which are located in places where there is a miniature capacitor on the rest of the ring. The rings are as close to each other as possible. Each ring contains 24 LEDs. If we start the animation on LED 1 on the first ring and start on LED 12 on the second, the two points will be relative to each other at the opposite end of the ring. Although both move clockwise, the first appears to move to the right and the second appears to move to the left. After passing the twelfth position, the direction seemingly reverses and they move against each other again.

If we use three rings for the animation, the resulting effect will be more pronounced. The third ring animates in exactly the same way as the first ring. To enhance the overall impression, each ring has a different color.


In order to create an illusion, we need three rings (ring1, ring2 and ring3) and each ring is located on a separate pine (6, 7, 8). We described the class Rotator in a previous article. We need three objects (rt1, rt2 and rt3) of the class Rotator. Each object has a set phase shift (second parameter), hue (third parameter) and saturation (fourth parameter).

The whole animation is created in the loop function, in which we regularly call the function Step for each of the three objects. Simple code that creates an impressive animation.

#include <Adafruit_NeoPixel.h>

// led count
#define CNT 24
// max Hue
#define MAXHUE 65535

Adafruit_NeoPixel ring1(CNT, 6, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel ring2(CNT, 7, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel ring3(CNT, 8, NEO_GRB + NEO_KHZ800);

class Rotator
    Adafruit_NeoPixel *strip;
    int position;
    uint16_t hue;
    uint8_t saturation;

    Rotator(Adafruit_NeoPixel *npx, int pos = 0, uint16_t h = 0, uint8_t sat = 255);
    void Step();

Rotator::Rotator(Adafruit_NeoPixel *npx, int pos, uint16_t h, uint8_t sat)
  : strip(npx), position(pos), hue(h), saturation(sat)

void Rotator::Step()
  // hue - 0-65535
  // saturation - 0-255
  // value - 0-255
  for (int i = 0; i < CNT; i++)
      (i + position) % CNT,
      strip->ColorHSV(hue, saturation, strip->gamma8(i * (255 / CNT))));
  position %= CNT;

Rotator rt1(&ring1, 0, 0, 255); // red
Rotator rt2(&ring2, 12, 0, 200); // pink
Rotator rt3(&ring3, 0, 40000L, 200); // lightblue

void setup() {

void loop() {

Source code

The source code is located on the GitHub server.