fablab

NeoPixel Waag logo

I’m gonna make the Waag logo emit light with NeoPixels, with 3 modes that you can switch between: white light that can be dimmed with a pot meter, color that can be changed with the same pot meter, and rainbow mode (a standard NeoPixel option).

Neopixels and Arduino Mini

What I’m using:

Neopixel specifications:

Chaotic breadboard wiring:

First I soldered the NeoPixel quarter rings into a circle. I used wires of about 10cm long so I could make a wider circle; since we want to mount the NeoPixels to the Waag logo it won’t be (too) noticable that the circle is interrupted. Below you can see the soldered neopixels and a sneak preview of the milled PCB.

Arduino code

Notes on the code:

Code used:

#include <Adafruit_NeoPixel.h>
int pushButton = 4;   // choose the input pin (for a pushbutton)
int pushButtonRotary = 2;

// Potentiometer
int potSensor = A0;
int currentColourValue;

int lastState = 0; // the previous state from the input pin
int currentState = 0;    // the current reading from the input pin
static int hits = 0;

// Which pin on the Arduino is connected to the NeoPixels?
#define LED_PIN    7

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 60

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  pinMode(pushButton, INPUT);
  //  pinMode(pushButton, INPUT_PULLUP);

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
}

void loop() {
  lightSwitcher();
}

void lightSwitcher() {
  currentState = digitalRead(pushButton);
  int sensorValue = analogRead(potSensor);

  Serial.println("lightSwitcher loop start");
  Serial.print(sensorValue);  // potentiometer value 0-1023
  Serial.println(" potentiometer value");
  Serial.print(currentState); // HIGH (1) or LOW (0), button pressed or not pressed
  Serial.println(" button value");

  if (currentState != lastState) {
    if (currentState == HIGH) {
      hits = hits + 1;
      Serial.print(hits);
      Serial.println(" hits");
      delay(1);
    }
  }

  if (hits == 0) {
    whiteLight();
  }

  if (hits == 1) {
    rainbow(1);
    hits = hits + 1; // otherwise we can't exit the rainbow part
  }

  if (hits == 3) {
    potentioMeter();
  }

  if (hits == 4) {
    whiteLight();
    if (currentState != lastState) {
      if (currentState == HIGH) {
        hits = 0;
        Serial.println(hits);
        Serial.println("reset hits");
      }
    }
  }
}

void whiteLight() {
  int sensorValue = analogRead(potSensor);
  for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...
      strip.setPixelColor(i, 255, 255, 255, 255);
      strip.show();                          //  Update strip to match
      delay(1);                           //  Pause for a moment
      strip.setBrightness(sensorValue / 4); // 0-1023 values divided by 4 is about 0-255
    }
}

void potentioMeter() {
  Serial.println("potentioMeter loop start");
  int sensorValue = analogRead(potSensor);
  for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(sensorValue * 64)));
    strip.show();                          //  Update strip to match
    delay(1);                           //  Pause for a moment
  }
  currentState = digitalRead(pushButton);
  Serial.print(currentState); // HIGH (1) or LOW (0), button pressed or not pressed
  Serial.println(" button value, we're in the potentiometer part now");


}

// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(int wait) {
  // Hue of first pixel runs 5 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
  // means we'll make 5*65536/256 = 1280 passes through this outer loop:
  for (long firstPixelHue = 0; firstPixelHue < 65536; firstPixelHue += 256) {
    for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...
      // Offset pixel hue by an amount to make one full revolution of the
      // color wheel (range of 65536) along the length of the strip
      // (strip.numPixels() steps):
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
      // optionally add saturation and value (brightness) (each 0 to 255).
      // Here we're using just the single-argument hue variant. The result
      // is passed through strip.gamma32() to provide 'truer' colors
      // before assigning to each pixel:
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

Replacing Arduino Pro Mini with Attiny

pinout attiny 1614

KiCad

Project schematic (including the capacitor mistake for the neopixel ring).

This is where I assigned all components that I was going to add with wires to through-hole solder pads.

The rat’s nest:

Final design with the rat’s nest all sorted out:

3d preview of the board:

Milling the board

Below collage summary of milling the board. It wasn’t too eventful except that the through holes didn’t properly cut all the way through, so I used the milling bit afterwards to push through the holes.

Soldering the board

Notes

I accidentally connected the 330 Ohm resistor to the power instead of the data pin in KiCad and only found out that that happened when I was already done milling, so I added a 0 ohm resistor in place of the 330 one, removed a bit of the trace between the data pin and the ATTiny and added it there.

Programming the ATTiny

I used these specific hooks/claws (I forgot the name) to attach to the individual legs of the chip to program them. You can use these if you haven’t added a connector for a programmer.

First prototype of the box:

Assembly process:

Final result: