Customized My Bike's Indicator Light Using Attiny85

by alaminashik in Circuits > Gadgets

1292 Views, 17 Favorites, 0 Comments

Customized My Bike's Indicator Light Using Attiny85

Cover pic.jpg

I have always wanted to customize my bike's indicator light and add some cool effects. So, I bought an enclosure for the LED, made a custom bracket, designed a circuit programmed with ATTINY85, and attached it to the bike. Moreover, the size of the circuit is small enough to fit in any available space inside bike.

The device is connected to the power switch of the bike. So, the light turns on only when the bike starts using the switch.

The input is taken from the buttons at the front. Mainly it has three modes:

  1. When brake is pressed(bright red)
  2. when the left/right indicator is pressed(moving animation)
  3. when the emergency button is pressed(combined moving animation)

These three modes, accompanied by a starting animation, add beauty to the bike. It's been almost 4 months and it is still running smoothly.

In this project, I will share all the details, including code, testing, and implementation, with you guys.

Supplies

Materials that would be needed:

  • Metal enclosure - made from a local shop
  • 1 x Ws2812B led strip -LINK
  • 1 x ATTINY85 - LINK
  • 1 x LM7805 voltage regulator - LINK
  • 4 x 1k resistor - LINK
  • 3 x 2.2k resistor - LINK
  • 1 x 0.1uF capacitor - LINK
  • 1 x 0.33uF capacitor - LINK
  • 1 x Vero board - LINK
  • few heat shrink tube of different length- LINK
  • Glue gun and soldering Iron

Features

engine start.gif
stop button pressed.gif
right indicator gif.gif
emergency indicator gif.gif

It has a total of 4 different animations.

Theory

theory.png
  • The Led Strip

WS2812B LEDs have an IC built into the LED, which allows one-wire interface communication. This means that you can use one pin on your controller to power several LEDs. It usually contains three wires: VCC, GND, and data. A series of code controls each led making it easier to control.

Check this article by sdiplight.com to better understand its working principle. LINK

  • Microcontroller

I have used ATTINY85 for programming. It has 8Kb of flash storage so that it can store hundreds of lines of code. Its 8DIP package is pretty small, which is suitable for this project. I have used Arduino IDE to program the controller.

  • Voltage regulator

Since the microcontroller operates in the 2.7-5.5V range and consumes very little power, I opted to use L7805 to convert the battery's 12V to 5V DC. Additionally, I used a 12V Zener diode to counter the fluctuation in voltage that may occur.

Circuit Diagram

schematic_bb.jpg

I have done some preliminary research and came up with this schematic.

  • The buttons on the bike are common connected to the positive terminal of the battery. Thus in my diagram, the buttons are connected to the +12V
  • The L7805 regulator is used to convert the 12V battery to 5V output for the circuit to work.
  • 3 x 1k resistors are used with the switch to ensure LOW level when the button is not pressed. (when the button is pressed, the level goes to HIGH)

Note: the input of the strip is connected directly to the 12V terminal of the battery since the strip works at 12V. A Zener diode is connected to the battery to counter the fluctuation of voltage. However, it is always better to use a regulator like L7812 instead of a Zener diode for voltage regulation.

The Code

Adjust the code as you wish. Play with different codes to get your desired animation. Comments are added in each portion of the code.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif


int i = 0;


#define PIN        0          //strip input connected pin 0
#define NUMPIXELS  7          //number of led on the strip starting from 1 to 7(total 7)
#define left_but 3            //input switch
#define right_but 4           //input switch
#define stop 2                //input switch


Adafruit_NeoPixel strip(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); //defining varible strip
#define DELAYVAL 100           //delay time for each transition


void setup() {
 #if defined(__AVR_ATtiny85__) && (F_CPU == 8000000)   //frequency of internal IC
  clock_prescale_set(clock_div_1);
 #endif


  strip.begin();                //initiate strip


  pinMode(left_but, INPUT);
  pinMode(right_but, INPUT);
  pinMode(stop, INPUT);


//initial red animation
  for(i=2; i>=0; i--) {
    strip.setPixelColor(i, strip.Color(255, 0, 0));
    strip.setPixelColor(i+1, strip.Color(0, 0, 0));
    strip.setPixelColor(6-i, strip.Color(255, 0, 0));
    strip.setPixelColor(6-i-1, strip.Color(0, 0, 0));
    strip.show();
    delay(DELAYVAL);
  }
  for(i=0; i<=2; i++) {
    strip.setPixelColor(i, strip.Color(255, 0, 0));
    strip.setPixelColor(i-1, strip.Color(0, 0, 0));
    strip.setPixelColor(6-i, strip.Color(255, 0, 0));
    strip.setPixelColor(6-i+1, strip.Color(0, 0, 0));
    strip.show();
    delay(DELAYVAL);
  }


  for(i=0; i<200; i=i+10) {
    strip.fill(strip.Color(i,0,0), 0, 7); //color, first led, count led
    strip.show();
    delay(30);
  }
  for(i=200; i>=0; i=i-10) {
    strip.fill(strip.Color(i,0,0), 0, 7); //color, first led, count led
    strip.show();
    delay(30);
  }
}

