NeoPixel Ring - Counterclockwise rotation

Zápisník experimentátora

Hierarchy: WS2812

Today, we're going to address a question from a subscriber to my YouTube channel. The colors rotate clockwise. Could this rotation be turned counterclockwise? At first glance, this seems simple, and my first reaction was to change the two lines in the source code. But it didn't work. So I looked at the problem and adjusted the algorithm so that it rotates in the opposite direction.

Example

The change is in a single line. If the macro CCW is enabled, the ring rotates counterclockwise. But I will not write here what a genius programmer I am and how I wrote the right code on the first try. I didn't write it on the first try and there were many more. I used the trial-and-error method until I succeeded. It shouldn't be done that way, but when you think it's easy, then things like that happen.

#include <Adafruit_NeoPixel.h>
#include "hsv.h"

// data pin
#define PIN 6
// led count
#define CNT 24
// max Hue
#define MAXHUE 256*6

int position = 0;

#define CCW

Adafruit_NeoPixel strip = Adafruit_NeoPixel(CNT, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
}

void loop() {
  // hue - red
  // saturation - max
  // value - 0-255
  for (int i = 0; i < CNT; i++) {
#ifdef CCW
    strip.setPixelColor(((CNT + i) - position) % CNT, getPixelColorHsv(i, 0, 255, strip.gamma8((CNT - i) * (255 / CNT))));
#else
    strip.setPixelColor((i + position) % CNT, getPixelColorHsv(i, 0, 255, strip.gamma8(i * (255 / CNT))));
#endif
  }
  strip.show();
  position++;
  position %= CNT;
  delay(50);
}

An accidental attempt leads to the right result

It is clear from the previous text that even random attempts can sometimes reach your target. But let's look at the values of the variables to see how the program reworks to the result. I'll modify the source code a bit to print the values in some variables on the serial port.

And from the listings on the serial port, it is clear that this is not completely perfect. In particular, the brightness setting in the variable value should be better stretched between 0 - 255. But when it moves, the human eye does not notice small imperfections and the illusion is perfect. Study the individual statements and try to guess how the illusion of a moving ring is created. On the NeoPixel Ring, the individual LEDs are placed clockwise and start where the data wires are connected.

#include <Adafruit_NeoPixel.h>
#include "hsv.h"

// data pin
#define PIN 6
// led count
#define CNT 24
// max Hue
#define MAXHUE 256*6

int position = 0;
char output[128];

//#define CCW

Adafruit_NeoPixel strip = Adafruit_NeoPixel(CNT, PIN, NEO_GRB + NEO_KHZ800);

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

void loop() {
  // hue - red
  // saturation - max
  // value - 0-255
  sprintf(output, "position: %d", position);
  Serial.println(output);

  for (int i = 0; i < CNT; i++) {
#ifdef CCW
    int pos = ((CNT + i) - position) % CNT;
    int value = strip.gamma8((CNT - i) * (255 / CNT));
    sprintf(output, "i: %d, pos: %d, value: %d", i, pos, value);
    Serial.println(output);
    strip.setPixelColor(pos, getPixelColorHsv(i, 0, 255, value));
#else
    int pos = (i + position) % CNT;
    int value = strip.gamma8(i * (255 / CNT));
    sprintf(output, "i: %d, pos: %d, value: %d", i, pos, value);
    Serial.println(output);
    strip.setPixelColor(pos, getPixelColorHsv(i, 0, 255, value));
#endif
  }
  strip.show();
  position++;
  position %= CNT;
  delay(5000);
}

Clockwise

