-----
OBJECTIVE: A high bright LED for installation on a Kawasaki KLR650 motorcycle with six programmable modes:
- OFF
- 33% bright
- 50% bright
- 100% (full) bright
- "Breathing" mode
- STROBE mode
To keep the project simple, an Ardunio Nano is used to control the Gate Voltage (Vgs) of a MOSFET. When Vgs is HIGH the MOSFET switches on and the high bright LED turns on. By using Pulse Width Modulation (PWM) on the Arduino the brightness of the high bright LED can be easily controlled.
-----
You will need the parts in the schematic. All are readily available from Amazon or a host of electronic parts distributors. Of course, the 12VDC power source is provided by the vehicle.
On the bench the rig will look and function something like this:
The schematic leaves out some details that could be helpful. To control the MODE selection and the STROBE effect we used a handlebar mounted switch. I also drilled a small hole to mount the STATUS LED into the handlebar switch. With coded flashes, the STATUS LED lets the rider know the current mode of the rig. Pressing the GREEN button selects the next mode. Move the turn signal switch to "R" to turn on the STROBE effect. The image below provides some real world connection details. If you get the same handlebar switch we recommend buzzing out the wires first to verify them because the unit came with no diagram and low cost manufactures often change these details.
----
After you use the Arduino IDE to download the source code provided below into your Ardunio Nano you will need to mount to high bright LED. We got a mounting bracket from eBay. In the end it came out pretty nice.
-----
Here is a video of the rig running through all the modes. The quick strobe at the beginning is a wake up self test. The high bright LED swamps out the camera light sensor and doesn't provide a good indication of the actual effect. One note: It turns out Apple has a patent on the Breathing LED pattern (well, for a sleep indicator anyway). Use the "breathing LED" portion of the code with caution or, I guess, risk a cease and desist order.
Here is the Arduino source code for the rig. Good luck!
//------------------------------------------------------------------------
/*
KLR650 Aux LED Driver
July 2019
WhiskeyTangoHotel.Com
Ardunio Nano (should work with other Arduinos)
Program controls a IRF510 MOSFET to drive a High Bright LED Array
(I recommend a heat sink on the MOSFET, but it should be fine without it)
A button switch selects between modes
A switch sets the LED to fast strobe mode
*/
// MODES:
// 0 = OFF, Bright Examples (vars set below):
// 1 = Low% Bright
// 2 = Higher% Bright
// 3 = FULL BRIGHT
// 4 = Breath
int Number_of_Modes = 4; // Needed for program control.
int LED_Mode = 1; // LED_Mode sets the startup condition and is changed with button pushes in the main loop.
int Status_LED = 3; // PWM output pin for the LED status light.
int FET_Drive = 5; // PWM output pin to drive the gate on the MOSFET.
int mode_buttonPin = 4; // Mode changing push button (wired to GND via 10K)
int strobe_buttonPin = 8; // Mode changing push button (wired to GND via 10K)
boolean buttonState = LOW; // for the mode_ and strobe_ detect
// Percent brightness of the 3 modes. Example: 35% = .35, 100% = 1.00
// LED_Mode = 0 is OFF
float MODE1_Bright = .20;
float MODE2_Bright = .50;
// LED_Mode = 3 is FULL Bright: digitalWrite(Status_LED, 255); // 255 turns LED FULL BRIGHT
// LED_Mode = 4 is Breath
int Breath_Rate = 15; //Higher is faster
int Breath_Max_Bright = 170;
int Breath_Min_Bright = 20;
int Flash_delay = 50; // sets delay for strobe mode and self test (50 is a good start)
void setup()
{
// Serial commands are for debugging
//Serial.begin(9600);
//Serial.print(LED_Mode);
//Serial.println();
pinMode(Status_LED, OUTPUT); // sets the digital pins as output
pinMode(FET_Drive, OUTPUT);
pinMode(mode_buttonPin, INPUT); // initialize the mode pushbutton pin as an input. If HIGH change modes
pinMode(strobe_buttonPin, INPUT); // if HIGH quick stobe/flash mode
digitalWrite(Status_LED, 0); // 0 turns the LED OFF
digitalWrite(FET_Drive, 0);
// Self test loop. Quick flash the status and high bright LED
for (int i = 0; i <= 4; i++) {
digitalWrite(Status_LED, 255); // 255 turns LED FULL BRIGHT
digitalWrite(FET_Drive, 255);
delay(Flash_delay);
digitalWrite(Status_LED, 0); // 0 turns the LED OFF
digitalWrite(FET_Drive, 0);
delay(Flash_delay);
} // endSelf Test Loop
} //end Setup
void stobe_on_button () { // strobe/flash the LED when HIGH
int buttonState = digitalRead(strobe_buttonPin); // check if the pushbutton is pressed.
if (buttonState == HIGH) { // button is pressed, strobe the LEDs
Serial.println(buttonState);
digitalWrite(Status_LED, 255); // 255 turns LED FULL BRIGHT
digitalWrite(FET_Drive, 255);
delay(Flash_delay);
digitalWrite(Status_LED, 0); // 0 turns the LED OFF
digitalWrite(FET_Drive, 0);
delay(Flash_delay);
stobe_on_button (); // check to see if strobe button is still pressed HIGH
} // endif strobe_button HIGH
} // end of strobe_button function
void mode_change_button() { // function to dectect the mode_buttonPin press to change modes (increment the state machine)
int buttonState = digitalRead(mode_buttonPin); // check if the pushbutton is pressed.
if (buttonState == HIGH) { // button is pressed, advance to next LED_Mode
digitalWrite(Status_LED, 255); // 255 turns LED FULL BRIGHT
for (int x = 0; x < 25; x++) { // Quick flash the Status LED to confirm button press.
digitalWrite(Status_LED, !digitalRead(Status_LED)); // toggle state of the on board blue LED. Shows program is running
delay(100);
} // endfor quick toogle Blue LED
if (LED_Mode >= Number_of_Modes) { // reset state machine to zer0 to recycle LED_Modes
LED_Mode = 0;
}
else {
LED_Mode = LED_Mode + 1;
}
if (digitalRead(strobe_buttonPin) == HIGH) {
LED_Mode = 0; // this is a fast cycle to OFF. The flash button AND the mode button are HIGH
}
} // endif state_mode button pressed
} // end of mode_change_button function
void loop() {
//Serial.print(LED_Mode);
Serial.println(buttonState);
Serial.println();
// LED_Mode - OFF, no lights
if (LED_Mode == 0) {
analogWrite(Status_LED, 0); // 0 turns the LED OFF
analogWrite(FET_Drive, 0); // 0 turns the MOSFET
} // endif LED_Mode = 0
// LED_Mode - Percent Brightness
if (LED_Mode == 1) {
analogWrite(FET_Drive, (255 * MODE1_Bright)); // Percent Brightness = MODE1_Bright
for (int x = 0; x < LED_Mode; x++) { // Flash rate Status LED to match mode
digitalWrite(Status_LED, 255); // 255 turns LED FULL BRIGHT
delay(100); // endfor quick toogle Blue LED
digitalWrite(Status_LED, 0); // 0 turns LED OFF
delay(100); // endfor quick toogle Blue LED
} //for match Status_LED with mode
delay(600);
} // endif LED_Mode = 1
// LED_Mode - Percent Brightness
if (LED_Mode == 2) {
analogWrite(FET_Drive, (255 * MODE2_Bright)); // Percent Brightness = MODE2_Bright
for (int x = 0; x < LED_Mode; x++) { // Flash rate Status LED to match mode
digitalWrite(Status_LED, 255); // 255 turns LED FULL BRIGHT
delay(100); // endfor quick toogle Blue LED
digitalWrite(Status_LED, 0); // 0 turns LED OFF
delay(100); // endfor quick toogle Blue LED
} //for match Status_LED with mode
delay(600);
} // endif LED_Mode = 2
// LED_Mode - Full Brightness
if (LED_Mode == 3) {
digitalWrite(FET_Drive, 255); // FULL BRIGHT
for (int x = 0; x < LED_Mode; x++) { // Flash rate Status LED to match mode
digitalWrite(Status_LED, 255); // 255 turns LED FULL BRIGHT
delay(100); // endfor quick toogle Blue LED
digitalWrite(Status_LED, 0); // 0 turns LED OFF
delay(100); // endfor quick toogle Blue LED
} //for match Status_LED with mode
delay(600);
} // endif LED_Mode = 3
// LED_Mode - LED BREATHING
if (LED_Mode == 4) {
// Ramp up the brighness of the LED
for (int i = Breath_Min_Bright; i <= Breath_Max_Bright; i++) {
analogWrite(Status_LED, i);
analogWrite(FET_Drive, i);
float Breath_Delay = (exp(sin(i/2000.0*PI*10)) - 0.36787944)*108.0;
delay(Breath_Delay/Breath_Rate);
if (buttonState == HIGH) { // check if the pushbutton is pressed.
i = Breath_Max_Bright;
}
}
mode_change_button(); // check to see if mode_change button is pressed
stobe_on_button (); // check to see if strobe_button is pressed
// Ramp down the brightness of the LED
for (int i = Breath_Max_Bright; i >= Breath_Min_Bright; i--) {
analogWrite(Status_LED, i);
analogWrite(FET_Drive, i);
float Breath_Delay = (exp(sin(i/2000.0*PI*10)) - 0.36787944)*108.0;
delay(Breath_Delay/Breath_Rate);
if (buttonState == HIGH) { // check if the pushbutton is pressed.
i = Breath_Min_Bright;
}
}
} // endif LED_Mode 4
mode_change_button(); // check to see if mode_change button is pressed
stobe_on_button (); // check to see if strobe_button is pressed
}
-----