DIY Givi V56 Motorcycle Topbox Light Kit With Integrated Signals

3,709

32

26

Introduction: DIY Givi V56 Motorcycle Topbox Light Kit With Integrated Signals

About: I'm a jack of all trades type person getting involved in a lot of things. Big passions in life are building, flying, and the family.

As a motorcycle rider, I'm all too familiar with being treated like I'm invisible on the road. One thing I always add to my bikes is a top box which usually has an integrated light. I recently upgraded to a new bike and bought the Givi V56 Monokey box since it had lots of space for items. This box has a spot for a factory light kit which consists of two strips of LEDs for each side. The problem is this kit is about $70 and only does brakes. There is an aftermarket kit that probably does similar things and might be a bit easier to install, but your price goes up to $150. Being a resourceful person and looking for an excuse to try out the addressable LED strips, I decided to make an integrated system that not only would have brake lights, but running lights (on whenever moving), turn signals, and hazard lights. Just for the heck of it, I even added a startup sequence.... because I could. Note that this took a lot of work to do though I had a lot of things to figure out. Despite the work, I'm rather happy with how this turned out. Hopefully this ends up being useful to someone else.

The basic operation of how this system works is the Arduino unit looks for signals on the pins: brake light, left turn light, and right turn light. In order to read the 12 volt signal from the motorcycle, I used optoisolators to convert the 12V signal to a 5V signal that Arduino can read. The code then waits for one of these signals then outputs the commands to the LED strip using the FastLED library. That's the basics, now to get into the details.

Supplies:

These are the things that I used because for the most part I already had them lying around. Obviously, they can be exchanged out as needed:

  1. Arduino - I used a nano for size considerations but you can use whatever you feel like as long as you have five pins to use.
  2. 5V regulator - I used an L7805CV that was capable of 1.5 amps. This project will use 0.72 amps for the LEDs plus the power for the nano, so 1.5 works great for this project.
  3. Capacitors - you will need one 0.33 uF and one 0.1 uF for the voltage regulator to operate properly.
  4. 3x optoisolators - to do the signal conversion from 12V to 5V. I used PC817X type which only have four pins which is all we need.
  5. Resistors - you will need two types, three of each type. The first needs to be enough to reduce the current through the optoisolator IR LED. You will need at least 600 ohm, but 700 would be a better idea to handle changing voltages on the motorcycle. The other needs to be somewhere between 10k and 20k for a quick signal on the other side of the optoisolator.
  6. Prototype board - I had some that were small enough to fit inside a small project box with a slight amount of trimming.
  7. Project box - big enough to fit the components, but small enough to be easy to fit.
  8. Wire - I used Cat 6 ethernet wire because I had a lot of it sitting around. This has eight wires all color coded which helped with all the different connections and was a large enough gauge to handle the current draws.
  9. Plugs - anywhere you want the system to be easily removable. I used a waterproof plug to allow the top box to be removed and to handle any rain or water that gets on it. I also needed smaller plugs for the LED strips so I didn't have to drill large holes.
  10. Zip ties and zip tie adhesive mounts to hold everything in place.
  11. Shrink wrap to tidy up the connections.

Step 1: Building the Circuit

Obviously, if you're following my build, you won't have to go through the amount of testing I did. First thing I did was to make sure my code worked and I could properly get a signal from the optoisolators as well as properly control the LED strips. It took a moment to figure out how best to attach the signal pins to the isolators but through trial and error I found the right orientation. I just used a standard prototype board since I was only building one and figuring out a trace pattern would have taken more time than it was worth. The top part of the circuit board looks great, but the bottom does look like a bit of a mess, but at least it's functional.

The basic design starts with inputting the 12V power from a switched source (a wire that is only on when the motorcycle is on). A wiring diagram can really help to find this wire. This is fed into one side of the voltage regulator. A 0.33 uF capacitor ties this input to the ground on the voltage regulator which then feeds back to the ground on the motorcycle. The output of the voltage regulator will have a 0.1uF capacitor tied into it to ground. These capacitors help to smooth out the voltage from the regulator. If you can't find them in the picture of the circuit board, they are underneath the voltage regulator. From there, the 5V line goes to the Vin on the Arduino, to the power pin that will feed the LED strips, and two the Source side of the optoisolator that will feed into the Arduino pins providing the needed 5V signal.

As for the optoisolators, there are two sides: one with an IR LED and the other with a transistor with and IR detector. We want to use the IR LED side to measure the 12V signal. Since the LED has a forward voltage of 1.2V, we need a current limiting resistor in series. 12V - 1.2V = 10.8V and to run the LED at 18 mA (I always like to run less than 20 mA for lifetime reasons), you will need a resistor of R = 10.8V/0.018A = 600 ohm. Voltages on vehicles also tend to run higher, potentially up to 14V, so it's better to plan for that, which is about 710 ohm, though 700 would be more than reasonable. The output for the LED side then feeds back to ground. For the output side of the optoisolator, the input will use the 5V signal from the regulator then the output will connect to another resistor before going to ground. This resistor just needs to be around 10k - 20k ohm, at least that's what my datasheet showed. This will give a quick signal measurement since we're not dealing with a noisy environment. The output to the Arduino pin will come off between the resistor and the output of the optoisolator so that when the signal is off the pin is low and when the signal is on the pin is high.

The LED strip lights have three wires associated with them: Power, ground, and data. Power needs to be 5V. This project uses 12 LEDs total (though I have more LEDS on the strips but I'm only using every third LED) and each takes 60mA when white light is used at full brightness. This gives a total of 720 mA. We're well within the output power for the voltage regulator, so we're good. Just make sure that the wire is a large enough gauge to handle the power, I used 24 gauge Cat 6 ethernet wire. Ethernet wire was something that I had sitting around and it has 8 color coded wires so it worked out well for this project. The only wires that then need to go to the topbox itself is the power and ground (which both get split between the strips) and two data lines (one for each strip).

The rest of the wiring is connecting to the pins on the arduino and feeding it power. The pins that were used for this project were the following:

  1. Vin - connected to 5V
  2. Gnd - connected to ground
  3. Pin2 - connected to Left strip data line
  4. Pin3 - connected to Right strip data line
  5. Pin4 - connected to Brake signal from the optoisolator
  6. Pin5 - connected to Left turn signal from the optoisolator
  7. Pin6 - connected to Right turn signal from the optoisolator

Step 2: Wiring and Installing

Once the circuit is built, the time comes to actually wire this into place. Using your wiring schematic for your bike, you will need to locate the following:

  • Switched power supply
  • Ground
  • Brake Signal In
  • Left Turn Signal In
  • Right Turn Signal In

For mine, there was a single plug that had all of these on it, so I just used that. With enough time, I might have been able to find the same plug style and just make a plug in module, but I didn't, so I just removed the insulation in places and soldered the new wire to it. I used plugs on these spliced connections so that I could remove the rest should I ever need to in the future. From there I placed the Arduino, which is now in a sealed project box, under the seat where I attached it. The output cable then runs along the rack frame to a waterproof plug, then enters the box and runs along the back to the lid where it splits for each side. The wires run along the inside of the lid to the point where the connections for the LEDs are at. The wire is help in place using zip ties attached to Outdoor grade zip tie mounts with an adhesive backing. You can find these in the cable installation section at a home improvement store

I used two mini JST plugs on the LED strips because I needed a plug small enough to go through a hole of minimum diameter and because I wanted to make sure there was enough wire to handle the current requirements. Again, it may have been overkill and I didn't have any small plugs with three wires handy. The hole in the box for the light strip wires to pass through were sealed up to keep water out. As for positioning the LED strips, because there is a slight mismatch in spacing (there was about 1 - 1.5 mm difference in spacing between the holes in the reflector and the LEDs) I positioned them so that they would split the difference between the LED and the hole as much as possible. I then used hot glue to tack them in place and sealant to fully seal the area. The LED strips themselves are waterproof, so no issue if they get wet. Although it seems like a lot to install, this makes the system easier to remove in the future or replace parts are needed because it could happen.

Step 3: The Code

My source code should be at the beginning of this Instructable. I always comment my code heavily so it's easier to understand later on. Disclaimer: I'm not a professional code writer. The code was written in a method that was easier to get going first and some improvements were made, but I know it could be more refined. I'm also using a heavy amount of the delay() function for timing which is not as ideal. However, the signals that the unit is receiving are not fast signals in comparison, so I still felt justified to keep them over using something like millis(). I'm also a very busy father and husband so spending time to improve something that will ultimately not change the function isn't high on the list.

For this project, only one library is required which is the FastLED library. This has all the code for controlling the WS2811/WS2812B type LED strips. From there, I'll cover the basic functions that will be used.

The first other than the standard definitions is to declare your two strips. You will use the following code for each strip:

FastLED.addLeds<WS2812B, 2,RGB>(leds[0], NUM_LEDS);

This line of code sets up Pin 2 defines this strip as strip 0 with the number of LEDs defined by the constant NUM_LEDS, which in my case is set to 16. To define the second strip, the 2 will become 3 (for pin3) and the strip will be labeled strip 1.

The next line that will be important is color definition.

leds[0][1] = Color_high CRGB(r,g,b);

This line of code is used though in different looks (most of my use a constant). Basically, this code sends a value to each of the LED channels (red, green, blue) that defines each brightness. The brightness value can be defined by a number 0 - 255. By changing the level of brightness for each channel, you can define different colors. For this project, I want a white color to keep the light as bright as possible. So the only changes I do is to set the brightness level the same across all three channels.

The next set of code is used for individually lighting each light. Note that for each strip, each LED has an address that starts at 0 for the one closest to the data line connection all the way up to the highest number LED you have minus 1. Example, these are 16 LED strips, so the highest is 16 - 1 = 15. The reason for this is because the first LED is labeled 0.

for (int i = NUM_LEDS-1; i > -1; i = i - 3) {    // This will change the light for every third LED going from the last to first.<br>    leds[0][i] = Color_low;                      // Set strip 0 LED color to the chosen color.
    leds[1][i] = Color_low;                      // Set strip 1 LED color to the chosen color.
    FastLED.show();                              // Show the set colors.  
    leds[0][i] = CRGB::Black;                    // Turn off set color in prep for next color.  
    leds[1][i] = CRGB::Black;
    delay(150);
  }
  FastLED.show();				 // Show the set colors.  

The way this code works is that a variable (i) is used within a for loop as the LED address which is then referenced to the full number of LEDs (NUM_LEDS). The reason for this is that I want the lights to start at the end of the strip rather than the beginning. The setting is output to both strips (leds[0] and leds[1]) then a command to show the change is issued. After that this light is turned off (CRGB::Black) and the next light is lit. The Black reference is a specific color in the FastLED library so I don't have to issue 0,0,0 for each channel though they would do the same thing. The For loop advances 3 LEDs at a time (i = i-3) since I'm only using every other LED. By the end of this loop, the light sequence will go from one LED to the next with only one lit per strip, sort of a Knight Rider effect. If you want to keep each light lit so that the bar builds, you would just remove the lines that turn the LEDs off which happens in the next set of code in the program.

for (int i = 0; i < dim; i++) {                 // Quickly fade lights to running light level.  <br>    rt = rt + 1;
    gt = gt + 1;
    bt = bt + 1;
    for (int i = 9; i < NUM_LEDS; i = i +3) {     // This will light up the last three lights for the position light.  
      leds[0][i] = CRGB( rt, gt, bt);             // Set strip 0 LED color to the chosen color.
      leds[1][i] = CRGB( rt, gt, bt);             // Set strip 1 LED color to the chosen color.
    }
    FastLED.show(); 
    delay(3);
  }

The last example of code that I use for the LEDs is a fade loop. Here, I use temporary slots for the brightness for each channel (rt, gt, bt) and increment them by 1 with a delay between each showing to achieve the appearance I want. Also note that this code is only changing the last three LEDs as this is fading in the running lights so i starts at 9 rather than 0.

The rest of the LED code is iterations of these. Everything else is focused around looking for a signal on the three different wires. The Loop() area of the code looks for brake lights, which it will flash once before staying on (this is adjustable if desired) or looking for turn signals. For this code, because I couldn't assume the left and right turn lights would turn on exactly the same time for hazards, I have the code look for either one first, then after a small delay I check to see if both are on indicating the hazard lights are on. The one tricky part I had was turn signals because the light will go out for some period so how do I tell the difference between the signal still on but in the off period and a cancelled signal? What I came up with was implementing a delay loop that is set to continue longer than the delay between signal flashes. If the turn signal is still on, then the signal loop will continue. If the signal does not come back on when the delay ends, then it goes back to the start of the loop(). To adjust the length of the delay, change the number for the constant lightDelay remembering for every 1 in lightDelay the delay changes by 100ms.

while (digitalRead(leftTurn) == LOW) {    for(int i = 0; i < lightDelay; i++) {
      leftTurnCheck();
      if(digitalRead(leftTurn) == HIGH) {
        leftTurnLight();
      }
    delay(100);					   
    }
    for (int i = 0; i < NUM_LEDS; i = i +3) {       // This will change the light for every third LED going from the last to first.
      leds[0][i] = CRGB( 0, 0, 0);                  // Set strip 0 LED color to the chosen color.
    }
    for (int i = 9; i < NUM_LEDS; i = i +3) {       // This will set up the running lights which only use the last three.  
      leds[0][i] = Color_low;                       // Set strip 0 LED color to the chosen color.
    }
    FastLED.show();                                 // Output settings
    return;                                         // Once turn signal is no longer on, go back to loop.
  } 

Hopefully the rest of the code is self explanatory. It's just a repeating set of checking and acting upon signals.

Step 4: Results

The amazing part was that this system worked the first time I wired it to the bike. Now, to be fair I heavily tested it on the bench prior to this, but I still expected to have an issue or an adjustment. Turns out that I didn't need to make any adjustments to the code as well as the connections. As you can see in the video, the system goes though the startup sequence (which you don't have to have), then defaults into running lights. After that it looks for the brakes in which case it will light up all LEDs to full brightness and flash them once before remaining on till the brakes are released. When a turn signal is used, I made a scrolling effect for the side that the turn is indicated and the other side will be either running lights or brake light if on. Hazard lights will just blink in time with the other lights.

Hopefully with these additional lights, I will be more visible to other people. At the very least, it's a nice addition to make my box stand out a bit more than others while providing utility. I hope this project is useful to someone else as well even if they are not working with a motorcycle top box lighting. Thanks!

1 Person Made This Project!

Recommendations

  • The 1000th Contest

    The 1000th Contest
  • Battery Powered Contest

    Battery Powered Contest
  • Hand Tools Only Challenge

    Hand Tools Only Challenge

26 Discussions

0
Duadua
Duadua

Question 22 days ago on Introduction

Hi there, awesome project and I'm keen to make, with some minor amendments to fit my Givi E52 top box. By no means have a got the knowledge you have and when buying some of the components, I wasn't able to exactly match up the resistors you mentioned. My local hobby electronic store (NZ) supplied me with what I guess is close, but if I could be a pain, could I ask: what are the specific resistor colour bands for your set-up? Sincere thanks.

0
geckostudios
geckostudios

Answer 21 days ago

The resistors aren't super critical. You just need them in about the right area. For the smaller resistor, you want something around 600 to 800 ohms. I would not go with a lower value than 600 to avoid burning out the LED. For the larger resistor, you want around 10,000 - 20,000 ohms. You can look up a color code chart to see what these correspond to. I don't know them off the top of my head. Otherwise, if the values are close you should be fine.

0
Duadua
Duadua

Reply 15 days ago

Thanks so much for the advice. Turns out the resistors I bought were within the ranges you mentioned. I have to say it's been my first dabble into the Arduino world and just with this small project, and despite a few small mistakes, I think I've learned so much from you. The detail you've gone into has been super helpful. I thought I'd made a mistake with the indicator sequence until I re-read your code comment about lighting up, "....strip once". I made an assumption that on my test bed, if I kept the power on, it would keep looping, but now I understand it's looking for the distinct power 'pulse' (for want of a better word) to repeat the sequence - I hope I've got that right? One last question though if I may; the left, right and brake power entering the Optoisolator (referencing X1, X2, X3 on your schematic) is 12V - have I got that right?

0
geckostudios
geckostudios

Reply 14 days ago

Glad it's been a good learning project. Yes, the voltage coming in should be 12V (same as the battery your motorcycle uses). The optoisolators make it easy to convert from 12 volts to 5 volts while isolating the two electrical systems more. However, that's why the resistors have to be large enough to reduce the current through the LED inside the optoisolator so it doesn't burn out.

0
jonvejn79
jonvejn79

2 months ago

Awesome solution. Great Job. I was looking to put something like this on my bmw 1200 gs adv and based on your instructions and a little addition on the circuit (relay 12v and condensator on stop light signal) it works. But I put a little different code because I have clear glass on the box so I want to have red running and stop light and yellow signal and hazard lights. I want to use your program but the lights are always white. Where in your program do I change so that running lights are red? I will then figure out the signal lights later.
I changed bellow but it does not work:
int rt = 255;
int gt = 0;
int bt = 0;