position: 0
i: 0, pos: 0, value: 0
i: 1, pos: 1, value: 0
i: 2, pos: 2, value: 0
i: 3, pos: 3, value: 1
i: 4, pos: 4, value: 2
i: 5, pos: 5, value: 4
i: 6, pos: 6, value: 6
i: 7, pos: 7, value: 9
i: 8, pos: 8, value: 13
i: 9, pos: 9, value: 17
i: 10, pos: 10, value: 22
i: 11, pos: 11, value: 29
i: 12, pos: 12, value: 36
i: 13, pos: 13, value: 44
i: 14, pos: 14, value: 54
i: 15, pos: 15, value: 64
i: 16, pos: 16, value: 76
i: 17, pos: 17, value: 89
i: 18, pos: 18, value: 103
i: 19, pos: 19, value: 119
i: 20, pos: 20, value: 136
i: 21, pos: 21, value: 154
i: 22, pos: 22, value: 174
i: 23, pos: 23, value: 195
position: 1
i: 0, pos: 1, value: 0
i: 1, pos: 2, value: 0
i: 2, pos: 3, value: 0
i: 3, pos: 4, value: 1
i: 4, pos: 5, value: 2
i: 5, pos: 6, value: 4
i: 6, pos: 7, value: 6
i: 7, pos: 8, value: 9
i: 8, pos: 9, value: 13
i: 9, pos: 10, value: 17
i: 10, pos: 11, value: 22
i: 11, pos: 12, value: 29
i: 12, pos: 13, value: 36
i: 13, pos: 14, value: 44
i: 14, pos: 15, value: 54
i: 15, pos: 16, value: 64
i: 16, pos: 17, value: 76
i: 17, pos: 18, value: 89
i: 18, pos: 19, value: 103
i: 19, pos: 20, value: 119
i: 20, pos: 21, value: 136
i: 21, pos: 22, value: 154
i: 22, pos: 23, value: 174
i: 23, pos: 0, value: 195
position: 2
i: 0, pos: 2, value: 0
i: 1, pos: 3, value: 0
i: 2, pos: 4, value: 0
i: 3, pos: 5, value: 1
i: 4, pos: 6, value: 2
i: 5, pos: 7, value: 4
i: 6, pos: 8, value: 6
i: 7, pos: 9, value: 9
i: 8, pos: 10, value: 13
i: 9, pos: 11, value: 17
i: 10, pos: 12, value: 22
i: 11, pos: 13, value: 29
i: 12, pos: 14, value: 36
i: 13, pos: 15, value: 44
i: 14, pos: 16, value: 54
i: 15, pos: 17, value: 64
i: 16, pos: 18, value: 76
i: 17, pos: 19, value: 89
i: 18, pos: 20, value: 103
i: 19, pos: 21, value: 119
i: 20, pos: 22, value: 136
i: 21, pos: 23, value: 154
i: 22, pos: 0, value: 174
i: 23, pos: 1, value: 195

Counter clock-wise

position: 0
i: 0, pos: 0, value: 218
i: 1, pos: 1, value: 195
i: 2, pos: 2, value: 174
i: 3, pos: 3, value: 154
i: 4, pos: 4, value: 136
i: 5, pos: 5, value: 119
i: 6, pos: 6, value: 103
i: 7, pos: 7, value: 89
i: 8, pos: 8, value: 76
i: 9, pos: 9, value: 64
i: 10, pos: 10, value: 54
i: 11, pos: 11, value: 44
i: 12, pos: 12, value: 36
i: 13, pos: 13, value: 29
i: 14, pos: 14, value: 22
i: 15, pos: 15, value: 17
i: 16, pos: 16, value: 13
i: 17, pos: 17, value: 9
i: 18, pos: 18, value: 6
i: 19, pos: 19, value: 4
i: 20, pos: 20, value: 2
i: 21, pos: 21, value: 1
i: 22, pos: 22, value: 0
i: 23, pos: 23, value: 0
position: 1
i: 0, pos: 23, value: 218
i: 1, pos: 0, value: 195
i: 2, pos: 1, value: 174
i: 3, pos: 2, value: 154
i: 4, pos: 3, value: 136
i: 5, pos: 4, value: 119
i: 6, pos: 5, value: 103
i: 7, pos: 6, value: 89
i: 8, pos: 7, value: 76
i: 9, pos: 8, value: 64
i: 10, pos: 9, value: 54
i: 11, pos: 10, value: 44
i: 12, pos: 11, value: 36
i: 13, pos: 12, value: 29
i: 14, pos: 13, value: 22
i: 15, pos: 14, value: 17
i: 16, pos: 15, value: 13
i: 17, pos: 16, value: 9
i: 18, pos: 17, value: 6
i: 19, pos: 18, value: 4
i: 20, pos: 19, value: 2
i: 21, pos: 20, value: 1
i: 22, pos: 21, value: 0
i: 23, pos: 22, value: 0
position: 2
i: 0, pos: 22, value: 218
i: 1, pos: 23, value: 195
i: 2, pos: 0, value: 174
i: 3, pos: 1, value: 154
i: 4, pos: 2, value: 136
i: 5, pos: 3, value: 119
i: 6, pos: 4, value: 103
i: 7, pos: 5, value: 89
i: 8, pos: 6, value: 76
i: 9, pos: 7, value: 64
i: 10, pos: 8, value: 54
i: 11, pos: 9, value: 44
i: 12, pos: 10, value: 36
i: 13, pos: 11, value: 29
i: 14, pos: 12, value: 22
i: 15, pos: 13, value: 17
i: 16, pos: 14, value: 13
i: 17, pos: 15, value: 9
i: 18, pos: 16, value: 6
i: 19, pos: 17, value: 4
i: 20, pos: 18, value: 2
i: 21, pos: 19, value: 1
i: 22, pos: 20, value: 0
i: 23, pos: 21, value: 0

Source code

The source code is located on the GitHub server.



Video



19.12.2021


Menu