2023 Group 6: Apres-ski Party Hat

design blog

Project goals

Project Brief

Dance your cares away…

‘Create an e-textile with interactive LEDs that are set to flash to the beats of the music.’

Purpose

Skiers love to party and what is an après ski party without a light-up hat? Our warm, cosy hat is perfect for partying in the cold, snowy mountains and it lights up to the beat of the music! Wearing this hat will make you the envy of the slopes.

Requirements And Objectives

  • Create an e-textile (t-shirt, bag, skirt, etc) with interactive LEDs that can be set to either flash to the music’s beats or the wearer’s movement
  • Fit in a skiing environment
  • Interact with different types of music and beats
  • Program reactions using sensors and actuators (LEDs) with Arduino
  • Ensure physical components (such as Arduino Uno) do not make the user uncomfortable while wearing the hat
  • Consider sound for lighting schemes

Target audience

Skiers who love to party! The target demographic is skiers of all ages. The hat fits all sizes so any user can put it on and become the life of the party at any event.

Market Research

Product 1: Music Sync LED Lights Strip, RGB
Colour Changing LED Lights

Product 2: RGB Light Bars, Rechargeable Colourful Ambient LED Light Rhythm Light Bar, 32 Bit Sound Activated Lights, Voice Activated Pickup Music Rhythm Lights.

design decisions and processes

Brainstorming and Lofi prototypes

Brainstorming LED placement

Paper models

Design decisions

Colour – the colour changes based on volume of sound

Patterns – the patterns change based on the volume (colour)

  • Quiet: Blue and turquoise – LEDs change to this colour (they just turn on)
  • Medium: Orange and yellow – LEDs have a flashing dissolving pattern
  • Loud: Red – LEDs have a dissolving loop pattern

Brightness – the brightness changes based on the volume (colour)

  • Blue: 10
  • Green/blue: 20
  • Turquoise: 30
  • Green: 40
  • Yellow: 60
  • Orange: 80
  • Red: 100
Hifi Prototypes and Testing

First, we tested the LED strip and the sound sensor separately:

Testing the LED strip from the recycling box in the Electronics Lab. Initially, our LED strip wouldn’t work, it was resetting every 10 seconds. Then, we added the capacitor and resistor and it worked

Testing the sound sensor by using the serial monitor (code)

Testing the sound sensor by using the serial monitor (serial monitor output)

The circuit was shorting due to the previous soldering so we decided to resolder the wires

Re-soldering the wires

Re-soldered wires

Testing the patterns on the LED strip after we re-soldered them – they worked!

LED strip with basic loop animations
The LED pattern before adding the dissolve and loop animations
The LED pattern after adding the dissolve and loop animations

final product

Making
Re-soldering wires
Finished re-soldered wires
Sewing the LED strip
Final product

Project planning

GANTT Chart

makers manual

Components
  • Recycled WS2812B RGB LED strip (the main component of the project) x1
  • Arduino IDE x1
  • Breadboard x1
  • DAOKAI 5PCS High Sensitivity Microphone Sensor x1
  • Capacitor x1
  • Resistor x1
  • Wires x9
  • Fur hat x1
  • Battery pack x1
  • Power wire to attach Arduino IDE to battery pack x1
Tools
  • Soldering machine
  • Sewing kit
Breadboard Layout
How To Build
Building the circuit
  • Follow the circuit diagram above, attaching each component to their appropriate position
  • Ensure the sound sensor and the LEDs work before continuing to the next step. Also check that the wires on the LED are soldered correctly and are not touching to make sure there is no short circuiting
Attaching the circuit to the hat
  • Cut a hole at the top of the hat for the Arduino and the breadboard. The Arduino and the breadboard should fit into the seam of the hat so it cannot be seen on the outside or be touching the users head. Sew this in place
  • Attach the battery to Arduino Uno
  • Sew the LED strip around the front of the hat
  • Cut a hole on the side of the hat for the sound sensor to be attached. Sew the sound sensor in place so the sensor is on the outside of the hat
  • Attach the battery pack to the back of the hat

project evaluation

Shortcomings
  • The sensor in itself is quite basic, it measures the amplitude but not the frequency. 
  • After rigorous testing, we discovered that the range of values that it can output is around 5 variations. For example, ranging from 40 to 45, where 40 would be quiet and 45 would be loud. This did not give us a lot of space to be able to respond to the many variations of tones/frequencies/loudness of music. Before we had wanted to output darker, bluer colours for low frequencies and lighter, redder colours for higher frequencies, now we could only do so with amplitude and not frequency.
  • Improve aesthetics by improving the precision of sewing and incisions on the hat.
  • The sound sensor is exposed meaning the hat is not waterproof and also anything that touches the sensor will interfere with it.
Future Considerations
  • Incorporate gesture control with ultrasonic sound sensors that could provide an extra interactive layer.
  • Enabling users to customise patterns or animation with varying amplitude levels.
Conclusion

While the current sound sensor setup has its limitations in measuring only amplitude and providing a narrow range of values, the use of smaller Arduino and ultrasonic sound sensors could enhance the product by adding gesture control and customisable sound profiles and there is potential to overcome current constraints and responsive aspects of the project.

code

#include <FastLED.h>

#define SENSOR_PIN A0
#define LED_PIN 7
#define NUM_LEDS 47

// millis setup
unsigned long startTime;
unsigned long interval = 100;
unsigned long soundDetectionInterval = 1000;

// colours 
const CRGB red = CRGB(255, 0, 0);
const CRGB orange = CRGB(255, 128, 0);
const CRGB greenBlue = CRGB(0, 102,102);
const CRGB yellow = CRGB(255, 255, 0);
const CRGB green = CRGB(0, 153, 0);
const CRGB blue = CRGB(0, 0, 255);
const CRGB purple = CRGB(51, 0, 102);
const CRGB turqouise = CRGB(0, 102, 102);
const CRGB white = CRGB(255, 255, 255);

// default colour
CRGB colour = CRGB(0,0,0);
// initialise leds array
CRGB leds[NUM_LEDS];
// choose brightness
int brightness = 50;

void setup()
{
  pinMode(SENSOR_PIN, INPUT);
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  Serial.begin(9600);
  // turn off/reset LEDs
  clearLeds();
  fill_solid(leds, NUM_LEDS, red);
  FastLED.show(); // lights up all LEDs at once
}


void loop()
{ 
  delay(2);
  lightUp();
}

void lightUp() {
  CRGB colourDetermined = determineColour();
  FastLED.setBrightness(brightness);
  fill_solid(leds, NUM_LEDS, colourDetermined);
  FastLED.show(); // lights up all LEDs at once
}

CRGB determineColour(){
  unsigned long currentTime = millis();
  // read volume
  String volume = readSound();
  // choose which colour and pattern to display based on the volume
  if (currentTime - startTime >= interval) {
    if (volume == "ppp") {
      colour = blue;
      brightness = 10;
    }
    else if (volume == "pp") {
      colour = greenBlue;
      brightness = 20;
    }
    else if (volume == "p") {
      colour = turqouise;
      brightness = 30;
    }
    else if (volume == "mp") {
      colour = green;
      brightness = 40;
    }
    else if (volume == "mf") {
      colour = yellow;
      brightness = 60;
      dissolve(10, 10, 10);
    }
    else if (volume == "f") {
      colour = orange;
      brightness = 80;
      dissolve(10, 10, 10);
    }
    else if (volume == "ff") {
      colour = red;
      brightness = 100;
      displayLoopPattern(colour, 7);
      dissolve(10, 10, 7);
    }
    startTime = currentTime;
  }
  return colour;
}

void displayLoopPattern(CRGB patternColor, int patternSize) {
  FastLED.setBrightness(brightness);
  for (int i = 0; i < NUM_LEDS; i += patternSize) {
    for (int j = 0; j < patternSize && i + j < NUM_LEDS; j++) {
      leds[i + j] = patternColor;
    }
    FastLED.show();
    FastLED.delay(20);
    clearLeds();
  }
}

// turn off/reset LEDs
void clearLeds() {
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB::Black;
  }
}

// read the volue of the sensor
String readSound()
{
  int inputVolume = analogRead(SENSOR_PIN);
  String dynamicMarking = "";

  if (inputVolume < 42) {
    Serial.println("|");
    dynamicMarking =  "ppp";
  }
  else if (inputVolume == 42) {
    Serial.println("||");
    dynamicMarking =  "pp";
  }
  else if (inputVolume == 43) {
    Serial.println("|||");
    dynamicMarking =  "mf";
  }
  else if (inputVolume == 44 ) {
    Serial.println("|||||");
    dynamicMarking =  "f";
  }
  else if (inputVolume > 44) {
    Serial.println("||||||||||||||||||||||||||||||");
    dynamicMarking = "ff";
  }
  return dynamicMarking;
}

// Random dissolve colors
void dissolve(int simultaneous, int cycles, int speed){
  //delay(10);
  for(int i=0; i<cycles; i++){
    for(int j=0; j<simultaneous; j++){
      int idx = random(NUM_LEDS);
      leds[idx] = CRGB::Black;
    }
    FastLED.show();
    delay(speed);
  }
  allColor(CRGB::Black);
}

// Changes all LEDS to given color
void allColor(CRGB c){
  for(int i=0; i<NUM_LEDS; i++){
    leds[i] = c;
  }
  FastLED.show();
}