Who has not happened to note that wonderful breathing led effect present on some electronic devices?
There are makers all over the world equipped with oscilloscope tried to do reverse engingering to find the algorithm and turn it into an Arduino sketch. The problem lies in the fact that most of the codes found in the network have two defects: the first is that such algorithms do not contain a function but a series of pre-calculated values that do not make the effect smooth, while the second resides in the fact that often these codes are blocking, making use of delay and therefore do not permit the correct execution of the remaining code inside of the sketch.
Ispired by the Sean Voisen’s post who find the function defining the PWM values to drive the LED, I made some changes and tests to make it non-blocking and to make it work in background allowing execution to other code.
The end result is the following:
The connection is obviously as for any other LEDs and the system is capable of driving even power LEDs or LED strip, through appropriate transistor or MOSFET (See: Driving a LED Strip with Arduino)
The Arduino code is the following:
/*
NonBlockingBreathingLed 0.1
by Luca Soltoggio - 2015
12 May 2015
http://www.arduinoelettronica.com/
https://arduinoelectronics.wordpress.com/
http://minibianpi.wodpress.com/
Use a exp + sin function to recreate a
non-blocking breathing led effect
Released under GPL v.2 license
*/
#include <math.h>
#define ledPin 11
int i=0;
int breathe_delay = 15; // delay between loops
unsigned long breathe_time = millis();
void setup()
{
}
void loop()
{
nonBlockingBreath(); // call the nonblocking function
// yourOtherCodeHere();
}
void nonBlockingBreath()
{
if( (breathe_time + breathe_delay) < millis() ){
breathe_time = millis();
float val = (exp(sin(i/2000.0*PI*10)) - 0.36787944)*108.0;
// this is the math function recreating the effect
analogWrite(ledPin, val); // PWM
i=i+1;
}
}
On the internet there are so many Led Flasher’s projects, some even with low current consumption, but what I needed was a flasher to be used for geocaching, extremely small and that could last at least one year with a button battery.
I started so a little experiments with the ATtiny85 low power modes using the sketch of insidegadgets, achieving a power consumption of about 4.5uA in standby and of about 3mA during the led flash that occurs every 4 seconds and lasts for about 30ms.
In this way, the average consumption is around 25uA, which with a CR2032 button battery from about 220mAh, this means about a year of life!
After a first draft of the project, I thought it might be useful to also have a 12V version so that it can be also powered by the battery of a car.
Here you can see the circuit on the first version, namely the one powered by 3V button battery:
The schematic is really very simple because the real work is done by the code:
/*
Ultra Low Power Led Flasher
with AtTiny85 @ 1Mhz
by Luca Soltoggio
06/01/2014
http://www.arduinoelettronica.com
*/
#include <avr/sleep.h>
#include <avr/wdt.h>
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
int pinLed = 4;
volatile boolean f_wdt = 1;
void setup(){
pinMode(pinLed,OUTPUT);
setup_watchdog(8); // approximately 4 seconds sleep
}
void loop(){
if (f_wdt==1) { // wait for timed out watchdog / flag is set when a watchdog timeout occurs
f_wdt=0; // reset flag
digitalWrite(pinLed,HIGH); // let led blink
delay(30);
digitalWrite(pinLed,LOW);
pinMode(pinLed,INPUT); // set all used port to intput to save power
system_sleep();
pinMode(pinLed,OUTPUT); // set all ports into state before sleep
}
}
// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {
cbi(ADCSRA,ADEN); // switch Analog to Digitalconverter OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable();
sleep_mode(); // System sleeps here
sleep_disable(); // System continues execution here when watchdog timed out
sbi(ADCSRA,ADEN); // switch Analog to Digitalconverter ON
}
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
byte bb;
int ww;
if (ii > 9 ) ii=9;
bb=ii & 7;
if (ii > 7) bb|= (1<<5);
bb|= (1<<WDCE);
ww=bb;
MCUSR &= ~(1<<WDRF);
// start timed sequence
WDTCR |= (1<<WDCE) | (1<<WDE);
// set new watchdog timeout value
WDTCR = bb;
WDTCR |= _BV(WDIE);
}
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
f_wdt=1; // set global flag
}
Today I want to show you a project really very simple but effective that can be used for various applications.
This is a high resistance continuty sensor (current gain approximately 30000 times), based on the interesting Darlington NPN BC517, and very low cost.
The basic design published here simply allows you to turn on an LED by touching or immersing in water two metallic elements (cables, plates or whatever), but “cloning” the circuit and putting more transistors and more LEDs, we can get a gauge with 2, 3, 4 or 30 sectors.
It goes without saying nothing forbids to replace the LED with a relay in order to drive loads the most important.
But let’s see in detail the circuit:
The operation is quite trivial: by touching the two contacts of the sensor “SENS” with hands for example, the weak current flowing through the body is sufficient to excite the transistor via the resistor R1 which serves as protection if we join directly the two contacts. The BC517 is able to amplify this current approximately 30,000 times, for which a current of 10 uA, is able to slide up to 300 mA through the transistor. The resistor R2 serves to prevent accidental starting by grounding the base of the transistor, while R3 is simply the resistor to limit the current flowing through the LED.
Although simple, I believe that this project will be a starting point for other applications.
Also sometimes the simple things are the most functional and a little ‘analog electronics’ sometimes … is not bad …
Greetings and see you soon!
Update – 03/10/2012 Schema corrected: obviously one of the two leads did not go to mass but on the positive … I apologize for the mistake and thanx who rightly corrected me with his comments.
And now another interesting little project.
After seeing various online projects, especially based on the PIC microcontroller, I decided to make a charger for NiMH batteries driven by an ATtiny85.
Why we need a microcontroller to manage charging a battery? The answer is very simple … The most economic charger that on the market, regulate the charge based on a timer, that is if I charge a 2500mAh battery for example, they provide a charging current of 250mAh, keeping the charge for eg 14 hours (a part of the energy will be lost, so 10 hours would not be enough).
This way of charging NiMh or NiCd batteries is not very functional. It is a slow process, and does not guarantee a 100% accurate cell charge, as well as increasing the risk of overload.
“Smart” chargers however, charge batteries correctly, but besides being quite expensive, their usually charge current is not very high, leading to charging times still quite long.
So in addition to the curiosity and the desire to create something of my own, this project was born …
But lets proceed with order, starting with a video showing the finished running project:
Let us now try to understand the operating principle.
First nickel batteries require a constant current to be charged properly. So we used a transistor-based constant current source, derived from what we saw in a previous post, and so far nothing special, but how do we know when the battery is fully charged?
We need to constantly read the voltage of the battery being charged, and when there will be a maximum peak voltage followed by a sudden drop of about 20mV, the battery may be considered charged. This phenomenon (called Negative Delta V) is related to the chemistry of this type of battery, and allows to establish precisely the right moment to terminate charging.
Thus we see the circuit diagram:
The schematic is pretty simple. The darlington transistor Q1 (TIP127), through LED1 (which must be absolutely RED) and the resistance R3 from 0.3 Ω, creates a constant current flowing in the direction of the 6-cell battery (7.2V), while the Schottky diode 1N5822, serves to protect the entire circuit in the case that is lacking the input voltage with the battery connected. The voltage divider R4-R5, serves to bring to port 7 of the ATtiny (A1) the battery voltage decreased to about 1/3, in such a way that it can operate with voltages up to 15V (the analog input of the ATtiny can not exceed 5V). The transistor Q2, driven by the port 5 of the ATtiny (D0), serves as a switch to enable or disable the LED-1 and the transistor Q1. It’s really important that LED1 is RED, and this is not a matter of aesthetics, but because the power output is given by the ratio between the voltage of the LED (the red LED is about 1.8 to 2.2 V) and resistance R3. Using a green LED, the reference voltage is raised, and consequently also the current rises (and not just a little bit).
The circuit above, can deliver about 1.5-2.5 A: you may have to do some testing with various types of red LED, or vary the resistance, which must be at least 2W. If you can not find resistance with so low values, you can use 3 or 4 1Ω resistors in parallel.
Another thing to remember, is the power dissipated by the TIP127, which can be up to 20 watt (depending on the current and the voltage difference between the input and the battery), then a heat sink need to be mounted properly. In my case was enough to use the aluminum enclosure.
Last note is the input voltage, which must not be too high otherwise you risk to burn the transistor, but must not be even too low, because otherwise the dropout induced by the various components makes too low the charging current. Can fit approximately a difference of about 5V between the input voltage and the nominal value of the battery. For example, with 6-cell a voltage of 12.2 V is recommended (maybe 12). Of course you can also charge less cells, by suitably adjusting the input voltage. For a cell, we should feed the device with a voltage of about 1.2 + 5 = 6.2 V (maybe 6 or 7).
Let us consider now the printed circuit board:
Note the two gems that were not visible in the schematic. The ICSP connector (ie the ability to update the firmware on the ATtiny – via UsbTinyISP programmer for example – and the debug connector, to be connected to a TTL converter in order to read the battery voltage during charging.
The J1 connector is a jumper that must be closed at all times, except when updating the firmware of Attiny85.
About firmware … The source code is as follows:
/*
NiMh Charger 0.9
with AtTiny85 @ 1Mhz
by Luca Soltoggio
10/03/2012 - 20/04/2012
Use negative deltaV to determine end of charge.
Suitable for NiMh and NiCD battery pack.
Default is for 6 cells 2500mAh.
Need some hardware/software adjustment for changing current / cells number
See http://arduinoelettronica.wordpress.com/
*/
const int inputPin = A1;
const int outputPin = 0;
const int numReadings = 30; // number of analog read before checking battery status
const int multi = 1614; // multi coefficent for obtaining millivolts from analogread
long interval = 1000; // interval for pulse charging and analog read - don't change this
long interval2 = 250; // pulse off interval - you can adjust power with this. Use 100 for 2-4Ah battery packs, 500 for 1-2Ah battery pack
long interval2b=interval2;
long previousMillis,currentMillis,currentMillis2,trickleMillis = 0;
unsigned int readingtemp;
unsigned int total = 0;
unsigned int average,medium,maxmedium = 0;
boolean executed,endcharge,trickle=false; // booleans for controlling various activities (for example "end of charge")
unsigned int myarray [7]; // array for keeping last 7 readings
int index,i = 0;
void setup()
{
Serial.begin(9600);
pinMode(0,OUTPUT);
// Some readings for initial check
for (i=0;i<10;i++) {
readingtemp = analogRead(inputPin);
total=total+readingtemp;
}
average = (((float)total / 1023.0) * (float)multi) / 10.0 + 0.5;
if (average<=70) endcharge=true; // If there is no battery, end charge
Serial.println(average);
total=0;
average=0;
}
void pusharray() {
// push the array
for (i=0;i<=5;++i) {
myarray[i]=myarray[i+1];
}
myarray[6]=average;
}
void voltread() {
readingtemp = analogRead(inputPin); // read analog input
total= total + readingtemp;
index++;
// if numReadings reached, calculate the average
if (index==numReadings) {
index=0;
average = (((float)total / 1023.0) * (float)multi) / numReadings + 0.5;
if (average<=70) endcharge=true; // stop charge if battery is detached
total=0;
pusharray(); // insert new average in array
medium=(float)(myarray[6]+myarray[5]+myarray[4]+myarray[3]+myarray[2]+myarray[1]+myarray[0])/7.0+0.5; // calculate the average of the last 7 readings
if (medium>maxmedium) maxmedium=medium; // save the value of highest medium in "maxmedium"
Serial.print(medium);
Serial.print(",");
Serial.print(maxmedium);
Serial.print(",");
Serial.println(myarray[6]);
if ( ((medium+1) < maxmedium) && ((millis()/60000)>=11) ) { // if battery charged (average voltage is dropped 0.02v), but not in the firsts 11 mintues
if (!trickle) trickleMillis=millis(); // start trickle timer
trickle=true; // enter final trickle charging mode
if ((millis()/60000)<=15) endcharge=true; // if battery is charged in the firts 15 minutes, don't apply trickle charge (maybe was yet charged)
}
}
}
void loop() {
currentMillis = millis();
// executed every "interval" millis
if(currentMillis - previousMillis > interval) {
voltread(); // call reading and check volts function
digitalWrite(outputPin,LOW); // temporaly stop charging
previousMillis = currentMillis;
executed=false; // boolean for setting and checking if has been yet turned ON charge
// in the firsts 10 minutes and in the endings 15 minutes do a trickle charge (change OFF interval)
if ( ( (trickle) && (((millis()-trickleMillis)/60000)<15) ) || ((millis()/60000)<10) ) {
interval2=(interval-(interval-interval2b)/5);
} else if ((millis()/60000)>=10) interval2=interval2b; // after initial trickle charghe set back right time
if ( (trickle) && (((millis()-trickleMillis)/60000)>=15) ) endcharge=true; // if final trickle charge end, end charge
}
currentMillis2 = millis();
// executed "interval2" millis after turning OFF charge
if ((currentMillis2 - previousMillis > interval2) && (!executed)) {
executed=true;
if (!endcharge) {
digitalWrite(outputPin,HIGH); // if battery is not charged, re-enable charging
}
}
}
The code is pretty simple and self-explanatory.
I conclude with a few pictures of the finished project:
Some of my previous post that talked about LED Driver, have generated a bit of confusion in someone … So I wanted to do a bit of clarity.
In particular, in a comment, I was asked if the driver did well to drive the LED strips.
The answer is: NO WAY!
Nothing to do. We have to consider LED strips as if they were bulbs or motors at 12V: they do not require special drivers to be controlled, but we simply have to feed them with a proper voltage (usually just 12V).
This is because LED strips are not simple LED, but within them ther is a circuit of series-parallel LED equipped with suitable resistances, and are then handled as a normal 12V equipment.
In the case of single LED, which has no real operating voltage, we need instead oconstant current in order to operate.
The correct circuit for driving an LED strip with Arduino is therefore as follows:
Where VCC is obviously the Arduino output (digital or analog) and X1 represents my LED strip (or motor or any other dimmable equipment at 12V).
Q1 is a TIP120, but any NPN or darlington NPN is fine, as long as is adequate to the load power.
I hope this article could have done a little ‘clarity.
See you soon!
Finally after a long absence, in which I was immersed in the final realization of this project, I did it!
After months of planning, studies, research and other obstacles, the RGB LED Lamp 1.0 by Toggio is reality.
Here’s the video showing the final result obtained:
And now a brief history.
One of the things that attracted me the most when I first heard of Arduino, was light, and in particular I have always dreamed of achieving an LED lamp RGB.
Nothing difficult, you might think … Except that along this route I found several obstacles.
First of all, I did not find complete projects on the net … There is something, but, in my opinion, with bad algorithms, with little explanation or with complicated methods.
I wanted a simple present to give to the person who I love and that gave me a beautiful daughter …
I wanted something that had a powerful enough light, without too much heat. I wanted something that had a chance to choose the color and not a simple “color cycler.” I wanted something that would serve also as a standard lamp. And finally, I wanted something that was modular and upgradeable in the future.
After these reflections, I began to study the hardware first. I did not want to use the Arduino UNO because it seemed too big for my project. So I decided (and this could open up a huge parentheses) to use a board not so common, but in my opinion awesome (so much that I bought 4 or 5 piece): The Arduino Mini Pro.
(It is understood that in the project of this post, it can easily be replaced by an Arduino UNO or any other board.)
It ‘a very small board (18mm x 33mm), 100% compatible with Arduino Dumilanove, and low power consumption. It is available in four versions: with Atmega328 or with ATmega168, both with 3.3V or 5V.
So I opted in this project for the 5V version with ATmega168. In short it is a very economic solution (it costs about half of the Arduino UNO), very compact and beautiful to see.
I then thought of using the useful LED RGB strips, which offer many advantages over using 1W or 3W power LEDs: they do not heat up, they are powered with 12V and they offer a power up to 13-14W per meter.
Each channel can be powered by a PWM output of the Arduino using a simple transistor (in my case I used the BC337, but for higher power you can use other transistor, or even the MOSFET).
I then proceeded to build a kind of shield for my board. Practically I made a circuit in which the Arduino Pro Mini would fit with strip connectors and with the ability to be removed to upgrade the firmware. Everything has been designed with Fritzing and built by Fritzing Fab.
The final result of the printed circuit is as follows:
You can see the two rows of holes where the Mini Pro will be mounted… Basically, it’s the opposite of a shield 🙂
But let’s step back and see the circuit schematic:
I hope it is clear enough even if I have not drawn just fine!
In any case, the operation principle is as follows: The two 10k potentiometers connected between +5 V and ground, are the two analog inputs that allow to adjust the brightness and other parameters set by the software. The 3-position switch SW2 allows you to select three different functions for the lamp. The digital outputs 3,5,6 go through a resistor to drive the 3 BC337 transistors that will give negative voltage to the 3 channels (R, G, B) of the LED strip. The common positive goes to +12 V, while the Arduino is powered by RAW port (input from 7V to 13V) via a diode that in addition to providing reverse polarity protection, slightly lowers the voltage. SW1 is simply the bridge where will be connected a standard power switch.
Once soldered the components, connectors, potentiometers, mounted the circuit, encapsulated the Arduino board, and assembled it all in a electrician box, the result is as in the following picture:
The size of the box is approximately 10cmx10cmx7cm.
For the top, I used about 70cm of RGB led strip, for a total power of about 10W. To fit the whole strip I rolled it around the support of a “50 CD-R set”. I cut with a utility knife and I glued all with spacers on the box. I then glued with hot glue the wrapping strip led… In short, the job is a little rough but the end result is as follows:
The glass you see on the desk, is the final piece: the glass cover of a IKEA lamp, properly cut by a local glazier, so that it remains empty on both sides. This coverage will finally resting on the box and glued, obtaining the following results:
Not bad right?
Of course there is still the icing on the cake, a not less important part: the software.
The self-explanatory code is as follows:
/*
RGB Led Lamp 1.0a
by Luca Soltoggio
15/03/2012
http://arduinoelettronica.wordpress.com/
*/
int rpin = 3; // red pin
int gpin = 5; // green pin
int bpin = 6; // blue pin
unsigned int r=0, g=0, b=0,bm=0; // r,g,b, value and blue coefficient
unsigned int valh=0, vals=0, valv=0; // hue, saturation, value
unsigned int sensorValue; // analog sensor value
const int analogInPin = A0; // potentiometer pins
const int analogInPin2 = A1;
const int digitalInPin = 10; // switch pins
const int digitalInPin2= 11;
int red[]={255,255,135}; // predefined arrays for RGB / White
int green[]={157,255,158};
int blue[]={51,255,255};
boolean DIG1, DIG2;
long previousMillis = 0;
int i=0,j=0;
int dl=0; // delay
void setup()
{
pinMode(digitalInPin,INPUT);
pinMode(digitalInPin2,INPUT);
}
void loop()
{
DIG1=digitalRead(digitalInPin);
DIG2=digitalRead(digitalInPin2);
if (DIG1) {
bm=1.1;
HSV_Game();
}
else if (DIG2) {
bm=1.9;
RAINBOW_Game();
}
else {
bm=2.4;
LIGHT_Game();
}
analogWrite(rpin, r/1.09); // write RED PIN
analogWrite(gpin, g/1); // write GREEN PIN
analogWrite(bpin, b/bm); // write BLUE PIN
}
// analog input smoothing function
int SensorSmooth (int pin) {
sensorValue=0;
for (int i = 0; i<10; i++) {
sensorValue+= analogRead(pin);
}
return int ((float)sensorValue/10+0.5);
}
// first light game: modify HUE and VALUE with potentiometer
void HSV_Game() {
valh = SensorSmooth(analogInPin);
vals = 255;
valv = SensorSmooth(analogInPin2);
valh = map(valh,0,1023,0,359);
valv = map(valv,0,1023,32,255);
hsv2rgb(valh,vals,valv,r,g,b);
}
// second light game: three positions for Warm White, White and Cold White
void LIGHT_Game() {
valv = SensorSmooth(analogInPin2);
valv = map(valv,0,1023,16,255);
valh = SensorSmooth(analogInPin);
if (valh<=281) valh=0;
if (valh>=742) valh=2;
if (valh>2) valh=1;
r=red[valh]*valv/255;
g=green[valh]*valv/255;
b=blue[valh]*valv/255;
}
// color cycler
void RAINBOW_Game() {
dl = SensorSmooth(analogInPin); // delay time
dl = map(dl,0,1023,1,100);
valv = SensorSmooth(analogInPin2);
valv = map(valv,0,1023,64,255);
unsigned long currentMillis = millis();
switch (j) {
case 0:
r=255*valv/255;
g=i*valv/255;
b=0*valv/255;
break;
case 1:
r=(255-i)*valv/255;
g=255*valv/255;
b=0*valv/255;
break;
case 2:
r=0*valv/255;
g=255*valv/255;
b=i*valv/255;
break;
case 3:
r=0*valv/255;
g=(255-i)*valv/255;
b=255*valv/255;
break;
case 4:
r=i*valv/255;
g=0*valv/255;
b=255*valv/255;
break;
case 5:
r=255*valv/255;
g=0*valv/255;
b=(255-i)*valv/255;
}
if (currentMillis-previousMillis > (long)(100-dl)) { // use millis instead of delay
previousMillis=currentMillis;
i=i+1;
if (i==256) {
i=1;
j=j+1;
if (j==6) j=0;
}
}
}
/* HSV2RGB function
(c) Elco Jacobs, E-atelier Industrial Design TU/e, July 2011
http://code.google.com/p/shiftpwm/source/browse/trunk/examples/ShiftPWM_Example1/hsv2rgb.cpp?r=3
*/
void hsv2rgb(int hue, int sat, int val, unsigned int& r, unsigned int& g, unsigned int& b)
{
int H_accent = hue/60;
int bottom = ((255 - sat) * val)>>8;
int top = val;
int rising = ((top-bottom) *(hue%60 ) ) / 60 + bottom;
int falling = ((top-bottom) *(60-hue%60) ) / 60 + bottom;
switch(H_accent) {
case 0:
r = top;
g = rising;
b = bottom;
break;
case 1:
r = falling;
g = top;
b = bottom;
break;
case 2:
r = bottom;
g = top;
b = rising;
break;
case 3:
r = bottom;
g = falling;
b = top;
break;
case 4:
r = rising;
g = bottom;
b = top;
break;
case 5:
r = top;
g = bottom;
b = falling;
break;
}
}
In the previous post we saw a simple LED driver based on integrated LM317, but as explained one of the faults of the circuit is the high dropout.
Thus we see today a scheme based on a single transistor (in our case a BC337, but any NPN is fine as long as we know all the electronics characteristics), which has a dropout of about 1.25V.
The circuit is as follows:
Of course, you can also use just one LED. I put three in series as example, as we are able to drive three 1W LEDs with a high efficiency. In the abovbe figure, we have a LED power of about 3W, while the whole circuit consumes about 4W.
But let see the operation principle:
The LEDR is a standard LED and serves as a reference voltage for the transistor. The red LED dropout is about 1.8V, then the collector of the transistor will receive approximately 950mV. Always applying Ohm’s law 0.950 / 2,8 = 339, then with R2 at 2.8Ω there is a current leakage of 339mA, which will flow also through the emitter of Q1. In this way we will have a constant current regardless of the input voltage. This is true as long as the voltage will be sufficient to maintain the LEDR at 1.8 V, or 1.2V on the emitter of Q1. So in other words we expect that the input voltage is at least 1.2V higher than the dropout of the LED that we are going to drive. White leds for example, have a maximum voltage of 3.6V, so 3.6 × 3 = 10.8V and 10.8 + 1.2 = 12V. In this case we are perfect. I always recommend a voltage of about 1.5 V more for safety.
If the load to drive is greater than 500-600mA, it is possible to decrease the value of R1 up to 470Ω.
If we want to exceed 750mA instead, we should replace the transistor with a darlington type like the BD677A that can deliver up to 4A!
You can test the circuit by changing the values, using the free simulator online at this link.
Obviously this circuit is “PWM capable.” We can then feed the device via a PWM circuit, or use the following appropriate circuit in order to use a PWM output of Arduino:
In this case we have to slightly decrease the value of resistance R2, due to the fact that the Q1 driving voltage is not 12V but 5V.
The important thing as always is to experiment, experiment, experiment!
The use of LEDs in daily life, in recent years has increasingly taken hold.
With the release on the market of power LEDs (1W, 3W, 5W, 10W …) the ability to illuminate our lives with these diodes is within everyone’s reach.
Unfortunately, the integrated power LED (like brand name bulbs) have costs still high enough, but the individual leds are affordable.
The problem for many is the power, as compared to classic 20mA LED that typically are fed at 12V with a 470Ω series resistor, this type of LED need, considering the power, to be fed not with constant voltage, but with constant current.
When you buy a high power LED, often the seller also provides its specified power driver at prices not always acceptable.
Hence my research on the various sites and blogs for a system to power these LEDs, which give me the ability to be dimmed even by a PWM circuit or by a microcontroller (such as Arduino).
I found two interesting projects, simple, easy to implement, experienced and above all economic and built with components very common and widespread.
The first circuit that I want to present, is constructed using the integrated circuit LM317, which is a variable voltage regulator, but in this case we will use it as a current regulator.
The circuit shown here is quite simple to understand. Between Vout and ADJ is present a reference voltage of 1.25 V, then applying Ohm’s law I = V / R, with a voltage of 1.25 V and a resistance of 3.6 Ω, we will have a constant current of approximately 347mA flowing through LED1, irrespective of the input voltage. This circuit is therefore suitable for example for powering a 1W LED (which typically uses 350mA).
Of course you can put more LEDs in series, but remember that the dropout is about 3V, so the input voltage must be at least 3V higher than the nominal LED voltage. However, if the voltage is too high the chip will warm up too much as all the excess voltage is dissipated just from LM317.
In fact this circuit from the point of view of yield is not the maximum; to power a 1W LED, the circuit draws approximately 4W.
We must also think about the fact that the power dissipated by resistance is about 1.25V multiplied by the circuit current (347mA in this case), then we should pay attention that resistance is adequate to power (we can put two or more resistences in series or in parallel to avoid this problem).
Everything is “PWM capable“, so we can feed the device with a PWM power driver (maybe i will public one in a future post), or drive the LED with a low power PWM signal, such as the output of a 5V Arduino. In this case the schematic will be modified as follows:
We had to change the value of the resistance R1 because introducing R2, the reference value is brought to 1.75V approx. It should be tested and measured with an current meter.
In this circuit VCC, that is the TTL input of our circuit (PWM output of an Arduino, rather than the logic output of a NE555), when is at a high value (+5V), the transistor Q1 conducts and the ADJ pin of the LM317 goes to ground, inhibiting the flowing of current in R1 and then in the LED. Conversely, if I bring the logic input to a low value (0V) the transistor does not conduct allowing the flowing of current: the LED lights up as in the previous example. Obviously logic works in reverse and then in microcontroller programming this should be taken into account, or at least you can add an additional transistor to invert the logic again.
In a future post, we’ll create another circuit that has the same function, but using a transistor instead of the LM317.