NeoPixel Ring - Rotace proti směru hodinových ručiček

Zápisník experimentátora

Hierarchy: WS2812

Dnes se budeme věnovat otázce, kterou mi položil jeden odběratel mého YouTube kanálu. Barvy rotují ve směru hodinových ručiček. Dala by se tato rotace otočit proti směru hodinových ručiček? Na první pohled se to zdá být jednoduché a také moje první reakce byla, aby změnil dva řádky ve zdrojovém kódu. Ale nefungovalo to. A tak jsem se na problém podíval a upravil jsem algoritmus tak, aby to rotovalo opačným směrem.

Příklad

Změna je v jediném řádku. Pokud se povolí makro CCW, tak prstenec rotuje proti směru hodinových ručiček. Nebudu tady ale psát, jaký jsem geniální programátor a jak jsem správný kód napsal hned na první pokus. Nenapsal jsem to na první pokus a těch pokusů bylo mnohem víc. Použil jsem k tomu metodu pokus-omyl, dokud se mi to nepodařilo. Takhle by se to nemělo dělat, ale když si myslíte, že je to snadné, tak tehdy se dějí i takové věci.

#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);
}

Náhodný pokus vede ke správnému výsledku

Z předchozího textu je jasné, že i náhodnými pokusy se někdy dostanete k cíli. Pojďme si ale prohlédnout hodnoty proměnných, abychom viděli, jak se k výsledku program přepracuje. Upravím trochu zdrojový kód, abychom na sériový port vypsali hodnoty v některých proměnných.

A z výpisů na sériovém portu je jasné, že to není úplně dokonalé. Zejména nastavení jasu v proměnné value by mělo být lépe roztaženo mezi hodnotami 0 – 255. Ale když se to pohybuje, lidské oko drobné nedokonalosti nepostřehne a iluze je dokonalá. Studujte jednotlivé výpisy a pokuste se uhodnout, jak se iluze pohybujícího prstence vytváří. Na NeoPixel Ring jsou jednotlivé LED umístěny ve směru hodinových ručiček a začínají na místě, kde jsou připojeny datové vodiče.

#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);
}

Ve směru hodinových ručiček

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

Proti směru hodinových ručiček

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

Zdrojový kód

Zdrojový kód se nachází na serveru GitHub.



Video



19.12.2021


Menu