Monday, November 9, 2020

Constant current LED driver using ATtiny13 - Headlamp flashlight

Here is a simple constant current source for driving 7 white 5mm LEDs and also 2 red LEDs. I have made the circuit for a headlamp flashlight that had a soft button which required a microcontroller. To save the battery life the microcontroller is powering down when the lights are off with a current draw of only 0.3uA.

Constant current LED driver using ATtiny13 - Headlamp flashlight

Schematic of a constant current LED driver using ATtiny13A microcontroller

Constant current LED driver using microcontroller schematic

Using a resistor for current limiting in a LED driver is inefficient because when the battery voltage drops the resistance remains the same leading to a low light brightness even though there is still potential for a higher current in the batteries. For this reason it is preferable to replace the fixed resistor with a variable one. For that a transistor mosfet is used here (Q3 and Q2).

The circuit is very simple and the working principle can be applied to other LED projects. In this case I had to fix a headlamp torch that had the main IC burned out so I made another PCB to drive the LEDs. The flashlight has 7 white LEDs that are driven with 210mA (30mA for each LED) and 2 red LEDs (40mA - 20mA per LED).

Q3 is an SMD mosfet acting as a variable resistor. A mosfet is better than a transistor here because when the batteries are almost depleted the voltage will be too low to waste on the voltage drop that a transistor has even when is fully turn on. The collector voltage drop increases with the current and since the red LEDs only need 40mA, a cheap SMD transistor Q2 is used there. When the battery is almost empty the voltage is around 0.8V - 1V. If the flashlight uses 3 batteries, the lowest voltage will be around 3 volts therefore a mosfet with a low Vgs must be selected.

A 0805 SMD current sense resistor of 1 ohm is used (R5 and R3) and the ATtiny13A microcontroller monitors the current through the LEDs by measuring the voltage drop on the shunt resistor using an ADC. Then PWM is used to generate a voltage to control the mosfet. The PWM frequency is fixed only the duty cycle varies. If the current is lower than the desired one, the duty cycle is increased. If the current is too high the duty cycle is decreased.

An RC low-pass filter composed by R4 and C3 is used to convert the PWM to a steady voltage. 

Q1 mosfet is for reverse voltage protection in case the batteries are connected in reverse. The mosfet must have a low RDSon to drop as little voltage as possible at the maximum current that the circuit uses. Both Q1 and Q3 are both CPH3448-TL-W SMD mosfets with 0.038 ohm RDSon. To learn more about reverse voltage protection see this article from Texas Instruments Reverse Current/Battery Protection Circuits

J2 has 6 SMD pads for soldering the custom connector for the ISP programmer that I made from 6 pins header with the pins bend at 90 degrees. After programming the connector can be easily desoldered compared to a through hole one.

Headlamp repair constant current microcontroller

Headlamp repair constant current microcontroller

Software code for headlamp using ATtiny13A microcontroller and a soft push button

The code can be seen or downloaded bellow and has comments that explains it. The PCINT2 pin is set as an input with the pull-up resistor enabled and when the button is pressed the pin is pulled to ground triggering an interrupt and then the ISR sets a flag that the button was pressed. The debouncing is made in software. On every button press the flashlight toggles between on and off. When OFF the microcontroller enters in power down power saving mode and the current consumption is around 0.3uA. This is important to preserve the battery life while the flashlight is not used.

When the flashlight is ON the voltage at the current sense resistor is measured continuously by the ADC2 pin for main light and by the ADC3 for the auxiliary light (red LEDs). The transistors are controlled by Timer0 set in fast PWM mode with OCR0A controlling PB0 and main lights and OCR0B controls PB1 and the auxiliary light.

To switch between main and auxiliary light the button must be held down for approximately 2 seconds. Other modes can be implemented such as flashing and other brightness levels but are not implemented in the current software.

The current is set by the defines ADC_MAX_BRIGHTNESS and ADC_AUX_BRIGHTNESS which represents ADC units. To convert from current to ADC units use the formula: 

ADC = (Vrsense * ADCres) / Vref

Vrsense - is the voltage at the current sense resistor = Desired Current * Rsense = 0.210A * 1ohm = 0.210V
ADCres - is the ADC resolution. For a 10bit ADC used here this is 2^10 = 1024
Vref - the ADC refference voltage which is 1.1V in this case

So for 210mA the ADC value is (0.210V * 1024) / 1.1 = 195

By default ATtiny13A comes with the 9.6MHz CPU clock divided by 8 so I removed this clock prescaler by changing the fuse bits to get the full speed. Here are the fuse bits programmed with avrdude command line:

-U lfuse:w:0x7A:m     -U hfuse:w:0xFF:m 

Be aware that is a difference between ATiny13 and ATiny13A regarding the fuse bits so look at the microcontroller label to check the type. Here is the site used for calculating the fuse bits.

Download

main.c - v1.0

adc.h - v1.3