Arduino 220V light dimmer





This project shows how to control intense of light bulb 220V, so called light dimmer by Arduino and Thyristor. To examine controlling intense of light, Arduino is connected with Visual Studio to control by computer.

Hardware need:
1. Arduino Pro Mini
2. Thyristor BT148
3. Light 220V
4. Other electronics parts (detail in following circuit)

Step 1. Understand how it works
Thyristor is as diode but need current through GATE pin to let main voltage get through (please Wikipedia it for full understand)
Our grid power line is 220V, 50Hz in sine wave. Because of using Thyristor, voltage through Lamp could only be half-cycle of sine wave (to get full-cycle -> use Triac)
Role of Arduino is to detect beginning of sine wave (phase 0), then control trigger time (dim time) for Thyristor via GATE pin

Step 2. Make circuit
The circuit is based on idea "Half wave phase control" which is posted on this website
When S1 is ON, capacitor C is charged until full, then current goes through GATE pin -> make Thyristor SCR conduct (Cap C, Resistor R1 is chosen to make SRC conduct immediately when S1 is ON)
Arduino is used to on switch S1 in positive of half-cycle to control "conduction" effected time. As much "conduction" is made, as much "light intense" is out

Opto U5 EL817 is connected to pin2 of Arduino (interrupt, rising edge) which will detect phase 0 of sine wave of grid line 220VAC.
Opto U4 EL817 is connected to pin9 of Arduino (output) which will trigger Thyristor U1 BT148 for conducting lamp








Step 3. Code works at Arduino
At first, this code will set light with intense of (1-4500/6000)/2 = 12.5% of full light (Note: the calculation 12.5% not so exactly, but we can accept it)
Then, Arduino will wait command from Visual Studio (Computer) to control light dim
String mySt = "";
char myChar;
boolean stringComplete = false;  // whether the string is complete

const byte pin_phase = 2;   //for phase0 detect
const byte pin_trig = 9;    //for trigger Thyrsitor
double time_trig = 4500;

void setup() {
  pinMode(pin_phase,INPUT_PULLUP);
  pinMode(9,OUTPUT);

  attachInterrupt(digitalPinToInterrupt(pin_phase), detect_a, RISING);
  // start serial port at 9600 bps:
  Serial.begin(9600);

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

void loop() {
  if (stringComplete) {
    // clear the string when COM receiving is completed
    mySt = "";  // mySt will not become blank until '\n' is received
    stringComplete = false;
    // start interrupt detect_a()
    EIMSK |= 0b00000001; // un-mask for INT0
  }
  
  //receive command from Visual Studio
  if ((mySt.substring(0,12) == "light_dim_VS")&(stringComplete == false)){
    time_trig = mySt.substring(12,mySt.length()).toInt();  //get dim value after light_dim_VS
    time_trig = time_trig*1000*6/10;
  }

  //dont use "delay" or "println" in this main loop 
  //-> will destroy trigger time for sine 220V 
}

void detect_a() {
  //detect begining of sine wave 220VAC
  delayMicroseconds(time_trig);
  digitalWrite(pin_trig,1);
  delayMicroseconds(30);
  digitalWrite(pin_trig,0);
  
  //dont use "delay" or "println" in this sub 
  //-> will destroy trigger time for sine 220V 
}

void serialEvent() {
  EIMSK &= 0b11111110; // stop intterupt for INT0 - detect_a()
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    if (inChar != '\n') {
      mySt += inChar;
    }
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}
Step 4. Code works of Visual Studio
private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
     serialPort1->Open();
     timer1->Start();
     serialPort1->WriteLine("light_dim_VS"+trackBar1->Value.ToString());
    }
 private: System::Void timer1_Tick(System::Object^  sender, System::EventArgs^  e) {
     label1->Text=(trackBar1->Value*10).ToString();
     pictureBox1->Size = System::Drawing::Size(130-trackBar1->Value*10,130-trackBar1->Value*10);
     pictureBox1->Location = System::Drawing::Point(180-(130-trackBar1->Value*10)/2,80-(130-trackBar1->Value*10)/2);
    }
 private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
     serialPort1->WriteLine("light_dim_VS"+trackBar1->Value.ToString());
   }
 private: System::Void trackBar1_Scroll(System::Object^  sender, System::EventArgs^  e) {
     serialPort1->WriteLine("light_dim_VS"+trackBar1->Value.ToString());
   }

This code will make a small "HMI" to send "dim value" to Arduino and control light dim
Entire code of Visual Studio can be found here (Google share link)

Video result:







0 Comments: