How to fade-in and fade-out an LED?

Posted on
  • Hello,
    I am new to Espruino and Javascript and am struggling with the asynchronous nature of it. For my first shot at Espruino, I tried to fade in and out an LED. I have done this before in Arduino, but struggling here. What's the best way to do it?

    Here is what I did, but I realize this is wrong as both the fadeIn and fadeOut methods a running in parallel. Thanks in advance.

    var ledPower = 0;
    var ledPin = D15;
    
    function fadeIn(){
        var result = setInterval(function(){
          if(ledPower >= 1){
            clearInterval(result);
          }
          ledPower+= 0.001;
          analogWrite(ledPin, ledPower);
      }, 50);
    }
    
    function fadeOut(){
       result = setInterval(function(){
          if(ledPower <= 0){
            clearInterval(result);
          }
          ledPower-= 0.001;
          analogWrite(ledPin, ledPower);
      }, 50);
    }
    
    while(true){
      ledPower =0;
      fadeIn();
      fadeOut();
    }
    
  • I have got it to work(sort of), but I am not happy with it. It feels like there is/should be a better way to do it than below.

    While googling I found this jhonny-five example, which is quite nice. https://github.com/rwaldron/johnny-five/­blob/master/docs/led-fade.md

    A LED class might make it easier for a beginner like me to start with Espruino. In all, loving Espruino so far. Need to learn Javascript to fully appreciate it though.

    /* This example works by dividing 1 second into 10 ms time intervals and increasing/decreasing the led's analogWrite output by .01 per interval, to produce the fade-in and fade-out effects.
    */
    
    var ledPower =0;
    var ledPin = D15;
    
    function fadeIn(callback){
      //start fadeIn effect should take 1 second to finish.
        var result = setInterval(function(){
          analogWrite(ledPin, ledPower);
          ledPower+= 0.01;
           if(ledPower >= 1){
            clearInterval(result);
            return;
          }
      }, 10);
      
      //set the fade-out effect to start after 1 second.
      setTimeout(callback, 1000);
    }
    
    function fadeOut(){
        var result = setInterval(function(){
          analogWrite(ledPin, ledPower);
          ledPower-= 0.01;
           if(ledPower <= 0){
            clearInterval(result);
            return;
          }
      }, 10);
    }
    
    
    setInterval(function(){
      fadeIn(fadeOut);
    } , 2000);
    
    
  • I wouldn't be happy with that code either...

    TBH - what I'd do for something like this is have a single function getting called every 10 milliseconds with setinterval, set up like kind of like a state-machine, which determines if it needs to brighten, dim, or do nothing. Which feels slightly un-Espruino-ey... but I think it'll probably work better. I don't like a solution that's relying on two intervals staying in sync - that's not guaranteed.

  • You are right, I was unnecessarily complicating things. Thanks a lot for your suggestion @DrAzzy

    This is what I have got now

    let ledBrightness = 0;
    let ledPin = D15;
    let fadeIn = false;
    
    function fadeLED() {
     if((ledBrightness <= 0) || (ledBrightness >= 1)){
       fadeIn = !fadeIn;
     }
      
      setLedBrightness(fadeIn);
    
    }
    
    function setLedBrightness(fadeIn){
        if(fadeIn){
        ledBrightness += 0.01;
      }
      else {
        ledBrightness -=0.01;
      }
      
      analogWrite(ledPin, ledBrightness);
    }
    
    setInterval(fadeLED , 10);
    
    
  • I ended up wanting to do something like this too. I actually ended flashing with a sin wave instead to simplify things and it gives it a nice glow IMO. You can change how long the flash cycle is by adjusting the constant to multiply getTime() by. I liked a 2 second cycle, hence the code below.

    To ensure it always starts by fading in you could use a new Date object when you start the fade instead.

    function fadeLED() {
      analogWrite(ledPin, (Math.sin(getTime()*3)+1)/2);
    }
    
    setInterval(fadeLED, 10);
    
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

How to fade-in and fade-out an LED?

Posted by Avatar for Chaapu @Chaapu

Actions