Files @ 61fc6a315f27
Branch filter:

Location: Wearables/Neopixel-Goggles/Neopixel_Goggles.ino - annotation

Dennis Fink
Remove empty line
a4ad34889569
fb907b72aae9
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
6255b67a731b
6255b67a731b
6255b67a731b
a4ad34889569
a4ad34889569
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
2de2ee7f659f
2de2ee7f659f
2de2ee7f659f
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
6255b67a731b
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a5be02268126
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
6255b67a731b
6255b67a731b
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
e12ecbf1cb9f
e12ecbf1cb9f
e12ecbf1cb9f
e12ecbf1cb9f
e12ecbf1cb9f
e12ecbf1cb9f
e12ecbf1cb9f
e12ecbf1cb9f
a4ad34889569
e12ecbf1cb9f
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
6255b67a731b
e292df7a2a7a
6255b67a731b
e292df7a2a7a
a4ad34889569
a4ad34889569
6255b67a731b
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
6255b67a731b
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
a4ad34889569
#include <Adafruit_NeoPixel.h>

#ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc.
#include <avr/power.h>
#endif

/* Begin config section
-----------------------*/

#define PIN 0

#define BRIGHTNESS 64

#define MODE_CHANGE_TIME 10000

#define COLOR_MIN 0
#define COLOR_MAX 255

#define STEPS_MIN 5
#define STEPS_MAX 10

#define SLOW_INTERVAL_MIN 25
#define SLOW_INTERVAL_MAX 55

#define RAINBOW_CYCLE_MIN_INTERVAL 1
#define RAINBOW_CYCLE_MAX_INTERVAL 10

#define BLINK_MIN_INTERVAL 250
#define BLINK_MAX_INTERVAL 500

/* End config section */

enum  pattern {
  RAINBOW_CYCLE,
  COLOR_WIPE,
  DOUBLE_COLOR_WIPE,
  SCANNER,
  DOUBLE_SCANNER,
  RANDOM,
  DOUBLE_RANDOM,
  BLINK,
  DOT
};

class NeoPatterns : public Adafruit_NeoPixel {
  public:
    pattern  ActivePattern;

    uint16_t Interval;
    unsigned long lastUpdate;
    uint32_t PixelColor;
    uint16_t TotalSteps;
    uint16_t Index;

    void (*OnComplete)();

    NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)()) : Adafruit_NeoPixel(pixels, pin, type) {
      OnComplete = callback;
    }

    void Update() {
      if ((millis() - lastUpdate) > Interval) {
        lastUpdate = millis();
        switch (ActivePattern) {
          case RAINBOW_CYCLE:
            RainbowCycleUpdate();
            break;
          case COLOR_WIPE:
            ColorWipeUpdate();
            break;
          case DOUBLE_COLOR_WIPE:
            DoubleColorWipeUpdate();
            break;
          case SCANNER:
            ScannerUpdate();
            break;
          case DOUBLE_SCANNER:
            DoubleScannerUpdate();
            break;
          case RANDOM:
            RandomUpdate();
            break;
          case DOUBLE_RANDOM:
            DoubleRandomUpdate();
            break;
          case BLINK:
            BlinkUpdate();
            break;
          case DOT:
            DotUpdate();
            break;
          default:
            break;
        }
      }
    }

    void Increment() {
      show();
      Index++;
      if (Index >= TotalSteps) {
        Index = 0;
        OnComplete();
      }
    }

    void RainbowCycle(uint16_t interval) {
      ActivePattern = RAINBOW_CYCLE;
      Interval = interval;
      TotalSteps = 255;
      Index = 0;
    }

    void RainbowCycleUpdate() {
      for (int i = 0; i < numPixels(); i++) {
        setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
      }
      Increment();
    }

    void ColorWipe(uint32_t color, uint16_t interval) {
      ActivePattern = COLOR_WIPE;
      Interval = interval;
      TotalSteps = numPixels();
      PixelColor = color;
      Index = 0;
    }

    void ColorWipeUpdate() {
      setPixelColor(Index, PixelColor);
      Increment();
    }

    void DoubleColorWipe(uint32_t color, uint16_t interval) {
      ActivePattern = DOUBLE_COLOR_WIPE;
      Interval = interval;
      TotalSteps = numPixels() / 2;
      PixelColor = color;
      Index = 0;
    }

    void DoubleColorWipeUpdate() {
      setPixelColor(Index, PixelColor);
      setPixelColor(numPixels() - 1 - Index, PixelColor);
      Increment();
    }

    void Scanner(uint32_t color, uint16_t interval) {
      ActivePattern = SCANNER;
      Interval = interval;
      TotalSteps = (numPixels() - 1) * 2;
      PixelColor = color;
      Index = 0;
    }

    void ScannerUpdate() {
      for (int i = 0; i < numPixels(); i++) {
        if (i == Index) {
          setPixelColor(i, PixelColor);
        }
        else if (i == TotalSteps - Index)  {
          setPixelColor(i, PixelColor);
        }
        else {
          setPixelColor(i, DimColor(getPixelColor(i)));
        }
      }
      Increment();
    }

    void DoubleScanner(uint32_t color, uint16_t interval) {
      ActivePattern = DOUBLE_SCANNER;
      Interval = interval;
      TotalSteps = (numPixels() / 2);
      PixelColor = color;
      Index = 0;
    }

    void DoubleScannerUpdate() {
      for (int i = 0; i < numPixels() / 2; i++) {
        if (i == Index) {
          setPixelColor(i, PixelColor); // First Eye
          setPixelColor(numPixels() - 1 - i, PixelColor); // Second Eye
        }
        else {
          setPixelColor(i, DimColor(getPixelColor(i)));
          setPixelColor(numPixels() - 1 - i, DimColor(getPixelColor(i)));
        }
      }
      Increment();
    }

    void Random(uint32_t color, uint16_t steps, uint16_t interval) {
      ActivePattern = RANDOM;
      Interval = interval;
      TotalSteps = steps;
      PixelColor = color;
      Index = 0;
    }

    void RandomUpdate() {
      setPixelColor(random(numPixels()), PixelColor);
      Increment();
    }

    void DoubleRandom(uint32_t color, uint16_t steps, uint16_t interval) {
      ActivePattern = DOUBLE_RANDOM;
      Interval = interval;
      TotalSteps = steps;
      PixelColor = color;
      Index = 0;
    }

    void DoubleRandomUpdate() {
      int i = random(numPixels() / 2);
      setPixelColor(i, PixelColor);
      setPixelColor(numPixels() - 1 - i, PixelColor);
      Increment();
    }

    void Blink(uint32_t color, uint16_t steps, uint16_t interval) {
      ActivePattern = BLINK;
      Interval = interval;
      if (steps % 2 != 0) {
        steps++;
      }
      TotalSteps = steps;
      PixelColor = color;
      Index = 0;
    }

    void BlinkUpdate() {
      uint32_t c;
      if (Index % 2 == 0) {
        c = PixelColor;
      } else {
        c = Color(0, 0, 0);
      }
      ColorSet(c);
      Increment();
    }

    void Dot(uint32_t color, uint16_t steps, uint16_t interval) {
      ActivePattern = DOT;
      Interval = interval;
      TotalSteps = steps;
      PixelColor = color;
      Index = 0;
    }

    void DotUpdate() {
      ColorSet(Color(0, 0, 0));
      show();
      setPixelColor(random(numPixels()), PixelColor);
      Increment();
    }

    uint32_t DimColor(uint32_t color) {
      return Color(((color >> 16) & 0xFF) >> 1, ((color >> 8) & 0xFF) >> 1, (color & 0xFF) >> 1);
    }

    uint32_t Wheel(byte WheelPos) {
      WheelPos = 255 - WheelPos;
      if (WheelPos < 85) {
        return Color(255 - WheelPos * 3, 0, WheelPos * 3);
      }
      else if (WheelPos < 170) {
        WheelPos -= 85;
        return Color(0, WheelPos * 3, 255 - WheelPos * 3);
      }
      else {
        WheelPos -= 170;
        return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
      }
    }

    void ColorSet(uint32_t color) {
      for (int i = 0; i < numPixels(); i++) {
        setPixelColor(i, color);
      }
    }
};

void RingsComplete();

NeoPatterns Rings(32, PIN, NEO_GRB + NEO_KHZ800, &RingsComplete);
uint8_t mode = 0;
uint32_t prev_time;

void setup() {
#ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc.
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  Rings.begin();
  Rings.setBrightness(BRIGHTNESS);
  Rings.RainbowCycle(random(RAINBOW_CYCLE_MIN_INTERVAL, RAINBOW_CYCLE_MAX_INTERVAL + 1));
  prev_time = millis();
}

void loop() {
  Rings.Update();
  /*
   * We could store the return of the first millis call in a variable.
   * But this routine is fast, so we only loose some milliseconds (if even)
   * and we are not that time critical, that the MODE changes extacly after
   * MODE_CHANGE_TIME. Calling millis twice, saves us 8 bytes, which is critical
   * for the small storage space we have.
   */
  if ((millis() - prev_time) >= MODE_CHANGE_TIME) {
    mode = random(0, 9);
    prev_time = millis();
  }
}

void RingsComplete()
{
  uint16_t slow_interval = random(SLOW_INTERVAL_MIN, SLOW_INTERVAL_MAX + 1);
  uint16_t steps = random(STEPS_MIN, STEPS_MAX + 1);
  uint32_t color = Rings.Wheel(random(COLOR_MIN, COLOR_MAX + 1));
  
  switch (mode) {
    case 0:
      Rings.RainbowCycle(random(RAINBOW_CYCLE_MIN_INTERVAL, RAINBOW_CYCLE_MAX_INTERVAL + 1));
      break;
    case 1:
      Rings.ColorWipe(color, slow_interval);
      break;
    case 2:
      Rings.DoubleColorWipe(color, slow_interval);
      break;
    case 3:
      Rings.Scanner(color, slow_interval);
      break;
    case 4:
      Rings.DoubleScanner(color, slow_interval);
      break;
    case 5:
      Rings.Random(color, steps, slow_interval);
      break;
    case 6:
      Rings.DoubleRandom(color, steps, slow_interval);
      break;
    case 7:
      Rings.Blink(color, steps, random(BLINK_MIN_INTERVAL, BLINK_MAX_INTERVAL + 1));
      break;
    case 8:
      Rings.Dot(color, steps, slow_interval);
      break;
    default:
      break;
  }
}