Monday, July 25, 2016

Jump-activated rainbow beanie (retrospective)

This was a project I did about a year ago after attending a workshop on arduino wearables. The project was run at the MAAS, which does some great events for kids and young adults, but doesn't often run events for adults. So I was happy when I heard they were doing an adults course, and came along. I'd seen some super cool wearable projects, and the mix of electronics and textiles/soft surfaces seemed cool. During the workshop everyone was given an arduino Gemma, some neopixels, a bunch of little sensors and some conductive thread and encouraged to see what we could make. I ended up connecting four neopixels up to the Gemma with a little vibration switch and sewed them all into a beanie: voila! a jump activated rainbow beanie.


The neopixels take power, ground and are driven by one digital output pin that transmits individually addressed RGB data to each and every neopixel attached along a chain. The vibration switch is triggered when shaken or given a good jolt, and one of the Gemma pins was used to read its state. The code on the Gemma would then just trigger a preprogrammed rainbow sequence along the neopixels.


All of connections were made using conductive thread sewed into the rim of the beanie and powered from a small 500 mAh lipo battery. Because the beanie was quite stretchy, I had to sew the conductive thread lines in a sort of zig-zag fashion: this meant they would sort of flex with the beanie when someone stretched it over their head (instead of just snap). Definitely the most time consuming part of the project was sewing the conductive thread circuit!

Here's the final code for my project sketch:

/* rainbow_jump_hat.ino - arduino sketch using four neopixels 
displaying a rainbow pattern triggered by a vibration switch
*/

#include 

#define LED_PIN 0
#define VIBSWITCH_PIN 1

Adafruit_NeoPixel strip = 
    Adafruit_NeoPixel(4, LED_PIN, NEO_GRB + NEO_KHZ800);

int VibSwitchState = 0;
int event = 0;
int eventcount = 0;

void setPixelHue(int pixel, int hue)
{
  while(hue < 0)
  {
    hue += 360;
  }
  
  float h = hue % 360;
    
  float sectorPos = h / 60;
  int sectorNumber = (int)floor(sectorPos);
  float fractionalSector = sectorPos - sectorNumber;
        
  float q = 1 - fractionalSector;
  float t = fractionalSector;
        
  switch(sectorNumber)
  {
    case 0:
      strip.setPixelColor(pixel, 255, 255 * t, 0);
      break;
    case 1:
      strip.setPixelColor(pixel, 255 * q, 255, 0);
      break;
    case 2:
      strip.setPixelColor(pixel, 0, 255, 255 * t);
      break;
    case 3:
      strip.setPixelColor(pixel, 0, 255 * q, 255);
      break;
    case 4:
      strip.setPixelColor(pixel, 255 * t, 0, 255);
      break;
    case 5:
      strip.setPixelColor(pixel, 255, 0, 255 * q);
      break;
  }
}

void DoRainbow() {
  for(int i = 0; i < 360; i++) {
    strip.setBrightness(255);
    setPixelHue(0, i);
    setPixelHue(1, i + 90);
    setPixelHue(2, i + 180);
    setPixelHue(3, i + 270);
    strip.show();
    delay(10);
  }
}

void setup()
{
  strip.begin();
  strip.setBrightness(255);
  strip.show();
  pinMode(VIBSWITCH_PIN, INPUT);
}

void loop()
{
  // Look for motion
  VibSwitchState = digitalRead(VIBSWITCH_PIN);
  if (VibSwitchState == HIGH) {
    event = 1;
  }
  else {
    event = 0;
  }
  
  if (event == 1) {
    DoRainbow();
    DoRainbow();
    event = 0;
  }
  else {
    for(int i = 0; i < 4; i++) {
      strip.setBrightness(0);
    }
    strip.show();
    delay(10);
  }
}

No comments:

Post a Comment