miercuri, 3 aprilie 2013

Variator de tensiune pentru bec cu Arduino (III)

   Fata de articolul precedent in care am controlat intensitatea luminoasa a unui bec din soft sau cu ajutorului unui buton prin crestere de la zero pana la maxim intr-un anumit numar de pasi, apoi de la maxim la minim, acum am mai pus un buton fara retinere astfel pot creste sau scade intensitatea dupa dorinta.

   Prima data am ales varianta cu 2 trepte de intensitate (bec stins, la 50% si la maxim), realizand si un mic filmulet numit ac light dimmer with Arduino (IX):
   Starile sunt:
- bec stins (LED albastru la maxim):
- bec la 50% (LED albastru la 50%):
- bec la maxim (LED albastru stins):
   Sketch-ul numit versiunea 4.0 este urmatorul:


/*
AC Light Control

 Updated by Robert Twomey <rtwomey@u.washington.edu>

 Changed zero-crossing detection to look for RISING edge rather
 than falling.  (originally it was only chopping the negative half
 of the AC wave form). 

 Also changed the dim_check() to turn on the Triac, leaving it on 
 until the zero_cross_detect() turn's it off.

 Ryan McLaughlin <ryanjmclaughlin@gmail.com>

 The hardware consists of an Triac to act as an A/C switch and 
 an opto-isolator to give us a zero-crossing reference.
 The software uses two interrupts to control dimming of the light.
 The first is a hardware interrupt to detect the zero-cross of
 the AC sine wave, the second is software based and always running 
 at 1/128 of the AC wave speed. After the zero-cross is detected 
 the function check to make sure the proper dimming level has been 
 reached and the light is turned on mid-wave, only providing 
 partial current and therefore dimming our AC load.

 Thanks to http://www.andrewkilpatrick.org/blog/?page_id=445 
 and http://www.hoelscher-hi.de/hendrik/english/dimmer.htm

 adapted sketch by niq_ro from
 http://www.tehnic.go.ro 
 http://www.niqro.3x.ro 
 http://nicuflorica.blogspot.com 
 version: 4m0 (03.04.2013 - Craiova, Romania)
 */

#include <TimerOne.h>           // Avaiable from http://www.arduino.cc/playground/Code/Timer1

volatile int i=0;               // Variable to use as a counter
volatile boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 3;                // Output to Opto Triac
int buton1 = 4;             // first button at pin 4
int buton2 = 5;              // second button at pin 5
int redLED = 11;                    // red LED at pin 11 
int blueLED = 10;                    // blue LED at pin 10
int dim = 128;                    // Dimming level (0-128)  0 = on, 128 = 0ff
int pas = 64; // step for count;

int freqStep = 75;    // This is the delay-per-brightness step in microseconds.
// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)
// and the number of brightness steps you want. 
// 
// The only tricky part is that the chopper circuit chops the AC wave twice per
// cycle, once on the positive half and once at the negative half. This meeans
// the chopping happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply. 

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