void loop() {
strip.clear(); //clear any effect that was running


//when left button is pressed
if (digitalRead(left_but) == HIGH  && digitalRead(right_but) == LOW) {
  for(i=4; i<NUMPIXELS; i++) {
    strip.setPixelColor(i, strip.Color(255, 60, 0));
    strip.show();
    delay(DELAYVAL);
  }


  for(i=4; i<NUMPIXELS; i++) {
    strip.setPixelColor(i, strip.Color(0, 0, 0));
    strip.show();
    delay(DELAYVAL);
  }
}


//when right button is pressed
else if (digitalRead(left_but) == LOW  && digitalRead(right_but) == HIGH) {
  for(i=2; i>=0; i--) {
    strip.setPixelColor(i, strip.Color(255, 60, 0));
    strip.show();
    delay(DELAYVAL);
  }


  for(i=2; i>=0; i--) {
    strip.setPixelColor(i, strip.Color(0, 0, 0));
    strip.show();
    delay(DELAYVAL);
  }
}


//when emergency button is pressed
else if (digitalRead(left_but) == HIGH  && digitalRead(right_but) == HIGH) {
  for(i=2; i>=0; i--) {
    strip.setPixelColor(i, strip.Color(255, 60, 0));
    strip.setPixelColor(6-i, strip.Color(255, 60, 0));
    strip.show();
    delay(DELAYVAL+30);
  }


  for(i=2; i>=0; i--) {
    strip.setPixelColor(i, strip.Color(0, 0, 0));
    strip.setPixelColor(6-i, strip.Color(0, 0, 0));
    strip.show();
    delay(DELAYVAL+30);
  }
}


else if (digitalRead(stop) == HIGH) {
    strip.fill(strip.Color(255,0,0), 0, 7); //color, first led, count led
    strip.show();
  }


else{
    strip.fill(strip.Color(80,0,0), 0, 7);
    strip.show();
  }


i = 0;
}

Upload the Code

step 11.png
step 1.png
step 2.png
step 3.png
step 4.png

Follow the steps as shown in the picture to upload code in a ATTINY85.

Step 0: Open Arduino IDE go to FIles > preference > additional board manager URL. Paste the following code: "https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json"

Step 1: Connect the circuit as shown in step 1 and upload the code "Arduino ISP" inside Arduino IDE. To upload the code, just go to File > Example > Arduino ISP > Arduino ISP. This enables an Arduino dev board such as Arduino Uno to upload code to ATTINY85.

Step 2: Select the board ATTINY85 in Arduino IDE. Tools > Board

Step 3: ensure that the programmer is set as Arduino as ISP. Tools > Programmer

Step 4: Upload the code using Arduino ISP as a programmer. Otherwise, the code may not upload properly. Sketch > Upload using programmer.

See this Instructable post by NemesisC to get better understanding: https://www.instructables.com/How-to-Program-an-Attiny85-From-an-Arduino-Uno/

Build the Board and Test

bread board.png
testing.gif

It is always better to build the project on a breadboard and check if everything is working correctly.

It also makes changing the code and testing to the effect easier. The attiny can support a wide range of voltage from 2.7V to 5.5V; hence, I used a lithium battery(3.7V) to test the lights.

Note that the LED strip I am using here is a 5V; thus, it didn't require any extra 12V voltage source to light the strip. For the final device, I used the 12V strip.

Build the Circuit on Vero Board/PCB

20231012_230044.jpg
vero board circuit annotated.jpg

I have used a small vero board and soldered the components. It is always a good idea to make a printed circuit board instead of soldering by hand. For me, this was an experiment so I built it on the Vero board. Moreover, all THT components were used so, hand soldering was not very difficult

I like how it turns out and how compact it is. The picture shows annotation as to where the wire goes.

I used a small plastic enclosure and enough glue gun to secure the circuit board.

Attach the Enclosure With Bike

20240111_190041.jpg
20240111_190056.jpg
20240111_190126.jpg
20231012_231912.jpg

For this part, I contacted a local mechanic. And It turns out, this type of enclosure already exists. So, I bought the metal panel and attached with some screws to the bike.

The LED strip is securely placed inside the white plastic, so it is very water-tight. Moreover, I used heat shrink tubes for the wiring.

Complete

cover.png

And done! I am really satisfied with how it turned out. The only problem I can note is the brightness. But with a brighter LED strip, this problem can be fixed; everything else remains as it is.

It's been almost 4 months and it is still running smoothly. I have plans to make more gadgets for the bike. So, stay tuned :)