3

I am trying to turn my incandescent bulb gradually,say its brightness should go from zero to 100% in 10 mins. In doing so I found the following code and it works well but it's not as gradual as I want so I hope to achieve my goal by modifying it. I thought I could change the delay in void loop() and that's it! but doing so makes no significant result.

volatile int i=0;               // Variable to use as a counter volatile as it is in an interrupt
volatile boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 9;                // Output to Opto Triac
int dim_level = 0;                    // Dimming level (0-128)  0 = on, 128 = 0ff
int inc=1;                      // counting up or down, 1=up, -1=down

int freqStep =75;    // This is the delay-per-brightness step in microseconds.
                      // For 60 Hz it should be 65
// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)
// and the number of brightness steps you want. 
// 
// Realize that there are 2 zerocrossing per cycle. This means
// zero crossing happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply. 

// To calculate freqStep divide the length of one full half-wave of the power
// cycle (in microseconds) by the number of brightness steps. 
//
// (120 Hz=8333uS) / 128 brightness steps = 65 uS / brightness step
// (100Hz=10000uS) / 128 steps = 75uS/step

void setup() {                                      // Begin setup
  pinMode(AC_pin, OUTPUT);                          // Set the Triac pin as output
  attachInterrupt(0, zero_cross_detect, RISING);    // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
  Timer1.initialize(freqStep);                      // Initialize TimerOne library for the freq we need
  Timer1.attachInterrupt(dim_check, freqStep);      
  // Use the TimerOne Library to attach an interrupt
  // to the function we use to check to see if it is 
  // the right time to fire the triac.  This function 
  // will now run every freqStep in microseconds.                                            
}

void zero_cross_detect() {    
  zero_cross = true;               // set the boolean to true to tell our dimming function that a zero cross has occured
  i=0;
  digitalWrite(AC_pin, LOW);       // turn off TRIAC (and AC)
}                                 

// Turn on the TRIAC at the appropriate time
void dim_check() {                   
  if(zero_cross == true) {              
    if(i>=dim_level) {                     
      digitalWrite(AC_pin, HIGH); // turn on light       
      i=0;  // reset time step counter                         
      zero_cross = false; //reset zero cross detection
    } 
    else {
      i++; // increment time step counter                     
    }                                
  }                                  
}                                   

void loop() {                        
  dim_level+=inc;
  if((dim_level>=128) || (dim_level<=0))
    inc*=-1;
  delay(600);
}

Edit 1: Working on the first sketch suggested by Juraj, I put a light bulb as its load and because the period was initialized by FADE_MIN I expect the light should instantly glow in full brightness first and then gradually lose its brightness and so on, but it's not what happens and instead it takes some time to achieve its full brightness.

mahyar
  • 31
  • 4
  • 3
    try my sketch https://arduino.stackexchange.com/questions/63631/fan-regulator-control-from-arduino/63674#63674 – Juraj Dec 14 '21 at 13:39
  • 1
    Right! I've just run it on Proteus , but it's not that clear to me. what is "FADE_MAX/MIN" for example? arbitrary chosen? what is happening in the void loop? and how to obtain the gradual fading in say 10 mins? – mahyar Dec 14 '21 at 16:28
  • 1
    What delays did you try? The `vold loop(){...}` code makes 128 steps * 600ms = 76.8 sec, which is not close to the desired 10*60=600sec. You probably want a `delay(10*60 * 1000 / 128)` (that's 4687ms per step) to make it 10 minutes one-way. Also, how do you get 10000uS / 128 steps = 75uS/step? I get 10000/128 = 78. – Dave X Dec 15 '21 at 22:09
  • 2
    ... and thirdly, the n/128 steps on an incandescent lamp probably don't map linearly to perceived brightness for a couple reasons: The power per unit time under the sine curve isn't uniform, and secondly the perceived brightness per incremental watt will change with temperature and wattage. You might add an array mapping equal-sized perceptual steps to microseconds, using Juraj's 3rd example.. – Dave X Dec 15 '21 at 22:41
  • 1
    addressing Edit 1: try lower FADE_MIN value – Juraj Dec 19 '21 at 15:52
  • I tried different amounts for delay and FADE_MIN and it still gradually goes high. – mahyar Dec 20 '21 at 06:51

0 Answers0