555! Led fading that stays on, adjustable speed dimming speed - help! - Page 1
Forum section: electronics / beginners

author: EEVPiobee
author_rank: Contributor
timestamp: February 05, 2014, 04:20:13 pm
content: Hello EEVBloggers!Here's my project:I'm looking for a circuitry that would fade in (0% to 100%) a set of LEDs when a switch is activated (circuit closed) then stays on until the switch is back to an open circuit.Well, 5%-95% is acceptable, of course!This is to put some lighting in a crystal glasses display, whenever the door opens, the light would open smoothly... With style!This is on 12v and it MUST be realized using a PWM method (like a 555) as these LEDs won't be driven directly by it, but with "Repeaters" that will only switch full on when voltage get about over 7v and full off under that(Just saying - Dimming those repeaters work just fine when taking a signal from a simple 555 dimmer like the one Dave Jones did in EEVblog #392 - 555 LED PWM Hack)I also would like to be able to adjust the speed it fades in or out but it's not an absolute necessity, an average of 3 seconds would be fine.Any help on that would be greatly appreciated! Thank you!

author: gregallenwarner
author_rank: Regular Contributor
timestamp: February 05, 2014, 04:35:21 pm
content: 555 timers get their frequency/duty cycle from an RC circuit, so varying the PWM duty cycle would mean changing resistance or capacitance values. I suppose you could use a digital potentiometer, but it'd have to be controlled by another timing device.A much simpler method would be to use a microcontroller with a PWM output. Literally any of the microcontroller options out there would suffice. Arduino is one of the most popular right now, and it includes some example programs with the IDE that are frighteningly close to what you are trying to achieve already. This route will be the easiest, with the least required hardware/circuitry.

author: grumpydoc
author_rank: Super Contributor
timestamp: February 05, 2014, 04:57:14 pm
content: All you need for PWM is a sawtooth and a comparator and you can do the sawtooth with the 555.Or use a dedicated PWM controller eghttp://uk.farnell.com/linear-technology/ltc6992cs6-1-trmpbf/pwm-volt-ctrl-timerblox-6sot-23/dp/1848044The control voltage can be generated from (another) cap charged from a constant current source when the door is opened.

author: electronics man
author_rank: Frequent Contributor
timestamp: February 05, 2014, 05:04:37 pm
content: I would recommend using a microcontroller such as picaxe as arduino is expensive for the application and picaxe is easily embedded mabe the picaxe 08 or 08m would work

author: EEVPiobee
author_rank: Contributor
timestamp: February 05, 2014, 05:05:09 pm
content: Thanks for advice gregallenwarner, that might be interestinghowever I don't do Arduino (at least not yet - It seems that I should get to it)Just for the hick of it I think I'll try both of your solutions, but I'll have to have my hands on an Arduino kit first (Besides, it's not for mass production, so I don't really care for a 3-4$ in parts difference)

author: EEVPiobee
author_rank: Contributor
timestamp: February 05, 2014, 05:07:55 pm
content: Quote from: electronics man on February 05, 2014, 05:04:37 pmI will need to get to programming, I'm still used to small more analog projectsbut that's also something I might try...

author: electronics man
author_rank: Frequent Contributor
timestamp: February 05, 2014, 05:08:57 pm
content: Anyway you should try picaxe before arduino its easier o learn programming that's what I did

author: Simon
author_rank: Unknown
timestamp: February 05, 2014, 05:16:02 pm
content: Quote from: electronics man on February 05, 2014, 05:04:37 pmYou can stick an arduino sketch on an ATtiny85 to do they job, the choice of specific brand is the least of the problems

