[Arduino #26] LED helmet “done”

For last two weeks I tried to finish my old project: LED helmet. It has Receiver and Transmitter part.

  • Receiver:
    • 50 LEDs
    • RF 443MHz receiver
    • Arduino nano
    • Batteries
  • Transmitter:
    • two push buttons
    • RF 443MHz transmitter
    • Arduino nano
    • Batteries

The LEDs work just like rear lights on cars. Usually they are red and when you make a turn, one side will blink. If I have the LED helmet, I will be able to keep my hands on my handle all the time and to alert people on my back clearly.

All the parts were arrived from AliExpress and the project was getting old so I had to finish it. To tell the end result first, I’m done but the project isn’t. I’ve soldered 50 LEDs, wrote codes, and built all the boards, but I haven’t found the time to build a case so I could go wearable.

The project consisted of five parts:

  1. Ideas+researches (Fun)
  2. Purchasing parts (Lost in Google… @.@)
  3. Building hardware (Meditation)
  4. Coding (Fun)
  5. Building cases + battery issues (Difficult & Don’t have time)

Beginning

The project sounds simple but I’ve spent pretty long time about how I would make it. There are already several similar projects done before but none of them were really practical. One day I and my friend Heikki were talking in a cafe in Helsinki. We agreed on following things: there shouldn’t be too many LEDs(energy issue), it should look casual = it shouldn’t attract too much attention, and it should be detachable. I don’t exactly remember whom it was but I came with a design that I would build a receiver part that would simple hang on behind a helmet. When you consider how many holes there are behind helmets, it seemed to be a quite nice solution.

20150319_120924

Soldering

20150319_133456There were quite many things to solder. In one LED there are six points to solder and I had 50 LEDs. That will be 300 points to solder. I’ve soldered only 4 times before this and in total they were like 7 points. It was frustrating in the beginning when it took me one hour to solder 10 LEDs. However as I went on, it took me less than 30 minutes to solder 25 LEDS. It was indeed a nice soldering crash course and now I’m very confident about my soldering skill.

20150319_181329There was a nice surprise last Sat morning. I was coding in my room and I smelled something burning. It was a day after the soldering crash course so I thought I was smelling from my memory. However, I could smell for long time and I saw smoke rising from my electronic box. A AA-battery pack was burning. Only then I remembered the poster on the wall in our school lab that says, “Detach batteries from battery packs after use!!!!” Yeah, detach them because they burn!!!!

20150321_155332_1Coding

This is the snappiest codes I’ve ever written. I’m least proud to post them but I will post it anyway so someone can get benefit out of it. The codes were borrowed from Adafruit and Instructable

Receiver+LEDs


#include <Adafruit_NeoPixel.h>
#include <avr/power.h>
#include <VirtualWire.h>

#define LED_right_PIN 14
#define LED_left_PIN 15
#define receiver 2
boolean led_is_on = false;
boolean led_right_is_on = false;
boolean led_left_is_on = false;

// 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)
Adafruit_NeoPixel LED_right = Adafruit_NeoPixel(25, LED_right_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel LED_left = Adafruit_NeoPixel(25, LED_left_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.

void setup() {
vw_set_ptt_inverted(true); // Required for DR3100
vw_set_rx_pin(receiver);
vw_setup(4000);  // Bits per sec
pinMode(13, OUTPUT);

vw_rx_start();       // Start the receiver PLL running

LED_right.begin();
LED_right.show(); // Initialize all pixels to 'off'

LED_left.begin();
LED_left.show(); // Initialize all pixels to 'off'
Serial.begin(9600);

}

void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
for(unsigned long i=0; i < 90000; i++){
if(!led_is_on && vw_get_message(buf, &buflen)){
if(buf[0]=='5'){  // Turn right
digitalWrite(13,1);
led_right_is_on = true;
Serial.println("Right!");
both_blink(LED_left.Color(0,0,0), 10);
}//else if(buf[0]=='6'){
else{
digitalWrite(13,0);
led_left_is_on = true;
Serial.println("Left!");
both_blink(LED_right.Color(0,0,0), 10);
}
led_is_on = true;
break;
}else if(led_is_on && vw_get_message(buf, &buflen)){
led_is_on = false;
led_right_is_on = false;
led_left_is_on = false;
break;
}
}
if(!led_is_on){
////////// Turn on! //////////
both_blink(LED_left.Color(30,0,0), 10);
////////// Turn off! //////////
both_blink(LED_left.Color(0,0,0), 10);
}else if(led_is_on){
if(led_right_is_on){
Adafruit_NeoPixel strip = LED_right;
colorWipe(strip, strip.Color(30, 0, 0), 5); // Red
colorWipe(strip, strip.Color(0, 0, 0), 5); // Red
//monocolor(strip, strip.Color(0,0,0), 5);
}else if(led_left_is_on){
Adafruit_NeoPixel strip = LED_left;
colorWipe(strip, strip.Color(30, 0, 0), 5); // Red
colorWipe(strip, strip.Color(0, 0, 0), 5); // Red
//monocolor(strip, strip.Color(0,0,0), 10);
}

}
}

void both_blink(uint32_t c, uint8_t wait){
for(uint16_t i=0; i<LED_left.numPixels(); i++) {
LED_left.setPixelColor(i, c);
LED_right.setPixelColor(i, c);
LED_left.show();
LED_right.show();
delay(wait);
}
}

void monocolor(Adafruit_NeoPixel strip, uint32_t c, uint8_t wait){
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}

// Fill the dots one after the other with a color
void colorWipe(Adafruit_NeoPixel strip, uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}

void colorWipe_left(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<LED_left.numPixels(); i++) {
LED_left.setPixelColor(i, c);
LED_left.show();
delay(wait);
}
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< LED_right.numPixels(); i++) {
LED_right.setPixelColor(i, Wheel_right(((i * 256 / LED_right.numPixels()) + j) & 255));
LED_left.setPixelColor(i, Wheel_left(((i * 256 / LED_left.numPixels()) + j) & 255));
}
LED_left.show();
LED_right.show();
delay(wait);
}
}

uint32_t Wheel_right(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return LED_right.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else if(WheelPos < 170) {
WheelPos -= 85;
return LED_right.Color(0, WheelPos * 3, 255 - WheelPos * 3);
} else {
WheelPos -= 170;
return LED_right.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
}

uint32_t Wheel_left(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return LED_left.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else if(WheelPos < 170) {
WheelPos -= 85;
return LED_left.Color(0, WheelPos * 3, 255 - WheelPos * 3);
} else {
WheelPos -= 170;
return LED_left.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
}

Transmitter+Buttons


//simple Tx on pin D12
//Written By : Mohannad Rawashdeh
// 3:00pm , 13/6/2013
//http://www.genotronex.com/
//..................................
#include <VirtualWire.h>
char *controller;
#define button_right 5
#define button_left 6
int button_state;

void setup() {
pinMode(13,OUTPUT);
pinMode(button_right,INPUT_PULLUP);
pinMode(button_left,INPUT_PULLUP);

vw_set_ptt_inverted(true); //
vw_set_tx_pin(12);
vw_setup(4000);// speed of data transfer Kbps
Serial.begin(9600);
}

void loop(){
if(!digitalRead(button_right)){
controller="5";
vw_send((uint8_t *)controller, strlen(controller));
vw_wait_tx(); // Wait until the whole message is gone
digitalWrite(13,1);
Serial.println("Right!");
delay(500);
}else if(!digitalRead(button_left)){
controller="6";
vw_send((uint8_t *)controller, strlen(controller));
vw_wait_tx(); // Wait until the whole message is gone
digitalWrite(13,0);
Serial.println("Left!");
delay(500);
}
}

I tried to use Interrupt for RF module receiver but didn’t succeed. I could google some codes but they seemed to require quite long time to understand them but I didn’t have time for it. So instead I put a for-loop that would hear the signal. I tried several for-loop logic and found one that works pretty well but the problem was that RF module itself was quite unstable.

20150326_194832Here is a demonstration video:

Conclusion

I wanted to go wearable, well that was the whole point of this project, but unfortunately I couldn’t find a battery pack that could power the nano in the lab. Of course I could try it tomorrow but I have to help my Finnish family moving to a new house tomorrow and I have lots of other more important stuff to do.  Maybe one day when I have friends to work together in this, I will come back to it but not tomorrow. For now I’m “done” with this project.
Edit: I just can’t let my project be half done. I’m coming back next week after Easter!

P.S. – If you are broke or if you want to improve your soldering skill go ahead and buy these “raw-LEDs”. Otherwise just buy LED strips that are already connected. It’s very time consuming and tiring.

P.S. – Shooooot, I forgot to film in HD! 😦

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: