Introduction: Arduino LED DJ Helmet
Marshmellow Helmet with LED strip using accelerometer and Arduino Uno technology to control colors of the lights.
Step 1: Tools
Wire stripper
Drill
Paddle bit (3/4 inch)
Scissors
Razor Knife
Tape measure
Needle nose pliers
Blow Dryer
Sharpie
Step 2: Materials / Components
Marshmellow Helmet (includes foaming)
Arduino Uno
Accelerometer
LED strip
Jumper wires
Switch
Scotch Double sided tape
26 guage wire
Stakon wire terminals
Heat shrink
Scotch Clear Tape
Scotch Blue Tape
Black Cloth
Breadboard
2 Resistors
9v Battery
Battery Connector for Arduino
USB Hook up for Arduino
Computer
Arduino Software
Step 3: Testing
Before you actually start, it is a good idea to test your LED and Accelerometer and make sure they are working.
To test and possibly calibrate the accelerometer use this tutorial. https://learn.adafruit.com/adafruit-analog-accelerometer-breakouts/assembly-and-wiring
Once you see that your accelerometer works, use this tutorial to test your LED. https://create.arduino.cc/projecthub/glowascii/neopixel-leds-arduino-basics-126d1a
Step 4: Coding
For this project, I combined coding from Adafruit Neopixel Strandtest (which can be downloaded here https://github.com/adafruit/Adafruit_NeoPixel ) and code from this wonderful blog post (which can be found here https://github.com/swedishhat/yaaa/blob/master/mpu6050-led-ahrs/mpu6050-led-ahrs.ino ).
This is the code that I eventually stuck with, however, you can edit the code any way you like with whatever effects you'd like.
/* This is R. Godwin's mash up or MPU6050_raw and the strand test for neopixels.
*/
//Start the MPU_6050 important junk
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files // for both classes must be in the include path of your project #include "I2Cdev.h" #include "MPU6050.h"
// class default I2C address is 0x68 // specific I2C addresses may be passed as a parameter here // AD0 low = 0x68 (default for InvenSense evaluation board) // AD0 high = 0x69 MPU6050 accelgyro; //MPU6050 accelgyro(0x69); // <-- use for AD0 high
int16_t ax, ay, az; int16_t gx, gy, gz;
// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated // list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read, // not so easy to parse, and slow(er) over UART. #define OUTPUT_READABLE_ACCELGYRO
//END the MPU_6050 important junk
//Start Neopixel junk
#define LED_PIN 13 bool blinkState = false;
#include #ifdef __AVR__ #include #endif
#define PIN 6
// Parameter 1 = number of pixels in strip // Parameter 2 = Arduino pin number (most are valid) // Parameter 3 = pixel type flags, add together as needed: // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across // pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input // and minimize distance between Arduino and first pixel. Avoid connecting // on a live circuit...if you must, connect GND first.
//End Neopixel junk
void setup() { //MPU_6050 setup
// join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif
// initialize serial communication // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but // it's really up to you depending on your project) Serial.begin(38400);
// initialize device Serial.println("Initializing I2C devices..."); accelgyro.initialize();
// verify connection Serial.println("Testing device connections..."); Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
// configure Arduino LED pin for output pinMode(LED_PIN, OUTPUT); //End MPU_6050 setup
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket #if defined (__AVR_ATtiny85__) if (F_CPU == 16000000) clock_prescale_set(clock_div_1); #endif // End of trinket special code
strip.begin(); strip.show(); // Initialize all pixels to 'off' }
void loop() { // read raw accel/gyro measurements from device accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// these methods (and a few others) are also available //accelgyro.getAcceleration(&ax, &ay, &az); //accelgyro.getRotation(&gx, &gy, &gz);
#ifdef OUTPUT_READABLE_ACCELGYRO // display tab-separated accel/gyro x/y/z values Serial.print("a/g:\t"); Serial.print(ax); Serial.print("\t"); Serial.print(ay); Serial.print("\t"); Serial.print(az); Serial.print("/t"); Serial.print(gx); Serial.print("\t"); Serial.print(gy); Serial.print("\t"); Serial.println(gz);
#endif int redVal = ax; int grnVal = ay; int bluVal = az;
redVal = map(redVal,0,20000,0,255); grnVal = map(grnVal,0,20000,0,255); bluVal= map(bluVal,0,20000,0,255);
gx = map(gx,0,20000,0,255); gy = map(gy,0,20000,0,255); gz = map(gz,0,20000,0,255);
// blink LED to indicate activity blinkState = !blinkState; digitalWrite(LED_PIN, blinkState);
// // Some example procedures showing how to display to the pixels: colorWipe(strip.Color(gx, gy, gz), 5); // g vals // colorWipe(strip.Color(0, 255, 0), 50); // Green // colorWipe(strip.Color(0, 0, 255), 50); // Blue //colorWipe(strip.Color(redVal, grnVal, bluVal), 3); // White RGBW // Send a theater pixel chase in... theaterChase(strip.Color(redVal, grnVal, bluVal), 40); // accelormeter vals // theaterChase(strip.Color(127, 0, 0), 50); // Red // theaterChase(strip.Color(0, 0, 127), 50); // Blue // // rainbow(20); // rainbowCycle(20); // theaterChaseRainbow(40); }
// Fill the dots one after the other with a color void colorWipe(uint32_t c, uint8_t wait) { for(uint16_t i=0; i
void rainbow(uint8_t wait) { uint16_t i, j;
for(j=0; j<256; j++) { for(i=0; i
// Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(uint8_t wait) { uint16_t i, j;
for(j=0; j<256*2; j++) { // 2 cycles of all colors on wheel for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); } strip.show(); delay(wait); } }
//Theatre-style crawling lights. void theaterChase(uint32_t c, uint8_t wait) { for (int j=0; j<20; j++) { //do 20 cycles of chasing for (int q=0; q < 3; q++) { for (uint16_t i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, c); //turn every third pixel on } strip.show();
delay(wait);
for (uint16_t i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } } }
//Theatre-style crawling lights with rainbow effect void theaterChaseRainbow(uint8_t wait) { for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel for (int q=0; q < 3; q++) { for (uint16_t i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on } strip.show();
delay(wait);
for (uint16_t i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } } }
// Input a value 0 to 255 to get a color value. // The colours are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if(WheelPos < 85) { return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 170) { WheelPos -= 85; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); }
Step 5: Wire It Up!
(This project/step assumes you soldered your accelerometer already.)
This is a lot of wiring, so I put the wiring into steps using Fritzing. Each image is an extension to the next, but does not have the previous step. Continue through the images as though they were all the same. I did not move the resistors to leave a reference.
This last Fritzing image is how it should look (except for one wire running from INT on accelerometer to 2 on Arduino) with extending wire (the yellow black and blue wires running off the breadboard) that leads to LED strip.
THE EXTRA WIRING IS FOR LEADING LED STRIP TO REACH TO BREADBOARD WHEN MOUNTED IN HELMET.
BE SURE TO HOOK UP LED WITH THE ARROWS FACING AWAY FROM THE BREADBOARD.
I also included my actual wiring.
Step 6: Putting It All Inside / Switch First:
Using Drill, Paddle Bit (3/4 inch is what worked for the switch I bought) and switch choose where you would like to place the switch. Keep in mind it will need to be reached while the helmet is on.
Drill hole in helmet and push switch through hole, try to keep it straight before you push it through because if it is snug it won't want to twist while it's in the helmet.
Cut one of the two wires of the battery connector and add wire to both ends of the wire you cut (I had 26 gauge wire handy, so that's what I used). Secure using heat shrink and a heat gun or blowdryer to heat it up.
Use Stakons to connect wires to switch. This is used for a snug fit and is less likely to come loose.
Plug in 9V battery to arduino and test switch out.
Step 7: LED
Use the scotch double stick tape and wrap it around the inside of the helmet where you want to put your LED strip. Measure everything out! This can be a pain because the tape can lose it's stickiness if you touch it too much. Run LED strip around the helmet pressing hard on the strip to make it stick well to tape.
Trim LED strip. I also added tape to keep the wires flush with the sides of the helmet.
Step 8: Mounting
Mount the breadboard, battery, and the Arduino in the middle of the helmet with scotch double stick tape making sure not to put them in the way of where the foam inside will sit. The breadboard I used already had a sticky backing, so I didn't add the tape to that, but I did for the Arduino and battery.
Step 9: Cut It Up!
When I bought the helmet, the foam inside was too thick and made visibility almost impossible, so I cut the foam in half with scissors.
Next I realized that the helmet was too wobbly to stay on your head without some sort of support, so I cut the other half a little shorter to stop before it got to the black visor.
I also cut a black piece of cloth about 12" x 12" and put it between the two halves of the foam to help protect and also hide the wiring. I did not attach the cloth in any way other than tucking it between the bottom half and the sides of the helmet. I wanted the cloth to be removable in order to get to the wiring and to change out the battery in the future
Step 10: Try It On!
The code takes a few seconds to start up, so give it some time and enjoy!