0
geckostudios
geckostudios

Reply 2 months ago

The color is defined at the beginning of the code. I wrote the program to have a single color with two brightness settings. If you want different colors, you will have take out my code that refers to the defined color and just write in your own.

At the start of the code, there are two levels defining the brightness values:
#define bright 255 // Define the level for bright
#define dim 80 // Define the level for dim

Then after that I create the variables that will use these values. If you wanted just Red, then I would set g, b, g2, and b2 to zero to make red only (I added notes by them):
// The following code uses white color as that should be the brightest. It could be changed to other colors as well if needed.
// Define Full brightness, max 255
#define r bright
#define g bright // Set to zero
#define b bright // Set to zero
// Define low brightness
#define r2 dim
#define g2 dim // Set to zero
#define b2 dim // Set to zero
#define Color_high CRGB(r,g,b) // Define high brightness state
#define Color_low CRGB(r2,g2,b2) // Define dim brightness state

Hope that helps.

0
jonvejn79
jonvejn79

Reply 2 months ago

Thanks, now I understand the code more.

0
JohnJeiJei
JohnJeiJei

3 months ago

Awesome job, brother! I already bought all components i didn't yet have, except the jst connectors. Which brings me to my question: why are there two connectors for each led strip? I really don't see anything to explain that, in the text, in the images, or in the diagram.

A photo of the entire thing laid out on a table would have done wonders, but I'd be more than happy with just an explanation or something.

Also: how did you test it on the bench? how did you emulate in code turning the signals on or off, or braking or whatever? Did you attach (temporarily) buttons on the signal input line, to turn the 12v on or off, or what?

I'm really loving this (if you can't tell), and i'm looking forward to starting to work on it! As soon as the electronic part is done, i'll start messing with the code (i want to design my own start up sequence, and maybe even a different light up pattern for signals or braking or whatever) - this is the most fun part!

Cheers,
John

1
geckostudios
geckostudios

Reply 3 months ago

The reason I had two connectors per line was because I was concerned the current draw on those small wires would be too much and wanted extra current capacity. It might have been fine but I decided to just be safe. Again, I used what I had on hand. A single connector that has a larger gauge wire would be just fine. For testing on the bench, I just connected a power wire by hand to the contact as needed to simulate the tests. I had a small 12V battery that I was using to test the system. Lots of ways to do things though. Hope that helps.

0
JohnJeiJei
JohnJeiJei

Reply 3 months ago

That helped immensely, THANK YOU!
Now, to get the kid to bed, so that i have some time to play! :D

0
JohnJeiJei
JohnJeiJei

Reply 3 months ago

