EEVblog Electronics Community Forum

Electronics => Beginners => Topic started by: EEVPiobee on February 05, 2014, 04:20:13 pm

Title: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: EEVPiobee on February 05, 2014, 04:20:13 pm
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!  8)

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!  ^-^
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: gregallenwarner on February 05, 2014, 04:35:21 pm
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.
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: grumpydoc on February 05, 2014, 04:57:14 pm
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 eg http://uk.farnell.com/linear-technology/ltc6992cs6-1-trmpbf/pwm-volt-ctrl-timerblox-6sot-23/dp/1848044 (http://uk.farnell.com/linear-technology/ltc6992cs6-1-trmpbf/pwm-volt-ctrl-timerblox-6sot-23/dp/1848044)

The control voltage can be generated from (another) cap charged from a constant current source when the door is opened.
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: electronics man on February 05, 2014, 05:04:37 pm
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
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: EEVPiobee on February 05, 2014, 05:05:09 pm
Thanks for advice gregallenwarner, that might be interesting

however 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)
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: EEVPiobee on February 05, 2014, 05:07:55 pm
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

I will need to get to programming, I'm still used to small more analog projects  :P but that's also something I might try...
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: electronics man on February 05, 2014, 05:08:57 pm
Anyway you should try picaxe before arduino its easier o learn programming that's what I did
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: Simon on February 05, 2014, 05:16:02 pm
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

You can stick an arduino sketch on an ATtiny85 to do they job, the choice of specific brand is the least of the problems
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: EEVPiobee on February 05, 2014, 05:54:40 pm
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

You can stick an arduino sketch on an ATtiny85 to do they job, the choice of specific brand is the least of the problems

What 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)
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: Simon on February 05, 2014, 06:12:21 pm
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

You can stick an arduino sketch on an ATtiny85 to do they job, the choice of specific brand is the least of the problems

What 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)

Well the arduino environment is not setup for the tiny mcu's but the atmega328 but it can be adapted
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: EEVPiobee on February 06, 2014, 09:57:16 am
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 :D  :-/O
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: Simon on February 06, 2014, 10:03:59 am
Take a look at this: http://highlowtech.org/?p=1229 (http://highlowtech.org/?p=1229)
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: gregallenwarner on February 07, 2014, 03:24:10 pm
The ATTiny may most certainly be programmed with Arduino. See how here:
http://www.instructables.com/id/Program-an-ATtiny-with-Arduino/ (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.
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: Simon on February 07, 2014, 05:23:27 pm
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.
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: EEVPiobee on March 10, 2014, 07:19:52 am
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 output


And wrote this from scratch: (I know... ain't optimized, some parts are bit messy, but truly works well and smooth)

Code: [Select]
// 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 4

unsigned 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 here

    byte inValue = (inputSwitchesState(AInputPin)); //Calls fuction to read 3 switches pulled on voltage dividers (high or low) and returns binary (00001111) values... 8 to 15=error
    setDim(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 whatsoever
  else if ((sensorValue >=82) && (sensorValue < 223)) {
    retValue = 4;   
  } //0100 SW 3 pulled high CHECK
  else if ((sensorValue >=223) && (sensorValue < 327)) {
    retValue = 2;   //CHECK
  } //0010 SW 2 pulled high
  else if ((sensorValue >=327) && (sensorValue < 415)) {
    retValue = 6;   //CHECK
  } //0110 SW 2+3 pulled high
  else if ((sensorValue >=415) && (sensorValue < 486)) {
    retValue = 1;   //CHECK
  } //0001 SW 1 pulled high
  else if ((sensorValue >=486) && (sensorValue < 534)) {
    retValue = 5;   //CHECK
  } //0101 SW 1+3 pulled high
  else if ((sensorValue >=534) && (sensorValue < 575)) {
    retValue = 3;   //CHECK
  } //0011 SW 1+2 pulled high
  else if ((sensorValue >=575) && (sensorValue < 640)) {
    retValue = 7;  //CHECK
  } //0111 SW 1+2+3 pulled high
  else 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...  ;D 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
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: gregallenwarner on March 10, 2014, 08:21:39 pm
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.
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: EEVPiobee on March 10, 2014, 11:19:51 pm
   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 use PWM outputs 0 and 1 and use two 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: How to Control a Ton of Inputs using Shift Registers! (https://www.youtube.com/watch?v=nXl4fb_LbcI#ws)

But I think We are going WAY off topic now talking about Shift Registers and I still want to try the Analog solution (for my own experience) even if the final is going to be AVR anyways...
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: gregallenwarner on March 11, 2014, 04:20:33 pm
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/ShiftOut (http://arduino.cc/en/tutorial/ShiftOut)

That'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.
Title: Re: 555! Led fading that stays on, adjustable speed dimming speed - help!
Post by: djococaud on March 13, 2014, 12:53:51 pm
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.