In this short tutorial we will see how to mount the circuit, read the signal from the PIR sensor, detect the 0 cross of the main 220V AC signal and then create the firing pulse to the TRIAC gate and control the power applied to the light bulb at the output.
Below we have the schematic for this project. The PIR sensor will give a high signal for 3 seconds when it detects movement. Then we read that signal with the Arduino. At the same time we read the potentiometer value and map the delay between 5 seconds and 60 seconds. Alos, at the same time we read the 0 cross and the other potentiometer and create a short firing pulse and with that we control the power that will go to the light bulb, so, the brightness.
Copy or download the code from below. Make the connections as in the schematic above and then upload the code. The Arduino is supplied with 12V from the 220VAC to 12VDC regulator. Change this line "delay_time = map(analogRead(delay_in),0,1024,5000,60000); " if you want a different delay range than 5 to 60 seconds.
//Inputs and outputs
int sensor_in = A0;
int delay_in = A1;
int brightness = A2;
int relay_out = 3;
//Variables for the code
int detected = 0;
int firing_pulse_delay=0;
int last_CH1_state = 0;
bool relay_activated = false;
unsigned long delay_time = 5000; //Initial delay time = 5 seconds
unsigned long previousMillis = 0;
void setup() {
pinMode(sensor_in,INPUT);
pinMode(delay_in,INPUT);
pinMode(brightness,INPUT);
pinMode(relay_out,OUTPUT);
/*
* Port registers allow for lower-level and faster manipulation of the i/o pins of the microcontroller on an Arduino board.
* The chips used on the Arduino board (the ATmega8 and ATmega168) have three ports:
-B (digital pin 8 to 13)
-C (analog input pins)
-D (digital pins 0 to 7)
//All Arduino (Atmega) digital pins are inputs when you begin... */
PCICR |= (1 << PCIE0); //enable PCMSK0 scan
PCMSK0 |= (1 << PCINT0); //Set pin D8 trigger an interrupt on state change. Input from optocoupler
pinMode(3,OUTPUT); //Define D3 as output for the TRIAC pulse
}
void loop() {
delay_time = map(analogRead(delay_in),0,1024,5000,60000); //Map delay from 5 to 60 seconds
if(analogRead(sensor_in) > 500 && !relay_activated)
{
relay_activated = true;
previousMillis = millis();
}
if(analogRead(sensor_in) < 500)
{
unsigned long currentMillis = millis();
if(currentMillis - previousMillis >= delay_time)
{
previousMillis += delay_time;
relay_activated = false;
}
}
if(relay_activated)
{
firing_pulse_delay = map(analogRead(brightness),0,1024,7200,10);
if (detected)
{
delayMicroseconds(firing_pulse_delay); //This delay controls the power
digitalWrite(3,HIGH);
delayMicroseconds(100);
digitalWrite(3,LOW);
detected=0;
}
}
}//end of void loop
//This is the interruption routine
//----------------------------------------------
ISR(PCINT0_vect){
///////////////////////////////////// //Input from optocoupler
if(PINB & B00000001){ //We make an AND with the pin state register, We verify if pin 8 is HIGH???
if(last_CH1_state == 0){ //If the last state was 0, then we have a state change...
detected=1; //We haev detected a state change!
}
}
else if(last_CH1_state == 1){ //If pin 8 is LOW and the last state was HIGH then we have a state change
detected=1; //We haev detected a state change!
last_CH1_state = 0; //Store the current state into the last state for the next loop
}
}
Below we can see the regulator that supplies 12V to the relay and the Arduino Vin pin. The PIR module is connected to the Arduino and the Arduino will control the TRIAC so the power applied to the light bulb.