The wiring isn't soldered. I've got alligator clips running from the Gemma to short strands of wires I have twisted into the ring. I tried just the clips but nothing was working that way.
Code:
Code: Select all
[quote]
[color=#7E7E7E]/*[/color]
[color=#7E7E7E]NeoPixel Ring goggles sketch -- for steampunk, rave or Burning Man fashion![/color]
[color=#7E7E7E]Welding or costume goggles using 50mm round lenses can be outfitted with[/color]
[color=#7E7E7E]a pair of Adafruit NeoPixel Rings: http://www.adafruit.com/product/1463[/color]
[color=#7E7E7E]Please exercise common sense. These goggles emit a LOT of stray light and[/color]
[color=#7E7E7E]should NOT BE WORN ON YOUR EYES. They're for fashion and costuming only,[/color]
[color=#7E7E7E]for display on a hat or on your forehead.[/color]
[color=#7E7E7E]Draws a spinning rainbow on both eyepieces. Not a Mac beachball, honest.[/color]
[color=#7E7E7E]"Eyes" glance around and blink at random.[/color]
[color=#7E7E7E]For 'reflected' colors (rainbows rotate in opposite directions, while eyes[/color]
[color=#7E7E7E]look in same direction), connect the output of the first ring to the input[/color]
[color=#7E7E7E]of the second. Or you can connect the inputs of both rings to the same[/color]
[color=#7E7E7E]Arduino pin if that's easier -- the rainbows will both twirl in the same[/color]
[color=#7E7E7E]direction in that case.[/color]
[color=#7E7E7E]By default, pixel #0 (the first LED) on both rings should be at the TOP of[/color]
[color=#7E7E7E]the goggles. Looking at the BACK of the board, pixel #0 is immediately[/color]
[color=#7E7E7E]clockwise from the OUT connection. If a different pixel is at the top,[/color]
[color=#7E7E7E]that's OK, the code can compensate (TOP_LED_FIRST and TOP_LED_SECOND below).[/color]
[color=#7E7E7E]*/[/color]
#include <Adafruit_NeoPixel.h>
#ifdef __AVR_ATtiny85__ [color=#7E7E7E]// Trinket, Gemma, etc.[/color]
#include <avr/power.h>
#endif
#define PIN 0
#define TOP_LED_FIRST 0 [color=#7E7E7E]// Change these if the first pixel is not[/color]
#define TOP_LED_SECOND 0 [color=#7E7E7E]// at the top of the first and/or second ring.[/color]
#define EFFECT RAINBOW [color=#7E7E7E]// Choose a visual effect from the names below[/color]
#define RAINBOW 0
#define ECTO 1
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(32, PIN, NEO_GRB + NEO_KHZ800);
[color=#CC6600]const[/color] int8_t PROGMEM
yCoord[] = { [color=#7E7E7E]// Vertical coordinate of each pixel. First pixel is at top.[/color]
127,117,90,49,0,-49,-90,-117,-127,-117,-90,-49,0,49,90,117 },
sine[] = { [color=#7E7E7E]// Brightness table for ecto effect[/color]
0, 28, 96, 164, 192, 164, 96, 28, 0, 28, 96, 164, 192, 164, 96, 28 };
[color=#7E7E7E]// Eyelid vertical coordinates. Eyes shut slightly below center.[/color]
#define upperLidTop 130
#define upperLidBottom -45
#define lowerLidTop -40
#define lowerLidBottom -130
[color=#7E7E7E]// Gamma correction improves appearance of midrange colors[/color]
[color=#CC6600]const[/color] uint8_t PROGMEM gamma8[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7,
7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12,
13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20,
20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29,
30, 31, 31, 32, 33, 34, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 75,
76, 77, 78, 80, 81, 82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96,
97, 99,100,102,103,105,106,108,109,111,112,114,115,117,119,120,
122,124,125,127,129,130,132,134,136,137,139,141,143,145,146,148,
150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,
182,184,186,188,191,193,195,197,199,202,204,206,209,211,213,215,
218,220,223,225,227,230,232,235,237,240,242,245,247,250,252,255
};
uint32_t
iColor[16][3]; [color=#7E7E7E]// Background colors for eyes[/color]
int16_t
hue = 0; [color=#7E7E7E]// Initial hue around perimeter (0-1535)[/color]
uint8_t
iBrightness[16], [color=#7E7E7E]// Brightness map -- eye colors get scaled by these[/color]
brightness = 220, [color=#7E7E7E]// Global brightness (0-255)[/color]
blinkFrames = 5, [color=#7E7E7E]// Speed of current blink[/color]
blinkCounter = 30, [color=#7E7E7E]// Countdown to end of next blink[/color]
eyePos = 192, [color=#7E7E7E]// Current 'resting' eye (pupil) position[/color]
newEyePos = 192, [color=#7E7E7E]// Next eye position when in motion[/color]
gazeCounter = 75, [color=#7E7E7E]// Countdown to next eye movement[/color]
gazeFrames = 50; [color=#7E7E7E]// Duration of eye movement (smaller = faster)[/color]
int8_t
eyeMotion = 0; [color=#7E7E7E]// Distance from prior to new position[/color]
[color=#CC6600]void[/color] [color=#CC6600][b]setup[/b][/color]() {
#ifdef __AVR_ATtiny85__ [color=#7E7E7E]// Trinket, Gemma, etc.[/color]
[color=#CC6600]if[/color](F_CPU == 16000000) clock_prescale_set(clock_div_1);
[color=#7E7E7E]// Seed random number generator from an unused analog input:[/color]
[color=#CC6600]randomSeed[/color]([color=#CC6600]analogRead[/color](2));
#else
[color=#CC6600]randomSeed[/color]([color=#CC6600]analogRead[/color](A0));
#endif
pixels.[color=#CC6600]begin[/color]();
}
[color=#CC6600]void[/color] [color=#CC6600][b]loop[/b][/color]() {
uint8_t i, r, g, b, a, c, inner, outer, ep;
[color=#CC6600]int[/color] y1, y2, y3, y4, h;
int8_t y;
[color=#7E7E7E]// Draw eye background colors[/color]
#if EFFECT == RAINBOW
[color=#7E7E7E]// This renders a glotating rainbow...a WAY overdone LED effect but[/color]
[color=#7E7E7E]// does show the color gamut nicely.[/color]
[color=#CC6600]for[/color](h=hue, i=0; i<16; i++, h += 96) {
a = h;
[color=#CC6600]switch[/color]((h >> 8) % 6) {
[color=#CC6600]case[/color] 0: iColor[i][0] = 255; iColor[i][1] = a; iColor[i][2] = 0; [color=#CC6600]break[/color];
[color=#CC6600]case[/color] 1: iColor[i][0] = ~a; iColor[i][1] = 255; iColor[i][2] = 0; [color=#CC6600]break[/color];
[color=#CC6600]case[/color] 2: iColor[i][0] = 0; iColor[i][1] = 255; iColor[i][2] = a; [color=#CC6600]break[/color];
[color=#CC6600]case[/color] 3: iColor[i][0] = 0; iColor[i][1] = ~a; iColor[i][2] = 255; [color=#CC6600]break[/color];
[color=#CC6600]case[/color] 4: iColor[i][0] = a; iColor[i][1] = 0; iColor[i][2] = 255; [color=#CC6600]break[/color];
[color=#CC6600]case[/color] 5: iColor[i][0] = 255; iColor[i][1] = 0; iColor[i][2] = ~a; [color=#CC6600]break[/color];
}
}
hue += 7;
[color=#CC6600]if[/color](hue >= 1536) hue -= 1536;
#elif EFFECT == ECTO
[color=#7E7E7E]// A steampunk aesthetic might fare better with this more subdued effect.[/color]
[color=#7E7E7E]// Etherial green glow with just a little animation for visual spice.[/color]
a = (hue >> 4) & 15;
c = hue & 15;
[color=#CC6600]for[/color](i=0; i<16; i++) {
b = (a + 1) & 15;
iColor[i][1] = 255; [color=#7E7E7E]// Predominantly green[/color]
iColor[i][0] = (pgm_read_byte(&sine[a]) * (16 - c) +
pgm_read_byte(&sine[b]) * c ) >> 4;
iColor[i][2] = iColor[i][0] >> 1;
a = b;
}
hue -= 3;
#endif
[color=#7E7E7E]// Render current blink (if any) into brightness map[/color]
[color=#CC6600]if[/color](blinkCounter <= blinkFrames * 2) { [color=#7E7E7E]// In mid-blink?[/color]
[color=#CC6600]if[/color](blinkCounter > blinkFrames) { [color=#7E7E7E]// Eye closing[/color]
outer = blinkFrames * 2 - blinkCounter;
inner = outer + 1;
} [color=#CC6600]else[/color] { [color=#7E7E7E]// Eye opening[/color]
inner = blinkCounter;
outer = inner - 1;
}
y1 = upperLidTop - (upperLidTop - upperLidBottom) * outer / blinkFrames;
y2 = upperLidTop - (upperLidTop - upperLidBottom) * inner / blinkFrames;
y3 = lowerLidBottom + (lowerLidTop - lowerLidBottom) * inner / blinkFrames;
y4 = lowerLidBottom + (lowerLidTop - lowerLidBottom) * outer / blinkFrames;
[color=#CC6600]for[/color](i=0; i<16; i++) {
y = pgm_read_byte(&yCoord[i]);
[color=#CC6600]if[/color](y > y1) { [color=#7E7E7E]// Above top lid[/color]
iBrightness[i] = 0;
} [color=#CC6600]else[/color] [color=#CC6600]if[/color](y > y2) { [color=#7E7E7E]// Blur edge of top lid in motion[/color]
iBrightness[i] = brightness * (y1 - y) / (y1 - y2);
} [color=#CC6600]else[/color] [color=#CC6600]if[/color](y > y3) { [color=#7E7E7E]// In eye[/color]
iBrightness[i] = brightness;
} [color=#CC6600]else[/color] [color=#CC6600]if[/color](y > y4) { [color=#7E7E7E]// Blur edge of bottom lid in motion[/color]
iBrightness[i] = brightness * (y - y4) / (y3 - y4);
} [color=#CC6600]else[/color] { [color=#7E7E7E]// Below bottom lid[/color]
iBrightness[i] = 0;
}
}
} [color=#CC6600]else[/color] { [color=#7E7E7E]// Not in blink -- set all 'on'[/color]
memset(iBrightness, brightness, sizeof(iBrightness));
}
[color=#CC6600]if[/color](--blinkCounter == 0) { [color=#7E7E7E]// Init next blink?[/color]
blinkFrames = [color=#CC6600]random[/color](4, 8);
blinkCounter = blinkFrames * 2 + [color=#CC6600]random[/color](5, 180);
}
[color=#7E7E7E]// Calculate current eye movement, possibly init next one[/color]
[color=#CC6600]if[/color](--gazeCounter <= gazeFrames) { [color=#7E7E7E]// Is pupil in motion?[/color]
ep = newEyePos - eyeMotion * gazeCounter / gazeFrames; [color=#7E7E7E]// Current pos.[/color]
[color=#CC6600]if[/color](gazeCounter == 0) { [color=#7E7E7E]// Last frame?[/color]
eyePos = newEyePos; [color=#7E7E7E]// Current position = new pos[/color]
newEyePos = [color=#CC6600]random[/color](16) * 16; [color=#7E7E7E]// New pos. (always pixel center)[/color]
eyeMotion = newEyePos - eyePos; [color=#7E7E7E]// Distance to move[/color]
gazeFrames = [color=#CC6600]random[/color](10, 20); [color=#7E7E7E]// Duration of movement[/color]
gazeCounter = [color=#CC6600]random[/color](gazeFrames, 130); [color=#7E7E7E]// Count to END of next movement[/color]
}
} [color=#CC6600]else[/color] ep = eyePos; [color=#7E7E7E]// Not moving -- fixed gaze[/color]
[color=#7E7E7E]// Draw pupil -- 2 pixels wide, but sup-pixel positioning may span 3.[/color]
a = ep >> 4; [color=#7E7E7E]// First candidate[/color]
b = (a + 1) & 0x0F; [color=#7E7E7E]// 1 pixel CCW of a[/color]
c = (a + 2) & 0x0F; [color=#7E7E7E]// 2 pixels CCW of a[/color]
i = ep & 0x0F; [color=#7E7E7E]// Fraction of 'c' covered (0-15)[/color]
iBrightness[a] = (iBrightness[a] * i ) >> 4;
iBrightness[b] = 0;
iBrightness[c] = (iBrightness[c] * (16 - i)) >> 4;
[color=#7E7E7E]// Merge iColor with iBrightness, issue to NeoPixels[/color]
[color=#CC6600]for[/color](i=0; i<16; i++) {
a = iBrightness[i] + 1;
[color=#7E7E7E]// First eye[/color]
r = iColor[i][0]; [color=#7E7E7E]// Initial background RGB color[/color]
g = iColor[i][1];
b = iColor[i][2];
[color=#CC6600]if[/color](a) {
r = (r * a) >> 8; [color=#7E7E7E]// Scale by brightness map[/color]
g = (g * a) >> 8;
b = (b * a) >> 8;
}
pixels.setPixelColor(((i + TOP_LED_FIRST) & 15),
pgm_read_byte(&gamma8[r]), [color=#7E7E7E]// Gamma correct and set pixel[/color]
pgm_read_byte(&gamma8[g]),
pgm_read_byte(&gamma8[b]));
[color=#7E7E7E]// Second eye uses the same colors, but reflected horizontally.[/color]
[color=#7E7E7E]// The same brightness map is used, but not reflected (same left/right)[/color]
r = iColor[15 - i][0];
g = iColor[15 - i][1];
b = iColor[15 - i][2];
[color=#CC6600]if[/color](a) {
r = (r * a) >> 8;
g = (g * a) >> 8;
b = (b * a) >> 8;
}
pixels.setPixelColor(16 + ((i + TOP_LED_SECOND) & 15),
pgm_read_byte(&gamma8[r]),
pgm_read_byte(&gamma8[g]),
pgm_read_byte(&gamma8[b]));
}
pixels.show();
[color=#CC6600]delay[/color](15);
}
[/quote]
YouTube Video