Điều chỉnh độ sáng bóng đèn từ xa với Arduino

Điều chỉnh độ sáng bóng đèn từ xa với Arduino

Điều khiển từ xa IR được sử dụng trong dự án này sử dụng giao thức truyền thông RC-5. Một dự án liên quan dưới đây cho thấy cách giải mã điều khiển từ xa RC-5. Lưu ý rằng chúng ta cần giải mã điều khiển từ xa IR của mình để biết mã IR của các nút mà chúng ta sẽ sử dụng trong code Arduino.

Phần cứng cần thiết:

Danh sách linh kiện cơ bản cần thiết cho dự án này bên dưới.

  • Board Arduino
  • BT136 Triac
  • Đèn điện xoay chiều 220v
  • bộ thu IR
  • IC LM393 (hoặc LM339)
  • Bộ ghép nối (MOC3020, MOC3021, MOC3022, MOC3023)
  • 2 x Diode 1N4007 (hoặc 1N4001)
  • 2 x Điện trở 220k ohm
  • Điện trở 10k ohm
  • Điện trở 470 ohm
  • Điện trở 120 ohm
  • Điện trở 100 ohm
  • Tụ 47uF
  • Tụ 0,01uF
  • Breadboard
  • Dây dẫn

Arduino điều khiển cường sáng từ xa:

Sơ đồ mạch được hiển thị dưới đây.

Tất cả các điểm mút nối đất được nối với nhau.

Nói chung, bộ thu IR có 3 chân: GND, VCC và đầu ra, trong ví dụ này, đầu ra được nối với chân Arduino 2 là chân ngắt ngoài (INT0). Cảm biến hồng ngoại cũng như IC LM393 được cung cấp nguồn 5V (đến từ board Arduino).

Thông tin thêm về IC LM393 tại đây.

CODE điều chỉnh ánh sáng điều khiển từ xa bằng Arduino:

Như được hiển thị trong sơ đồ mạch, đầu ra của bộ thu IR được kết nối với chân ngắt bên ngoài Arduino (chân số 2), có nghĩa là khi nhấn nút (từ điều khiển từ xa), Arduino bắt đầu đọc Tín hiệu hồng ngoại ngay lập tức.

Điều khiển từ xa được sử dụng trong ví dụ này sử dụng giao thức RC-5, thông báo mã RC-5 dài 14 bit:

2 bit start, 1 bit chuyển đổi, 5 bit địa chỉ và 6 bit lệnh. 2 bit (bit start) luôn là 1 và bit chuyển đổi có thể là 1 hoặc 0.

Trong dự án này, tôi đã không sử dụng 2 bit start và bit chuyển đổi vì chúng không có tác dụng (cũng để đơn giản hóa code). Tôi đã sử dụng một điều khiển từ xa TV có nghĩa là tất cả các bit địa chỉ là 0 (address = 0).

Những gì còn lại là phần quan trọng trong mã RC-5 là số lệnh, tôi đã sử dụng hai nút. nút đầu tiên có mã = ​​0x10, nó tăng cường độ ánh sáng và nút thứ hai có mã = ​​0x11 làm giảm cường độ ánh sáng. Các nút khác của điều khiển từ xa không có tác dụng đối với mạch này.

Tần số của nguồn AC của tôi là 50Hz, có nghĩa là khoảng thời gian là 20ms, vì vậy chu kỳ nửa sóng là 10ms = 10000 us.

CODE Arduino đầy đủ:

// Arduino light dimmer with IR remote control
// 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);

}

VIDEO demo:

 

 

 

 

 

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *