In the last project I made a simple light dimmer using Arduino where the intensity of light (lamp brightness) is controlled with a potentiometer, now in this project I’m going to show how to add a remote control to the circuit so that the lamp brightness is controlled from IR remote control instead of the potentiometer.
The IR remote control used in this project uses RC-5 communication protocol. A related project below shows how to decode RC-5 remote controls. Note that we need to decode our IR remote control in order to know the IR code of the buttons which we’re going to use in the Arduino code.
Related Projects:
220V Light dimmer with Arduino – Lamp brightness control
Arduino RC5 IR remote control decoder
Hardware Required:
Basic component list required for this project is below.
- Arduino board —> ATmega328P datasheet
- BT136 Triac — datasheet
- 220V AC lamp
- IR receiver
- LM393 (or LM339) comparator
- Optocoupler (MOC3020, MOC3021, MOC3022, MOC3023) — datasheet
- 2 x 1N4007 diode (or 1N4001)
- 2 x 220k ohm resistor
- 10k ohm resistor
- 470 ohm resistor
- 120 ohm resistor
- 100 ohm resistor
- 47µF capacitor
- 0.01µF capacitor
- Breadboard
- Jumper wires
Arduino remote controlled light dimmer circuit:
The circuit schematic diagram is shown below.
All grounded terminals are connected together.
Generally the IR receiver has 3 pins: GND, VCC and output, in this example the output pin is connected to Arduino pin 2 which is an external interrupt pin (INT0). The IR sensor as well as the LM393 comparator IC are supplied with 5V (comes from the Arduino board).
The LM393 comparator is used for zero crossing detection.
Arduino remote controlled light dimmer code:
As shown in the circuit diagram, the IR receiver output pin is connected to Arduino external interrupt pin (pin number 2), that means when a button is pressed (from the remote control) the Arduino starts reading the IR signal immediately.
The remote control used in this example uses RC-5 protocol, the RC-5 code message is 14-bit long:
2 start bits, 1 toggle bit, 5 address bits and 6 command bits. The 2 bits (start bits) are always 1 and the toggle bit may be 1 or 0.
In this project I didn’t use the 2 start bits and the toggle bit at all because they have no effect (also to simplify the code). I used a TV remote control which means all the address bits are zeros (address = 0).
What’s left is the important part of the RC-5 code message which is the command number, I used two buttons. the first one with code = 0x10, it increases the light intensity and the second button with code = 0x11 which decreases the light intensity. The other buttons of the remote control have no effect on the circuit.
The frequency of my AC source is 50Hz which means the period is 20ms, so the half wave period is 10ms = 10000µs.
Full Arduino code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | // Arduino light dimmer with IR remote control // This is a free software with NO WARRANTY - Use it at your own risk! // http://simple-circuit.com/ // Define number of Timer1 ticks (with a prescaler of 1/8) #define short_time 1400 // Used as a minimum time for short pulse or short space ( ==> 700 us) #define med_time 2400 // Used as a maximum time for short pulse or short space ( ==> 1200 us) #define long_time 4000 // Used as a maximum time for long pulse or long space ( ==> 2000 us) // define remote control button codes #define Button_up 0x10 #define Button_dn 0x11 #define ZC_input 3 #define triac_gate 8 bool ZC_previous = 0; byte rc5_state = 0, j, alpha = 100; unsigned int rc5_code; void setup(void) { pinMode(triac_gate, OUTPUT); digitalWrite(triac_gate, LOW); // Timer1 module configuration TCCR1A = 0; TCCR1B = 0; // Disable Timer1 module TCNT1 = 0; // Set Timer1 preload value to 0 (reset) TIMSK1 = 1; // enable Timer1 overflow interrupt attachInterrupt(0, RC5_Read, CHANGE); // Enable external interrupt (INT0) } void RC5_Read() { unsigned int timer_value; if(rc5_state != 0){ timer_value = TCNT1; // Store Timer1 value TCNT1 = 0; // Reset Timer1 } switch(rc5_state){ case 0 : // Start receiving IR data (initially we're at the beginning of mid1) TCNT1 = 0; // Reset Timer1 TCCR1B = 2; // Enable Timer1 module with 1/8 prescaler ( 2 ticks every 1 us) rc5_state = 1; // Next state: end of mid1 j = 0; return; case 1 : // End of mid1 ==> check if we're at the beginning of start1 or mid0 if((timer_value > long_time) || (timer_value < short_time)){ // Invalid interval ==> stop decoding and reset rc5_state = 0; // Reset decoding process TCCR1B = 0; // Disable Timer1 module return; } bitSet(rc5_code, 13 - j); j++; if(j > 13){ // If all bits are received rc5_state = 0; rc5_code &= 0x07FF; // Remove the two start bits and the toggle bit from the code message if( (rc5_code == Button_dn) && (alpha < 100) ) alpha++; if( (rc5_code == Button_up) && (alpha > 0) ) alpha--; return; } if(timer_value > med_time){ // We're at the beginning of mid0 rc5_state = 2; // Next state: end of mid0 if(j == 13){ // If we're at the LSB bit rc5_state = 0; bitClear(rc5_code, 0); // Clear the LSB bit rc5_code &= 0x07FF; if( (rc5_code == Button_dn) && (alpha < 100) ) alpha++; if( (rc5_code == Button_up) && (alpha > 0) ) alpha--; return; } } else // We're at the beginning of start1 rc5_state = 3; // Next state: end of start1 return; case 2 : // End of mid0 ==> check if we're at the beginning of start0 or mid1 if((timer_value > long_time) || (timer_value < short_time)){ rc5_state = 0; // Reset decoding process TCCR1B = 0; // Disable Timer1 module return; } bitClear(rc5_code, 13 - j); j++; if(timer_value > med_time) // We're at the beginning of mid1 rc5_state = 1; // Next state: end of mid1 else // We're at the beginning of start0 rc5_state = 4; // Next state: end of start0 return; case 3 : // End of start1 ==> check if we're at the beginning of mid1 if((timer_value > med_time) || (timer_value < short_time)){ // Time interval invalid ==> stop decoding TCCR1B = 0; // Disable Timer1 module rc5_state = 0; // Reset decoding process return; } else // We're at the beginning of mid1 rc5_state = 1; // Next state: end of mid1 return; case 4 : // End of start0 ==> check if we're at the beginning of mid0 if((timer_value > med_time) || (timer_value < short_time)){ // Time interval invalid ==> stop decoding TCCR1B = 0; // Disable Timer1 module rc5_state = 0; // Reset decoding process return; } else // We're at the beginning of mid0 rc5_state = 2; // Next state: end of mid0 if(j == 13){ // If we're at the LSB bit rc5_state = 0; bitClear(rc5_code, 0); // Clear the LSB bit rc5_code &= 0x07FF; if( (rc5_code == Button_dn) && (alpha < 100) ) alpha++; if( (rc5_code == Button_up) && (alpha > 0) ) alpha--; } } } ISR(TIMER1_OVF_vect) { // Timer1 interrupt service routine (ISR) rc5_state = 0; // Reset decoding process TCCR1B = 0; // Disable Timer1 module } void loop() { while(digitalRead(ZC_input) == ZC_previous) ; // Wait for zero crossing event ZC_previous = digitalRead(ZC_input); delayMicroseconds(alpha * 95); // Why 95? for max alpha=100 we get 9500µs (half wave period=10000µs) digitalWrite(triac_gate, HIGH); delayMicroseconds(200); digitalWrite(triac_gate, LOW); } |
Arduino remote controlled light dimmer video:
Discover more from Simple Circuit
Subscribe to get the latest posts sent to your email.
How to control ac fan speed controller with arduino uno and 4 channels relay by ir remote control plse sir make a video
HIjailia contact me at [email protected] to provide you more support
8 channel rilay coad ir timer
Sir I used the same circuit and code but am not getting output ( there is no change in intensity of bulb)
Hlo ..I use ir library , when I use interrupt for zero crossing data the data received is change even I press same switch..
IAM A BEGINNER CAN U PLEASE EXPLAIN THE CODE..