Uzaktan Kumandalı AC Dimmer

Bir reklamda "tembel adam yaratı olur" diyordu. Bu projemizin çıkış nedeni de biraz tembellik aslında. Bazen uzanmış yatıyor olursunuz ve tavandaki aydınlatma tam gözünüze gelir. Okuma lambanız yoksa yatağa uzanıp kitap okumak istersiniz ama sonra kalkıp ışığı kapatmaya üşenirsiniz. Bu sorunları yaşayanlar için uzaktan kumandalı duy olduğunu görmüştüm ama çok verimli çalışmadığını okudum. Kendim yapayım diye düşündüm ve aşağıdaki kart ortaya çıktı. Parlaklığı arttırıp azaltırken biraz oynama yapıyor ama onun dışında kumanda algılaması ve çalışması gayet iyi.

Uygulamada MSP430 işlemcisi kullanıldı. Kartın avizelere de monte edilebilir olması için az yer kaplaması istiyordum. Bu yüzden güç kaynağı koymadım ve pil ile çalıştırdım. MSP430 pilli uygulamalarda kendini ispatlamış bir mikrodenetleyici. Uyku modunda yalnızca 0,85mA akım tüketiyor. Çalışma anında ise 2,5mA civarında. Uzaktan kumanda alıcısında yapılacak bir iyileştirme ile bu tüketim çok daha aşağılara düşebilir.

Devrenin şeması şöyle. Bu uygulama için daha az pini olan bir işlemci kullanılabilirdi ama fiyat olarak MSP430G2553 işlemcisinden daha pahalı oldukları için bunu seçtim.

Kızılötesi alıcı ve vericiyi set halinde bulabilirsiniz. Veya sadece alıcıyı bağlayıp evdeki atıl durumda bekleyen veya aktif kullanılan herhangi bir kumanda ile çalışacak hale getirebilirsiniz.

Uygulamanın kodu şu şekilde. Kızılötesi kütüphanesini diğer projelerdeki uygulamalardan alabilirsiniz.


/* Created on: 13 Eki 2014
 * Author: Soner SEZGİN-
 * EXP: MSP430 controller digital dimmer.
 * 		Dimming is set by IR remote controller and/or up and down buttons
 * 		Need to know IR button code and set to ir.h file.
 * 		Library supports NEC type IR controllers only.
 * 		IR library is needed to be modify to support other type protocols.
 * 		IR timer is set to 50usec with DCO clock in RUN mode
 * 		and it is set to 1000usec with ACLK in IDLE mode to save power
 *
 * 		AC ON  + OUT OFF + IR OFF = 1,17mA
 * 		AC ON  + OUT OFF + IR ON  = 3,92mA
 * 		AC ON  + OUT ON  + IR OFF = 2,50mA
 * 		AC ON  + OUT ON  + IR ON  = 3,90mA
 * 		AC OFF + OUT OFF + IR OFF = 0,85mA
 */
#include  
#include "main.h"
#include "ir.h"

#define IRPIN		BIT3
#define ZEROPASS	BIT1
#define DIMOUT		BIT2
#define UP			BIT4
#define DOWN		BIT3

#define TRIGHOLD		1
#define	STEP			2
#define MINDIM			106			//120-STEP-TRIGHOLD
#define MAXDIM			1
static unsigned int		ondelay = MAXDIM * 4;
static unsigned char	dimstate = ON;

#define ACLK		ON

#define PWM_START	{TA1CCTL1 = OUTMOD_3;	TA1R = 0; TA1CCR1 = ondelay; TA1CCR0 = ondelay+TRIGHOLD;}
#define PWM_STOP	{TA1CCTL1 = OUTMOD_0;	TA1CCTL1 &= ~OUT;}

static unsigned char cpustate = ON;

//IR global variables
static unsigned char repeated_cnt;
static unsigned long repeated_code;
extern irparams_t irparams;
static decode_results results;

void IR_Process(decode_results *results);
void InitPWM(void);

void main(void) {

    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer

    BCSCTL3 |= LFXT1S_2;
	BCSCTL1 = CALBC1_8MHZ;
	DCOCTL = CALDCO_8MHZ;

    P1DIR = 0xff;
    P1OUT = 0x00;
    P2DIR = 0xff & ~(ZEROPASS + UP + DOWN + IRPIN) ;
    P2DIR |= DIMOUT;
    P2REN |= UP + DOWN;
    P2OUT |= DIMOUT;
    P3DIR = 0xff;
    P3OUT = 0x00;

    P2DIR &= ~ZEROPASS;	// Set Zeropass Input
	P2IE  |= ZEROPASS;      // Zeropass pin interrupt enabled
	P2IES |= ZEROPASS;      // Interrupt Lo/Hi edge
	P2IFG &= ~ZEROPASS;     // Zeropass IFG cleared

	InitPWM();
	PWM_START;
	PWM_STOP;
	IR_SetInPin(IRPIN);
	IR_EnableIn();
	IR_InitTimer();
	
	__enable_interrupt();

	while(1){
		IR_ISR();

		if(IR_Decode(&results)){
			if(results.decode_type == NEC && irparams.rawlen < 70){
				IR_Process(&results);
			}
			else irparams.rawbuf[0] = 0;
		}
		cpustate = OFF;
		if(GetTimerState() == RUN1000u) LPM3;        // LPM3 with interrupts enabled
		else LPM0;
	}

}
void InitPWM(void){

//  Dimmer Board Configuration
	P2DIR |= DIMOUT;
	P2SEL |= DIMOUT;
	TA1CTL = TASSEL_1 + MC_2 ;			// ACLK, up mode
}

unsigned char GetCPUState(void){
	return cpustate;
}

void SetCPUState(unsigned char stat){
	cpustate = stat;
}

void IR_Process(decode_results *results){
	unsigned long ir_value;

	ir_value = results->value;

	if( ir_value != REPEAT){
		repeated_code = results->value;
		repeated_cnt = 0;
	}
	else{
		ir_value = repeated_code;
		repeated_cnt++;
	}

	switch(ir_value){
	case IR_UP:
		if(ondelay > (MAXDIM + STEP) ){
			ondelay -= STEP;
		}
		break;
	case IR_DOWN:
		if(ondelay < (MINDIM - STEP) ){
			ondelay += STEP;
		}
		break;
	case IR_OK:
		if(dimstate) dimstate =OFF;
		else dimstate = ON;
		break;
	}

	IR_resume();
}

#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
	P2IFG &= ~ZEROPASS;     // Zeropass IFG cleared
	if(dimstate) PWM_START;
}

İşte bu da videosu