Too tired to solder the led strips tonight (it's 1am),but if nothing comes up, tomorrow I'll be doing the first tests (after double checking everything). My leds are spaced differently, so I'll have to mess with the code a bit. I don't even have a topcase yet, so I'll have plenty of time to play with them.

In your diagram, the optoisolators are mirrored, and it confused me for a bit, but i believe i got it right eventually. As previously mentioned, i'll double check tomorrow.

Question: should I cut the power to the breadboard when uploading the code? Or at least disconnect the Vin?

2020-07-29 00.55.25.jpg
1
geckostudios
geckostudios

Reply 3 months ago

The optoisolators should be setup so the 12 V is on the LED side with the appropriate resistor then the 5V side on the transistor side. I would disconnect the Vin when programming so there isn't any unintentional power conflicts.

0
JohnJeiJei
JohnJeiJei

Reply 3 months ago

You mean the 6-700ohm resistor should be on the anode, 12V side (e.g. brake input), and the 20k resistor should be on the 5V Vcc from the L7805? In the wiring diagram, you placed the 6-700R on the cathode, and the 20k on the emitter, towards ground. I've added a diagram with the "redone" pc817, please tell me if this OR the original diagram is correct, I'd hate to start testing and blow something up.. :

PC817.png
1
geckostudios
geckostudios

Reply 2 months ago

My schematic is how I put it together. I can't claim to have followed all BKMs as I'm not a professional electronic circuit designer. However, with those two parts I don't think it will matter which side you put the resistor from a function standpoint. They are there just to limit the current flow. Would be worse to leave them out than to put them on different sides. Go with whichever method you like more.

0
JohnJeiJei
JohnJeiJei

Reply 2 months ago

Thanks for your patience, man! I got it working, i need to work the code a lot more - my led strips are 10 leds each, so i have to go through it to adapt it. I changed the i + 3's and -3's to 2's, but that's just to see if everything lights up. Well, it does, but there's no repeating, and it stays lit on high, so it's far from done..

However, the L7805CV is BOILING.. do you think this is due to the errors in code, that maybe confuses the nano into shooting more power into each led, or is that a result of some bad wiring? Or is it as simple as - there's 20 leds lit (not my intention), compared to the 12 you were running.. maybe it's a combination of all, and they're overloading the voltage regulator..

Edit, six hours later: i limited the leds to 3 per strip, and it still gets just as hot (i'm powering from a 12V 3A power adapter - as far as i know, increased amperage should not influence anything, so it shouldn't get any hotter than that when powered from the 14,3V 12A battery of my bike (charging voltage).. The L78 seems to be working fine otherwise, and even measured it separately - it puts out constant 4.99V (and doesn't get hot outside the circuit, of course). Still, i'd appreciate a second opinion.

2nd edit: read up on it, and it's apparently the way the L78 works.. i need a serious heat sink for it, since the voltage difference and the current draw are pretty high, which means the L78 is eating up several watts..

1
geckostudios
geckostudios

Reply 2 months ago

I was going to say to calculate the current draw. I made my light strip skip lights so that I would keep current draw down. A heat sink certainly helps, but you may need a second Voltage regulator to supply power to the LEDs (or maybe one for each if they're drawing a lot). I usually try to stay below 80% of the regulator's output.

0
JohnJeiJei
JohnJeiJei

Reply 2 months ago

Solved the heating problem: replaced the L78 for a LM2596.
Not the prettiest thing, but it works.

Bonus: test setup. Don't have uni diodes to "fake" hazzards, so i just have to press both turn signal buttons at the same time, but it does the job.

All that's left now is to buy a topcase and mount them..


index.jpg
0
geckostudios
geckostudios

Reply 2 months ago

Glad you got it working!

0
Jojoned
Jojoned

11 months ago

I really want to do this project. happy to find it . thanks alot for the great job. But i want to ask a question, i am using only 6led (ws2812) for this proect.Didn't find 16 led strip.
where can i need to change on the code for 6 leds.

Thanks.

0
geckostudios
geckostudios

Reply 10 months ago

Thank you for the comments! I had to use the fine spacing because the box I had had a specific spacing to match. If you are able to match the lights 1 for 1, then it will simplify the code. The main thing to change is in the for statements you will want to remove the " + 3" from the i, for instance in {for (int i = 0; i < NUM_LEDS; i = i +3)} you would rewrite it to be {for (int i = 0; i < NUM_LEDS; i = i )}. The other change would be at the beginning for the number of LEDs you're using (6) and any other reference to a specific starting LED or stopping LED. It shouldn't take long but might take a few trial and error. Hope that helps.