miercuri, 22 ianuarie 2014

Variator de tensiune pentru bec cu Arduino (V)

   Am revenit la partea de variator de tensiune pentru bec cu incandescenta,pana nu dispar de tot de pe piata... de data asta am pus si un afisaj LCD alfanumeric 1602 (16 coloane si 2 randuri), 2 butoane fara retinere pentru creste si scadere intensitate luminoasa si 16 trepte ...
   Partea cea mai complicata si cea mai periculoasa, care detecteaza trecerea prin zero a tensiunii retelei si, care comanda triacul, se gaseste in articolul Variator de tensiune pentru bec folosind un Arduino:
   In articolele Variator de tensiune pentru un bec cu Arduino (II)Variator de tensiune pentru bec cu Arduino (III) si Variator de tensiune pentru bec cu Arduino (IV) am prezentat mai multe experimente, iar schema de baza ar fi ca cea de mai jos, fara LED-ul RGB:
   Eu am conectat si afisajul LCD la pinii 8..13 obtinand:
- bec stins (0%):
- treapta 1 (6%):
- treapta 2-a (13%):
- treapta 3-a (19%):
- treapta 4-a (25%):
- treapta 5-a (31%):
- treapta 6-a (38%):
- treapta 7-a (44%):
- treapta 8-a (50%):
- treapta 9-a (57%):
- treapta 10-a (63%):
- treapta 11-a (69%):
- treapta 12-a (75%):
- treapta 13-a (82%):
- treapta 14-a (88%):
- treapta 15-a (94%):
- treapta 16-a (100%), adica maxim:
   Si sa "raman in continuare om serios" va arat si programiorul folosit / sketch-ul):
/*
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 <LiquidCrystal.h>
// use LiquidCrystal.h library for alphanumerical display 1602
LiquidCrystal lcd(13,12,11,10,9,8);
/*                                     -------------------
                                       |  LCD  | Arduino |
                                       -------------------
 LCD RS pin to digital pin 13          |  RS   |   D13   |
 LCD Enable pin to digital pin 12      |  E    |   D12   |
 LCD D4 pin to digital pin 11          |  D4   |   D11   |
 LCD D5 pin to digital pin 10          |  D5   |   D10   |
 LCD D6 pin to digital pin 9           |  D6   |    D9   |
 LCD D7 pin to digital pin 8           |  D7   |    D8   |
 LCD R/W pin to ground                 |  R/W  |   GND   |
                                       -------------------
*/

#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 dim2 = 0;                   // led control
int dim = 128;                  // Dimming level (0-128)  0 = on, 128 = 0ff
int pas = 8;                    // step for count;
// version: 4m7 (15.04.2013 - Craiova, Romania) - 16 steps, 4 button & LED blue to red (off to MAX) 
// version: 7m3 (22.01.2014 - Craiova, Romania) - 16 steps, 2 button & LCD1602

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(buton2, INPUT);  // set buton1 pin as input
  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

 lcd.begin(16, 2); // set up the LCD's number of columns and rows: 
 lcd.clear(); // clear the screen
 lcd.setCursor(2, 0); // put cursor at colon 0 and row 0
 lcd.print("16 steps AC"); // print a text
 lcd.setCursor(0, 1); // put cursor at colon 0 and row 1
 lcd.print("dimmer for bulb"); // print a text
 delay (3000);
 lcd.clear(); // clear the screen
 lcd.setCursor(1, 0); // put cursor at colon 0 and row 0
 lcd.print("this sketch is"); // print a text
 lcd.setCursor(1, 1); // put cursor at colon 0 and row 1
 lcd.print("made by niq_ro"); // print a text
 delay (3000);
 lcd.clear(); // clear the screen
}

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() {  
  digitalWrite(buton1, HIGH);
  digitalWrite(buton2, HIGH);
  
 if (digitalRead(buton1) == LOW)   
   {
  if (dim<127)  
  {
    dim = dim + pas;
    if (dim>127) 
    {
      dim=127;
    }
  }
   }
  if (digitalRead(buton2) == LOW)   
   {
  if (dim>5)  
  {
     dim = dim - pas;
  if (dim<0) 
    {
      dim=1;
    }
   }
   }
    while (digitalRead(buton1) == LOW) {  }              
    delay(10); // waiting little bit...  
    while (digitalRead(buton2) == LOW) {  }              
    delay(10); // waiting little bit...    
           

  dim2 = 255-2*dim;
  if (dim2<0)
  {
    dim2 = 0;
  }

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

  Serial.print("     dim2=");
  Serial.print(dim2);
  Serial.print("     dim1=");
  Serial.print(2*dim);
  Serial.print('\n');
  delay (100);
 lcd.setCursor(2, 0); // put cursor at colon 0 and row 0
 lcd.print("power is "); // print a text
 lcd.print(100-100*(255-dim2)/255);
 lcd.print("%    "); // print a text
 lcd.setCursor(1, 1); // put cursor at colon 0 and row 1
 lcd.print("dim. level="); // print a text
 lcd.print(dim);
 lcd.print("  "); // print a text
}
   Am facut si 2 filmulete:
ac light dimmer with Arduino (XVII)
ac light dimmer with Arduino (XVIII)
23.01.2014
   Deoarece am constatat ca la tastarea pentru cresterea sau scaderea intensitatii luminoase, mai apar erori la numarul minim sau maxim, am corectat sketch-ul in 2 locuri:
    if (dim>127) 
    {
      dim=128; // in vechiul sketch era 127
    }
   respectiv:
  if (dim<0) 
    {
      dim=0;  // in vechiul sketch era 1
    }

24.01.2014
   Am desenat si schema de comectare completa:

Un comentariu:

  1. Atat circuitul cat si softul e superb. As vrea sa folosesc acest circuit pentru a comanda puterea unui aparat de pirogravat. Este posibil extinderea numarului de trepti de putere? Multumesc.

    RăspundețiȘtergere