Jul 062014
 

Motorcycle (automobile) tail lights with leds and PWM

 

It is trendy to use leds wherever. On automobiles, but especially on motorbikes, where power is of the essence, going down from 10W (or 32W with break lights on) to ~1W is very important.

I did this for a friend who owns a Yamaha Venture:

 

This is how the tail light looks like on this bike:

 

1. Survey

I have measured the inside of the tail light and I came out with this:

Tail Lights Survey: the thicker border defines the PCB where the leds will be mounted.

The tail lights are also used to light up the license plate. So, two sets of leds should be used: red ones for the position and break lights, and white ones for the license plate lights.

All of these leds should be protected from an possible over voltage coming from the bike.

The schematic looks like this:

White lights are powered directly from the regulator while the red one will be linked to the PWM generator

The final PCB looks like this:

PCB with leds and 12 volts regulator

2. PWM generator

I have decided to build a digital PWM generator instead of a linear one, powered by a LM555.

The reasons were the following:

– LM555 works to a voltage up to 16V. A short voltage spike could easily ruin it;

– There is a need to make adjustments to the position intensity and memorize it somewhere.

– Micro-controllers work at 5V and they are protected easier than a LM555;

– they have almost the same price.

I have decided to use an ATtiny25/45/85 for this project, along with SMD components, in order to have a small PCB for the controller.

The schematic:

Power Stage

Micro-controller stage. Notice the Stop signal voltage being divided with resistors

Keyboard and ISP header

Power Stage

PCB

 The mosfet is able to drive up to 500 leds, connected in parallel rows of 4-5 leds, depending on their voltage, directly from 12V.

The keyboard is not a regular keyboard, but merely contacts on the PCB, which allow for an easy setup of the positions intensity. Shorting the “UP” or “DOWN” keys will increase, respectively decrease the PWM duty of the leds, while also memorizing the value into EEprom. This value will be loaded and used the next time the motorcycle will be powered.

3. The software

The software works if your MCU runs at 8 MHz, using the internal RC oscillator, not divided by 8.

Fuses setup

The program is written in C and compiled using Atmel Studio 6.1:

#include <stdlib.h>
#include <avr/io.h>
#include <avr/eeprom.h>
#define F_CPU 80000000
#include <util/delay.h>

uint8_t EEMEM EPositionValue=10;
uint8_t Def_PositionValue=10;

uint8_t PositionValue=10;
uint8_t StopValue=100;

//keys definition
#define UP        1
#define DOWN     2
#define STOP     4
#define KPIN  PINB

void init(void)
{
//timer0 setup
    TCCR0A = 
    1 << COM0A1 | // normal port operation, PWM disabled 
    0 << COM0A0 |
    0 << COM0B1 | // not inverted 
    0 << COM0B0 |
    1 << WGM00  | // fast pwm 8 bit
    1 << WGM01  ; // fast pwm 8 bit

    TCCR0B = 
    0 << WGM02 |
    0 << CS00  | // prescaler /8 = 250 Hz PWM 
    0 << CS01  |
    1 << CS02  ;

    DDRB  =_BV(0)|_BV(1)|_BV(2)|_BV(3);        //bits 0-3 of PORTB are defined as outputs
    PORTB =_BV(0)|_BV(1)|_BV(2)|_BV(3);        //bits 4-5 of PORTB are defined as inputs
    PositionValue= eeprom_read_byte(&EPositionValue);
    if (PositionValue==0xFF)                //not programmed EEPROM
    {
        PositionValue=Def_PositionValue;
        eeprom_write_byte(&EPositionValue, Def_PositionValue);
    }
}

void setduty( uint8_t duty) 
{
    OCR0A=duty*255/100;
}

void readkeys(void)
{
    //LEFT AND RIGHT keys

    //UP key
    if bit_is_set(KPIN, STOP)
    {
        setduty(100);
    }
    else
    if bit_is_clear(KPIN, UP)
    {
        PositionValue++;
        if (PositionValue>100) PositionValue=100;
        setduty(PositionValue);
        eeprom_write_byte(&EPositionValue, PositionValue);
        _delay_ms(10);
    }
    else
    //DOWNkey
    if bit_is_clear(KPIN, DOWN)
    {
        PositionValue--;
        if (PositionValue<1) PositionValue=1;
        setduty(PositionValue);
        eeprom_write_byte(&EPositionValue, PositionValue);
        _delay_ms(10);
    }
    else    setduty(PositionValue);
}

void inittest()
{
    uint8_t i,j;
    for(j=0;j<3;j++)
    {
        for(i=0;i<100;i++)
        {
            setduty(i);
            _delay_us(500);
        }
        for(i=100;i>0;i--)
        {
            setduty(i);
            _delay_us(500);
        }
    }
}
int main()

{
    init();
    inittest();
    setduty(PositionValue);
    while(1)
    {
        readkeys();
    }
}

Switch to mobile version
Advertisment ad adsense adlogger