author: EEVPiobee
author_rank: Contributor
timestamp: February 05, 2014, 05:54:40 pm
content: Quote from: Simon on February 05, 2014, 05:16:02 pmWhat would you recommend as a Arduino starter/learners kit? (keeping in mind this project's objectives) ATtiny85 seems good for this project as it is small, and I'd only need one pwm output for LED's and two inputs (for switch state and maybe fading time adjustments)

author: Simon
author_rank: Unknown
timestamp: February 05, 2014, 06:12:21 pm
content: Quote from: EEVPiobee on February 05, 2014, 05:54:40 pmWell the arduino environment is not setup for the tiny mcu's but the atmega328 but it can be adapted

author: EEVPiobee
author_rank: Contributor
timestamp: February 06, 2014, 09:57:16 am
content: Thank you Simon, I'll go ahead with an ATmega (even thou there is a waste of pins) let's just say maybe I'll make it multi-channels then

author: Simon
author_rank: Unknown
timestamp: February 06, 2014, 10:03:59 am
content: Take a look at this:http://highlowtech.org/?p=1229

author: gregallenwarner
author_rank: Regular Contributor
timestamp: February 07, 2014, 03:24:10 pm
content: The ATTiny may most certainly be programmed with Arduino. See how here:http://www.instructables.com/id/Program-an-ATtiny-with-Arduino/As for embedding, the Arduino platform also certainly supports embedding, thus, you don't need the expensive Arduino board (although I recommend having one because it's such a useful tool, and can be used as a removable "programmer" for embedded circuits.) In fact, nowadays, every time I want to begin a new Arduino project, I don't reach for an Arduino, I merely grab a breadboard, crystal, and a bare ATMega328P DIP IC.And as for programming an Arduino vs. a Picaxe, this depends on the user. Arduino uses pretty much straight C++, while the Picaxe has its own BASIC-like language. Whichever one you're most comfortable working in, that'd be the one I'd recommend. For me, that's the ATMega, as I was raised on C back in college.What I'd suggest is prototyping the design on an actual Arduino board first, then, build your final version as an embedded solution using a standalone ATMega328 or ATTiny85, whichever you prefer. Then, keep your Arduino board for your next project. No need to embed such an expensive device in a final solution when you can simply attach a crystal to a standalone Atmel microcontroller and be done with it.

author: Simon
author_rank: Unknown
timestamp: February 07, 2014, 05:23:27 pm
content: thats exactly what I do, I tend to use my arduino exclusively as a programmer as i gave up trying to get the avrisp2 to work and I want that installed for atmel studio.

author: EEVPiobee
author_rank: Contributor
timestamp: March 10, 2014, 07:19:52 am
content: Alright!Arduino IS a great thing indeed!My project changed a bit with some limitations, but still, in less than a month I went from "What's Arduino?" to getting the job done... I was able to upgrade it to 3 channels (3 doors, 3 lights/led strips) to only one chip; and shrunk it down to an ATTiny45 instead of my original plan of putting as much 555 timers as needed first...I achieved it with this config:ATTiny 45/85: (fused at 8mhz for software PWM)| (note pins numbers are Arduino pins and not package pins)|--Pin 0-- Vref|--Pin 1-- Led chan1 output|--Pin 2-- Led chan2 output|--Pin 3-- Analog input with 3 switches (and resistors as voltage dividers: 18k pulldown to GND, ch1:22k ch2:47k ch3:94k to Vref)|--Pin 4-- Led chan3 outputAnd wrote this from scratch: (I know... ain't optimized, some parts are bit messy, but truly works well and smooth)Code:// NOTE: FOR ATTiny25/45/84, you MUST "Burn bootloader" and set fuses to 8 Mhz with Arduino as ISP for optimal performances...// Even though ATTiny doesn't have an official bootloader, It will set the speed to higher, better value.// otherwise, you might see a lot of LED flickering// More infos on setting the fuses: http://forum.arduino.cc/index.php?topic=83623.0//// Original code: Pierre-Olivier Bisson, March 2014// Version: 1.0.0.1// Open Source, but please leave original credit and add you own. Thank you!#define onState HIGH //Change to LOW if LED is Common -#define offState LOW //Change to HIGH if LED is Common -#define mcuRes 32 //Defines CPU micros() resolution... 1mhz = 64, 2mhz = 32, 4mhz = 16, 8mhz = 8... etc#define pwmRes 192 // Defines adjustables "Levels"; namely duty cycle resolution... higher level, slower speed... (MAX 255)#define slewRate 5 //defines "slowing" factor for the fade time... "1" is the fastest, if you want to be faster, lower the pwmRes.// to calculate aprox fade time with original code: mcuRes * pwmRes * slewRate = total time in uSeconds#define AInputPin 3 //will be the Analog Input pin (3-4 for ATTiny 25/45/85)#define falseReadTreshold 5 //to avoid false detection of a switch, and leds flashing without any reason...#define redPin 1#define greenPin 2#define bluePin 4unsigned long calendar1 = 0L;unsigned long duty1 = 0L;boolean rStatus = 0;boolean gStatus = 0;boolean bStatus = 0;int redDim = 0;int greenDim = 0;int blueDim = 0;/////////////////////////////////////////////////////////////////////////SETUP////////////////////////////////////////////////////////////////void setup() {analogReference(EXTERNAL); //On attiny 25/45/85 Will use Digital Pin 0 as Vref to compare voltage of the input pin// pinMode(AInputPin, INPUT);pinMode(redPin, OUTPUT);pinMode(greenPin, OUTPUT);pinMode(bluePin, OUTPUT);//Nice "Boot sequence" :) ...digitalWrite(redPin, onState);delay(1000);digitalWrite(greenPin, onState);delay(1000);digitalWrite(bluePin, onState);delay(2000);digitalWrite(redPin, offState);digitalWrite(greenPin, offState);digitalWrite(bluePin, offState);}/////////////////////////////////////////////////////////////////////END SETUP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////LOOOOOOP////////////////////////////////////////////////////////////////void loop(){//code here to execute once every calendar...calendar1 = (micros() + ((mcuRes * pwmRes) * slewRate) );//insert/change switch check function here//insert/change Dimming increments and/or function calls herebyte inValue = (inputSwitchesState(AInputPin)); //Calls fuction to read 3 switches pulled on voltage dividers (high or low) and returns binary (00001111) values... 8 to 15=errorsetDim(inValue); //Adjust Global Dimming variables...while (calendar1 > micros()) {duty1 = (micros() + (mcuRes * pwmRes));while (duty1 > micros()){unsigned long currentMicros = micros();////Since micros() fuction reset after 71 hours, we want to avoid a complete crash every 71 hours with this condition:if ( duty1 >= (4284967295)) {calendar1=0;duty1=0;}if ( calendar1 >= (4284967295)) {calendar1=0;duty1=0;}//and reset flags if micros() reseted//Note: improvement could be made, since this one causes a 10 seconds freeze (or so with std parameters) every 3 days.../////////////////////////////////////////////////////////////////////////////////////////////////////////////////RED/////////////////////////if ((currentMicros+(mcuRes * redDim)) <= duty1 ){if (rStatus == 0){digitalWrite(redPin, offState);rStatus =1;}}else{if ((rStatus == 1)&&(redDim>falseReadTreshold)){digitalWrite(redPin, onState);rStatus =0;}}//////////////////////END RED///////////////////////////////////////////GREEN/////////////////////////if ((currentMicros + (mcuRes * greenDim)) <= duty1 ){if (gStatus == 0){digitalWrite(greenPin, offState);gStatus =1;}}else{if ((gStatus == 1)&&(greenDim>falseReadTreshold)){digitalWrite(greenPin, onState);gStatus =0;}}//////////////////////END GREEN///////////////////////////////////////////BLUE/////////////////////////if ((currentMicros+(mcuRes * blueDim)) <= duty1 ){if (bStatus == 0){digitalWrite(bluePin, offState);bStatus =1;}}else{if ((bStatus == 1)&&(blueDim>falseReadTreshold)){digitalWrite(bluePin, onState);bStatus =0;}}//////////////////////END Blue/////////////////////}//End of duty1}//end of calendar1}///////////////////////////////////////////////////////END LOOP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////SUB ROUTINES///////////////////////////////////////////////////////////void setDim(byte inValue){if (bitRead (inValue, 0)) //red channel switch flag at binary position 0{if (redDim <= pwmRes) {redDim++;}}else{if (redDim >=1) {redDim--;}};if (bitRead (inValue, 1)) //green channel switch flag at binary position 1{if (greenDim <= pwmRes) {greenDim++;}}else{if (greenDim >=1) {greenDim--;}}if (bitRead (inValue, 2)) //blue channel switch flag at binary position 2{if (blueDim <= pwmRes) {blueDim++;}}else{if (blueDim >=1) {blueDim--;}}}/* inputSwitchesState// Based on custom project, returns values on 3 voltage dividers based switches and possible combinations. Returns 0 to 7 (or 0000 to 0111)// Resistor values are: Pulldown: 18k, Switch 1: 22k, Switch 2: 47k, Switch 3: 94k (or x2 47k)// NOTE: USE PRECISION RESISTORS, AS 5% Tolerance may give unstable results!! 1% tolerance recommended.// Or, at least, measure the resistors you are installing to take the ones with SPOT ON the values...//// ALSO, use EXTERNAL Vref on your chip, instead of the internal one, otherwise results will vary.//// Here, ELSE IF is used to accelerate the function, that will end as soon as the correct value was found...*/byte inputSwitchesState(byte pin){int sensorValue = analogRead(pin);byte retValue = 0;if (sensorValue < 82) {retValue = 0;} //0= no switch pulled high whatsoeverelse if ((sensorValue >=82) && (sensorValue < 223)) {retValue = 4;} //0100 SW 3 pulled high CHECKelse if ((sensorValue >=223) && (sensorValue < 327)) {retValue = 2; //CHECK} //0010 SW 2 pulled highelse if ((sensorValue >=327) && (sensorValue < 415)) {retValue = 6; //CHECK} //0110 SW 2+3 pulled highelse if ((sensorValue >=415) && (sensorValue < 486)) {retValue = 1; //CHECK} //0001 SW 1 pulled highelse if ((sensorValue >=486) && (sensorValue < 534)) {retValue = 5; //CHECK} //0101 SW 1+3 pulled highelse if ((sensorValue >=534) && (sensorValue < 575)) {retValue = 3; //CHECK} //0011 SW 1+2 pulled highelse if ((sensorValue >=575) && (sensorValue < 640)) {retValue = 7; //CHECK} //0111 SW 1+2+3 pulled highelse if (sensorValue >=640) {retValue = 15; //CHECK} //1111 ErrorCode, actual resistor values don't permit higher values that 640...return(retValue);};The whole thing should in theory run with a ATTiny 25 @ 8mhz as it only takes 1.8k once compiled, but I don't know about Ram and other specs.. (If anyone wants to try...I only have 85's here at the moment)Gotta be addicted to Arduinos now... I can't wait to install that!**Edit: 2014-03-19 Updated code, Major bug 1.0.0.0 crashed

author: gregallenwarner
author_rank: Regular Contributor
timestamp: March 10, 2014, 08:21:39 pm
content: Way to go!I don't wanna spin your head too fast, since this is your first experience with microcontrollers, but the Atmel AVR line of uC's have built-in pulse width modulation hardware! Basically, by writing some data to certain registers, you can start the PWM hardware running, and have a square wave of a certain frequency/duty cycle start appearing on one of the pins, with the software free to go do something else or idle. So you don't have to measure delays and manually turn a pin on and off in software. Want to change the frequency or duty cycle? Just write different data to those registers, and the hardware obeys accordingly.This gets out of the realm of "Arduino" programming and more into the native AVR world, and so your code will no longer be guaranteed portable across all Arduino-compatible devices, but this is my personal favorite way to program AVR's. So if you want to, say, "take the next step", you might want to explore leveraging all the power that the chip has to offer.I believe, if I recall correctly, that the ATTiny85 has 2 timer circuits in it, which can be configured to give you 3 independent PWM outputs. Don't quote me on that, you'd have to check the datasheet.

author: EEVPiobee
author_rank: Contributor
timestamp: March 10, 2014, 11:19:51 pm
content: gregallenwarner:Well... So far I've been experimenting a lot with ATTiny 85s I got... but only managed to use 2 PWM outputs on pin 0 and 1... That's why I went for the software PWM solution, plus If I wanted to get an external Vref for analogRead() (which would be more accurate for what I do to my actual circut) it has to be on Pin 0; which leaves me with only 1 PWM left...Even if we suppose there is 3 PWM channels on those Tiny25/45/85, I still lose one PWM output for Vref to the profit of My inputs, which would leave two channels available...but If I only needed 2 channels, I would have opted to usePWM outputs 0 and 1and usetwo pins input, (lets say 3 and 4) no voltage divider required...But again, If I could move Vref to another pin (I don't know if that's possible) AND enable the 3rd PWM pin somehow (but I can't find true solid documentation on that) Then I could have a suitable solution as well that would give me 3 ouput channels and 3 (virtually 3) inputs out of the 5 usable pins (Note that I really don't want to use reset pin since I afraid I won't be able to reprogram my chip afterwards)Next step: will be to see if I could talk with 2 shift registers -in parallel- with an attiny85... One SR would be with shiftPWM library for my outputs the other SR would be to be able to read 8 inputs (or more... way more) as described here:But I think We are going WAY off topic now talking about Shift Registers andI stillwant to try the Analog solution (for my own experience) even if the final is going to be AVR anyways...

author: gregallenwarner
author_rank: Regular Contributor
timestamp: March 11, 2014, 04:20:33 pm
content: Yeah, that's the downside of working with such a small uC, a lot of the pins pull double duty for the chip's various functions. I hadn't realized you were using an external Vref, so I'd say your solution with software PWM was the way to go.http://arduino.cc/en/tutorial/ShiftOutThat's a tutorial on the Arduino shiftOut() function. I believe that function does software bit-banging rather than using the AVR's SPI hardware, so it should be able to work with any pins you specify, in case the SPI pins on your 85 are allocated to some other function.That's the nature of the beast when it comes to trying to use the built-in hardware on the chip, such as the PWM timers and the SPI. There's no way to remap these functions to other pins, since they are physically hard wired to specific pins. However, you only really have to use them when your code needs to go on and do other things while the hardware takes care of these peripheral functions. Since your code isn't that complex, it can handle the software PWM and bit-banging just fine without sacrificing any perceivable speed whatsoever.

author: djococaud
author_rank: Regular Contributor
timestamp: March 13, 2014, 12:53:51 pm
content: Or use the schematics below... I made it some time ago for a small lighting project...Nothing to program, just two standard opamps...replace R7 with a potentiometer if you want to adjust the fade time...With this circuit, when you set the switch in the "ON" position, the circuit will ramp up the load during a few seconds (PWM Mode) and stay on... When you set the switch in the "OFF" position, the circuit will ramp down the load and stay off.