Have You Ever Seen This Before?!

I would be willing to bet not.

 

There are times when the “pre-fab” just won’t come close to cutting it. There are times when you want something different, something better then the next guy.

That is exactly the case with this client. He told me “Make it one of a kind”.

To help meet the request of my client, I decided to pull out one of my favorite tools in my toolbox, an Arduino. For those who don’t know, an Arduino is an open-source platform that is used in building electronic projects. It consists of the psychical circuit board it self, as well as the software IDE (Integrated Development Environment), which is a program that can run on almost any computer and is used to upload computer code to the micro controller (physical circuit board). Arduinos have inputs and outputs that can be used for an unlimited amount of applications.

It all sounds very complicated, and you may be thinking, why would I need an Arduino to control some lights? Don’t they make RGB controllers?

Why yes, they do. However, the lights used in this particular application are called NeoPixels, which are not your standard RGB LED lights. They operate on data and frequency, where standard common anode RGBs are controlled with PWM(Pulse Width Modulation) basically, they are controlled by the ground applied to the Red, Blue, or Green “Wire”.

The benefit of operating on data vs PWM, is that you can control each LED module independently. For example, if I have a standard RGB strip and I supply the positive lead with 12V and the Red wire with ground the entire strip turns Red. NeoPixels operate on a completely different spectrum.  They require data communication and have their own driver built into each LED.

The black piece in the middle is the driver built into each LED.

However, NeoPixels only have 3 wires, Positive,Negative, and Data. Even still, there are specialty controllers that can meet basic needs of NeoPixels. BUT this client wanted a very specific set of flash patterns and color codes that “off the shelf” controllers would not be able to meet.

An example of an Arduino connected to a NeoPixel Strip. The green is the data wire.

Therefore, by using an Arduino, I was able to sit down with the client and go over the flash patterns and make changes on the fly. If he wanted the pattern to be faster, slower, a different direction, or whatever he could thin of, it was entirely do able.

You may be thinking, man I just want a blue accent light, this is way to much.

To that I would say, there is nothing wrong with wanting something a bit less complex. This was a very advanced installation that no local shop would be able to complete for you. Most people will not be interested in going this route. However, some people are unaware of the possibilities, and that is the point of this post. To help show interested individuals what COULD be done.

Alright, now that you hopefully have a little better understanding of some of the parts used in the install, lets move forward.

So first thing first, I decided to start on the Arduino part of things.

Arduino Example

You can see here the 3 Wires for the NeoPixels, Red (Power), Black (Ground), and Green (Data). The two black wires connect to a momentary toggle switch which tells the Arduino to change patterns

Once the basic foundation of the Arduino was completed, I decided to treat the client to a little sneak peak of what he would more so be interested in.

Enter Spray Guns!

Since his bike is orange, I decided to go all out on the theme. If you look close you can see that bolt to the left of the bulb fitment area. That it was the pods will attach to down the road.

Once I was satisfied with they way things were looking, I decided its time to start the wiring.

Don’t guess!

I wanted the headlights to operate just like the factory. I hooked a meter to the factory headlight bulb plug to find which wire was the high beam and which was the low.

What size fuse and wire should I use?

I would never recommend guessing on wire size and fuse rating. Even if the manufacture has a spec sheet available, why not triple check and test for your self. As you can see these pods draw 1.61 Amps at 12 Volts. That is a pretty low current draw, factory wiring COULD handle that. But, that would be the easy way out. I would rather take a few extra steps to know that everything exceeds standard safety ratings. So I designed a relay circuit that would send power from the battery (fused with 3A fuse) whenever the headlight switch was turned on.

Right Power, Right Now

The Arduino Nano I used requires 3.3v-12v to operate. As you may know, voltage fluctuates alot in automotive applications, and that is not good for sensitive electronics, such as micro controllers and computers. The NeoPixels also need 5v to operate at full capacity. So It makes sense to run 5v to both the Arduino, and the NeoPixels. In order to do that, I needed a converter. And in order to make the voltage more stable, I used a 1000uf capacitor. I added a good bit of 3M “waterproof tape self-fusing” tape to help protect against the elements. I took this picture before I loaded it down with the tape, but this is a small example of the tape for reference.

Don’t forget about the Arduino!

The mini USB you see (that rhymed) is where you can not only upload the code, but also power the Arduino. I would recommend only powering from USB while testing.

Finished product looks pretty good if you ask me.

But more importantly what do YOU think?

 

 

For those interested in the code used, I will paste excerpt below.

[code lang=”c”]
#include "FastLED.h"
#include
#define NUM_LEDS 17
CRGB leds[NUM_LEDS];
#define PIN 6

#define BUTTON 3
byte selectedEffect = 0;

void setup()
{ // FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
LEDS.setBrightness(100);
digitalWrite (BUTTON, HIGH); // internal pull-up resistor
delay(20);
attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
//setAll(255, 75, 0);
}

void loop() {
EEPROM.get(0, selectedEffect);

if (selectedEffect > 51) {
selectedEffect = 0;
EEPROM.put(0, 0);
}

switch (selectedEffect) {

case 0 : {
// Off
colorWipe(0, 0, 0, 50) ;
break;
}

case 1 : {

// meteorRain – Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay
//colorWipe(255,255,255, 50);
// setAll(255,80,0);
meteorRain(255, 255, 255, 25, 40, false, 10);

break;
}
case 2 : {
setAll(0, 0, 0); // Off
break;
}

case 3 : {
setAll(255, 255, 255); // White
break;
}

case 4 : {
setAll(0, 0, 0); //Off
break;
}
case 5 : {
setAll(0, 0, 255);//blue
break;
}
case 6 : {
setAll(0, 0, 0); //Off
break;
}

case 7 : {
meteorRain(0, 0, 255, 25, 45, false, 10);
break;
}
case 8 : {
setAll(0, 0, 0); //Off
break;
}

void changeEffect() {
if (digitalRead (BUTTON) == HIGH) {
selectedEffect++;
EEPROM.put(0, selectedEffect);
asm volatile (" jmp 0");
}
}

// *************************
// ** LEDEffect Functions **
// *************************

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
for (uint16_t i = 0; i < NUM_LEDS; i++) {
setPixel(i, red, green, blue);
showStrip();
delay(SpeedDelay);
}
}

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
setAll(0, 0, 0);

for (int i = 0; i < NUM_LEDS + NUM_LEDS; i++) {

// fade brightness all LEDs one step
for (int j = 0; j < NUM_LEDS; j++) { if ( (!meteorRandomDecay) || (random(10) > 5) ) {
fadeToBlack(j, meteorTrailDecay );
}
}

// draw meteor
for (int j = 0; j < meteorSize; j++) {
if ( ( i – j < NUM_LEDS) && (i – j >= 0) ) {
setPixel(i – j, red, green, blue);
}
}

showStrip();
delay(30);
}
}

// used by meteorrain
void fadeToBlack(int ledNo, byte fadeValue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
uint32_t oldColor;
uint8_t r, g, b;
int value;

oldColor = strip.getPixelColor(ledNo);
r = (oldColor & 0x00ff0000UL) >> 16;
g = (oldColor & 0x0000ff00UL) >> 8;
b = (oldColor & 0x000000ffUL);

r = (r <= 10) ? 0 : (int) r – (r * fadeValue / 256);
g = (g <= 10) ? 0 : (int) g – (g * fadeValue / 256);
b = (b <= 10) ? 0 : (int) b – (b * fadeValue / 256);

strip.setPixelColor(ledNo, r, g, b);
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds[ledNo].fadeToBlackBy( fadeValue );
#endif
}
[/code]

The entire file is available for download, hopefully to save the next guy some trouble! Click Here to download it. I had to save it as a .txt file because the company I host with will not allow the Arduino native .ino format on their servers.