void setup() {  // Begin setup
  pinMode(buton1, INPUT);  // set buton1 pin as input
  pinMode(AC_pin, OUTPUT);                          // Set the Triac pin as output
  pinMode(redLED, OUTPUT);                             // Set the LED pin as output
  pinMode(blueLED, OUTPUT);                             // Set the LED 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 on the TRIAC at the appropriate time
void dim_check() {                   
  if(zero_cross == true) {              
    if(i>=dim) {                     
      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() {                        
  if (digitalRead(buton1) == LOW)   
   {
  if (dim<125)  
  {
     dim = dim + pas;
  }
  else
  {
   analogWrite(redLED, 255);  // write dimmer value to the LED, for debugging
  delay (100);
   analogWrite(redLED, 0);  // write dimmer value to the LED, for debugging
   }
   }
  if (digitalRead(buton2) == LOW)   
   {
  if (dim>5)  
  {
     dim = dim - pas;
  }   
  else
  {
   analogWrite(redLED, 255);  // write dimmer value to the LED, for debugging
  delay (100);   
  analogWrite(redLED, 0);  // write dimmer value to the LED, for debugging
   }
   }
    while (digitalRead(buton1) == LOW) {  }              
    delay(10); // waiting little bit...  
    while (digitalRead(buton2) == LOW) {  }              
    delay(10); // waiting little bit...    
           
  analogWrite(blueLED, dim);  // write dimmer value to the LED, for debugging
  delay (100);
}

   Pentru a avea 3 pasi (0 - 33% - 67% - 100%) se schimba pasul de la 64 la 42, sketch-ul de venind versiunea 4m1.

int pas = 42; // step for count;

   Starile sunt:
- bec stins (LED albastru la maxim):
- bec la 33% (LED albastru la 67%):
- bec la 67% (LED albastru la 33%):
- bec la maxim (LED albastru stins):


   Am schimbat culoarea LED-ului indicator in verde, sketch-ul devenind versiunea 4m1.1:


/*
AC Light Control

 Updated by Robert Twomey <rtwomey@u.washington.edu>

 Changed zero-crossing detection to look for RISING edge rather
 than falling.  (originally it was only chopping the negative half
 of the AC wave form). 

 Also changed the dim_check() to turn on the Triac, leaving it on 
 until the zero_cross_detect() turn's it off.

 Ryan McLaughlin <ryanjmclaughlin@gmail.com>

 The hardware consists of an Triac to act as an A/C switch and 
 an opto-isolator to give us a zero-crossing reference.
 The software uses two interrupts to control dimming of the light.
 The first is a hardware interrupt to detect the zero-cross of
 the AC sine wave, the second is software based and always running 
 at 1/128 of the AC wave speed. After the zero-cross is detected 
 the function check to make sure the proper dimming level has been 
 reached and the light is turned on mid-wave, only providing 
 partial current and therefore dimming our AC load.

 Thanks to http://www.andrewkilpatrick.org/blog/?page_id=445 
 and http://www.hoelscher-hi.de/hendrik/english/dimmer.htm

 adapted sketch by niq_ro from
 http://www.tehnic.go.ro
 http://www.niqro.3x.ro 
 http://nicuflorica.blogspot.com 
 version: 4m1.1 (03.04.2013 - Craiova, Romania) - 3 steps
 */

#include <TimerOne.h>           // Avaiable from http://www.arduino.cc/playground/Code/Timer1

volatile int i=0;               // Variable to use as a counter
volatile boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 3;                // Output to Opto Triac
int buton1 = 4;             // first button at pin 4
int buton2 = 5;              // second button at pin 5
int redLED = 11;                    // red LED at pin 11 
int greenLED = 9;                    // green LED at pin 9
int dim = 128;                    // Dimming level (0-128)  0 = on, 128 = 0ff
int pas = 42; // step for count;

int freqStep = 75;    // This is the delay-per-brightness step in microseconds.
// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)
// and the number of brightness steps you want. 
// 
// The only tricky part is that the chopper circuit chops the AC wave twice per
// cycle, once on the positive half and once at the negative half. This meeans
// the chopping happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply. 

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

void setup() {  // Begin setup
  pinMode(buton1, INPUT);  // set buton1 pin as input
  pinMode(AC_pin, OUTPUT);                          // Set the Triac pin as output
  pinMode(redLED, OUTPUT);                             // Set the LED pin as output
  pinMode(greenLED, OUTPUT);                             // Set the LED 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 on the TRIAC at the appropriate time
void dim_check() {                   
  if(zero_cross == true) {              
    if(i>=dim) {                     
      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() {                        
  if (digitalRead(buton1) == LOW)   
   {
  if (dim<125)  
  {
     dim = dim + pas;
  }
  else
  {
   analogWrite(redLED, 255);  // write dimmer value to the LED, for debugging
  delay (100);
   analogWrite(redLED, 0);  // write dimmer value to the LED, for debugging
   }
   }
  if (digitalRead(buton2) == LOW)   
   {
  if (dim>5)  
  {
     dim = dim - pas;
  }   
  else
  {
   analogWrite(redLED, 255);  // write dimmer value to the LED, for debugging
  delay (100);   
  analogWrite(redLED, 0);  // write dimmer value to the LED, for debugging
   }
   }
    while (digitalRead(buton1) == LOW) {  }              
    delay(10); // waiting little bit...  
    while (digitalRead(buton2) == LOW) {  }              
    delay(10); // waiting little bit...    
           
  analogWrite(greenLED, dim);  // write dimmer value to the LED, for debugging
  delay (100);
}

- bec stins (LED verde la maxim):
- bec la 33% (LED verde la 67%):

- bec la 67% (LED verde la 33%):
- bec la maxim (LED verde stins):

   Pentru a avea 4 trepte de reglaj (0 - 25% - 50% - 75% - 100%) se schimba pasul de la 42 la 32, sketch-ul devenind versiunea 4m2.

int pas = 32; // step for count;

  Starile sunt:
- bec la maxim (LED verde stins):
 - bec la 75% (LED verde la 25%):
- bec la 50% (LED verde la 50%):
- bec la 55% (LED verde la 75%):
- bec stins (LED verde la maxim):

   Pentru a avea 8 trepte de reglaj (0 - 12,5% - 25% - 37,5% - 50% - 62,5% - 75% - 87,5% - 100%), schimbam pasul de la 32 la 
16, sketch-ul devenind versiunea 4m3.


int pas = 16; // step for count;

   Am facut un filmulet cu functionarea, numit ac light dimmer with Arduino (X):
   Starile distincte sunt:
- bec stins (LED indicator aprins la maxim):
- bec aprins la 12,5% (LED la 87,5%):
- bec aprins la 25% (LED la 75%):
- bec aprins la 37,5% (LED la 62,5%):
- bec aprins la 50% (LED la 50%):
- bec aprins la 62,5% (LED la 37,5%):
- bec aprins la 75% (LED la 25%):
- bec aprins la 87,5% (LED la 12,5%):
- bec aprins la maxim (LED indicator stins):



   Pentru a folosi la maxim LED-ul multicolor (RGB), care imi va indica cu albastru becul stins (rece) pana la rosu (bec la maxim), am folosit urmatorul sketch (versiune 4m4) pentru 4 trepte de intensitate:

/*
AC Light Control

 Updated by Robert Twomey <rtwomey@u.washington.edu>

 Changed zero-crossing detection to look for RISING edge rather
 than falling.  (originally it was only chopping the negative half
 of the AC wave form). 

 Also changed the dim_check() to turn on the Triac, leaving it on 
 until the zero_cross_detect() turn's it off.

 Ryan McLaughlin <ryanjmclaughlin@gmail.com>

 The hardware consists of an Triac to act as an A/C switch and 
 an opto-isolator to give us a zero-crossing reference.
 The software uses two interrupts to control dimming of the light.
 The first is a hardware interrupt to detect the zero-cross of
 the AC sine wave, the second is software based and always running 
 at 1/128 of the AC wave speed. After the zero-cross is detected 
 the function check to make sure the proper dimming level has been 
 reached and the light is turned on mid-wave, only providing 
 partial current and therefore dimming our AC load.

 Thanks to http://www.andrewkilpatrick.org/blog/?page_id=445 
 and http://www.hoelscher-hi.de/hendrik/english/dimmer.htm

 adapted sketch by niq_ro from
 http://www.tehnic.go.ro 
 http://www.niqro.3x.ro 
 http://nicuflorica.blogspot.com 
 version: 4m4 (03.04.2013 - Craiova, Romania) - 4 steps & LED blue to red (off to MAX) 
 */

#include <TimerOne.h>           // Avaiable from http://www.arduino.cc/playground/Code/Timer1

volatile int i=0;               // Variable to use as a counter
volatile boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 3;                // Output to Opto Triac
int buton1 = 4;             // first button at pin 4
int buton2 = 5;              // second button at pin 5
int redLED = 11;                    // red LED at pin 11 
int greenLED = 9;                    // green LED at pin 9
int blueLED = 10;                  // blue LED at pin 10
int dim2 = 0;  // led control
int dim = 128;                    // Dimming level (0-128)  0 = on, 128 = 0ff
int pas = 32; // step for count;

int freqStep = 75;    // This is the delay-per-brightness step in microseconds.
// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)
// and the number of brightness steps you want. 
// 
// The only tricky part is that the chopper circuit chops the AC wave twice per
// cycle, once on the positive half and once at the negative half. This meeans
// the chopping happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply. 

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

void setup() {  // Begin setup
  pinMode(buton1, INPUT);  // set buton1 pin as input
  pinMode(AC_pin, OUTPUT);                          // Set the Triac pin as output
  pinMode(redLED, OUTPUT);                             // Set the LED pin as output
  pinMode(greenLED, OUTPUT);                             // Set the LED pin as output
  pinMode(blueLED, OUTPUT);                             // Set the LED 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 on the TRIAC at the appropriate time
void dim_check() {                   
  if(zero_cross == true) {              
    if(i>=dim) {                     
      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() {                        
  if (digitalRead(buton1) == LOW)   
   {
  if (dim<127)  
  {
    dim = dim + pas;
    if (dim>127) 
    {
      dim=127;
    }
  }
  else
  {
   analogWrite(greenLED, 255);  // write dimmer value to the LED, for debugging
  delay (100);
   analogWrite(greenLED, 0);  // write dimmer value to the LED, for debugging
   }
   }
  if (digitalRead(buton2) == LOW)   
   {
  if (dim>5)  
  {
     dim = dim - pas;
  if (dim<0) 
    {
      dim=1;
    }
   }
  else
  {
   analogWrite(greenLED, 255);  // write dimmer value to the LED, for debugging
  delay (100);   
  analogWrite(greenLED, 0);  // write dimmer value to the LED, for debugging
   }
   }
    while (digitalRead(buton1) == LOW) {  }              
    delay(10); // waiting little bit...  
    while (digitalRead(buton2) == LOW) {  }              
    delay(10); // waiting little bit...    
           
  analogWrite(blueLED, 2*dim-2);  // write dimmer value to the LED, for debugging
  dim2 = 256-2*dim+1;
  if (dim2<0)
  {
    dim2 = 0;
  }
  analogWrite(redLED, dim2);  // write dimmer value to the LED, for debugging
  delay (100);
}

   Starile sunt:
- bec stins (LED albastru la maxim, LED rosu stins):
- bec la 25% (LED albastru la 75%, LED rosu la 25%):
- bec la 25% (LED albastru la 75%, LED rosu la 25%):
- bec la 25% (LED albastru la 75%, LED rosu la 25%):
- bec la maxim (LED albastru stins, LED rosu aprins):
   Filmuletul care prezinta modul de functionare se numeste ac light dimmer with Arduino (XI)
   Dupa cum se va observa in filmulete, la apasarea butonului de reducere a intensitatii si becul este stins se aprinde scurt LED-ul verde; acelasi lucru se intampla si pentru apasarea butonului de crestere a intensitatii si becul este la maxim.

4.4.2013
   Pentru a avea 8 trepte de iluminare, se injumatateste pasul 
int pas = 16; // step for count;
acum sketch-ul a devenit versiunea 4m5.
/*
AC Light Control
 Updated by Robert Twomey <rtwomey@u.washington.edu>
 Thanks to http://www.andrewkilpatrick.org/blog/?page_id=445 
 and http://www.hoelscher-hi.de/hendrik/english/dimmer.htm
 adapted sketch by niq_ro from
 http://www.tehnic.go.ro 
 http://www.niqro.3x.ro 
 http://nicuflorica.blogspot.com 
 version: 4m5 (04.04.2013 - Craiova, Romania) - 8 steps & LED blue to red (off to MAX) 
 */

#include <TimerOne.h>           // Avaiable from http://www.arduino.cc/playground/Code/Timer1

volatile int i=0;               // Variable to use as a counter
volatile boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 3;                 // Output to Opto Triac
int buton1 = 4;                 // first button at pin 4
int buton2 = 5;                 // second button at pin 5
int redLED = 11;                // red LED at pin 11 
int greenLED = 9;               // green LED at pin 9
int blueLED = 10;               // blue LED at pin 10
int dim2 = 0;                   // led control
int dim = 128;                  // Dimming level (0-128)  0 = on, 128 = 0ff
int pas = 16;                   // step for count;

int freqStep = 75;    // This is the delay-per-brightness step in microseconds.

void setup() {  // Begin setup
  pinMode(buton1, INPUT);  // set buton1 pin as input
  pinMode(AC_pin, OUTPUT);                          // Set the Triac pin as output
  pinMode(redLED, OUTPUT);                          // Set the LED pin as output
  pinMode(greenLED, OUTPUT);                        // Set the LED pin as output
  pinMode(blueLED, OUTPUT);                         // Set the LED 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
}

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 on the TRIAC at the appropriate time
void dim_check() {                   
  if(zero_cross == true) {              
    if(i>=dim) {                     
      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() {                        
  if (digitalRead(buton1) == LOW)   
   {
  if (dim<127)  
  {
    dim = dim + pas;
    if (dim>127) 
    {
      dim=127;
    }
  }
  else
  {
   analogWrite(greenLED, 255);  // LED is ON for indicate an error
  delay (100);
   analogWrite(greenLED, 0);  // LED is now OFF
   }
   }
  if (digitalRead(buton2) == LOW)   
   {
  if (dim>5)  
  {
     dim = dim - pas;
  if (dim<0) 
    {
      dim=1;
    }
   }
  else
  {
   analogWrite(greenLED, 255);  // LED is ON for indicate an error
  delay (100);   
  analogWrite(greenLED, 0);    // LED is now OFF
   }
   }
    while (digitalRead(buton1) == LOW) {  }              
    delay(10); // waiting little bit...  
    while (digitalRead(buton2) == LOW) {  }              
    delay(10); // waiting little bit...    
           
  analogWrite(blueLED, 2*dim-2);  // write dimmer value to the LED, for debugging
  dim2 = 256-2*dim+1;
  if (dim2<0)
  {
    dim2 = 0;
  }
  analogWrite(redLED, dim2);  // write dimmer value to the LED, for debugging
  delay (100);
}

   Starile sunt:
- bec stins (LED albastru aprins 100%, iar cel rosu stins)
- bec la treapta 1:
- bec la treapta 2:
- bec la treapta 3:
- bec la treapta 4:
- bec la treapta 5:
- bec la treapta 6:
- bec la treapta 7:
- bec aprins la maxim (LED rosu aprins la 100%, iar cel albastru stins):

   Pentru a avea 16 trepte de iluminare, se injumatateste pasul fata de cel pentru 8 trepte:

int pas = 8;                    // step for count;
// version: 4m6 (04.04.2013 - Craiova, Romania) - 16 steps & LED blue to red (off to MAX) 

acum sketch-ul a devenit versiunea 4m6, fiind completat si cu monitorizare seriala (pe ecranul monitorului) a valorilor intensitatii becului si celor 2 LED-uri (rosu si albastru):
/*
AC Light Control
 Updated by Robert Twomey <rtwomey@u.washington.edu>
 Thanks to http://www.andrewkilpatrick.org/blog/?page_id=445 
 and http://www.hoelscher-hi.de/hendrik/english/dimmer.htm
 adapted sketch by niq_ro from
 http://www.tehnic.go.ro 
 http://www.niqro.3x.ro 
 http://nicuflorica.blogspot.com 
*/

#include <TimerOne.h>           // Avaiable from http://www.arduino.cc/playground/Code/Timer1

volatile int i=0;               // Variable to use as a counter
volatile boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 3;                 // Output to Opto Triac
int buton1 = 4;                 // first button at pin 4
int buton2 = 5;                 // second button at pin 5
int redLED = 11;                // red LED at pin 11 
int greenLED = 9;               // green LED at pin 9
int blueLED = 10;               // blue LED at pin 10
int dim2 = 0;                   // led control
int dim = 128;                  // Dimming level (0-128)  0 = on, 128 = 0ff
int pas = 8;                    // step for count;
// version: 4m6 (04.04.2013 - Craiova, Romania) - 16 steps & LED blue to red (off to MAX) 

int freqStep = 75;    // This is the delay-per-brightness step in microseconds.

void setup() {  // Begin setup
  Serial.begin(9600);   
  pinMode(buton1, INPUT);  // set buton1 pin as input
  pinMode(AC_pin, OUTPUT);                          // Set the Triac pin as output
  pinMode(redLED, OUTPUT);                          // Set the LED pin as output
  pinMode(greenLED, OUTPUT);                        // Set the LED pin as output
  pinMode(blueLED, OUTPUT);                         // Set the LED 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
}

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 on the TRIAC at the appropriate time
void dim_check() {                   
  if(zero_cross == true) {              
    if(i>=dim) {                     
      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() {                        
  if (digitalRead(buton1) == LOW)   
   {
  if (dim<127)  
  {
    dim = dim + pas;
    if (dim>127) 
    {
      dim=127;
    }
  }
  else
  {
   analogWrite(greenLED, 255);  // LED is ON for indicate an error
  delay (100);
   analogWrite(greenLED, 0);  // LED is now OFF
   }
   }
  if (digitalRead(buton2) == LOW)   
   {
  if (dim>5)  
  {
     dim = dim - pas;
  if (dim<0) 
    {
      dim=1;
    }
   }
  else
  {
  analogWrite(greenLED, 255);  // LED is ON for indicate an error
  delay (100);   
  analogWrite(greenLED, 0);    // LED is now OFF
   }
   }
    while (digitalRead(buton1) == LOW) {  }              
    delay(10); // waiting little bit...  
    while (digitalRead(buton2) == LOW) {  }              
    delay(10); // waiting little bit...    
           
  analogWrite(blueLED, 2*dim);  // write dimmer value to the LED, for debugging
  dim2 = 255-2*dim;
  if (dim2<0)
  {
    dim2 = 0;
  }
  analogWrite(redLED, dim2);  // write dimmer value to the LED, for debugging

  Serial.print("dim=");
  Serial.print(dim);

  Serial.print("     dim2=");
  Serial.print(dim2);
  Serial.print("     dim1=");
  Serial.print(2*dim);
   
  Serial.print('\n');
  delay (100);
}

   Filmuletul cu reglarea intensitatii luminoase in 16 trepte se numeste ac light dimmer with Arduino (XII):

Un comentariu: