can learn IR commands
This commit is contained in:
parent
7e86211c93
commit
2dba5b10d2
244
firmware/main.c
244
firmware/main.c
|
@ -62,6 +62,8 @@ volatile bool power_flag = false; /* a change in the power or fan */
|
||||||
volatile bool ir_flag = false; /* to process a burst */
|
volatile bool ir_flag = false; /* to process a burst */
|
||||||
volatile bool pwm_flag = false; /* to trigger a PWM tick */
|
volatile bool pwm_flag = false; /* to trigger a PWM tick */
|
||||||
volatile bool channel_flag = false; /* indicate a change in the channel PWM values */
|
volatile bool channel_flag = false; /* indicate a change in the channel PWM values */
|
||||||
|
volatile bool learn_flag = false; /* learn an IR command for an action */
|
||||||
|
enum IR_ACTIONS to_learn = IR_ACTION_END; /* IR action to learn */
|
||||||
|
|
||||||
/* UART receive interrupt */
|
/* UART receive interrupt */
|
||||||
ISR(USART_RX_vect) {
|
ISR(USART_RX_vect) {
|
||||||
|
@ -208,6 +210,115 @@ void ioinit(void)
|
||||||
sei(); /* enable interrupts */
|
sei(); /* enable interrupts */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void help(void)
|
||||||
|
{
|
||||||
|
printf("commands:\n"\
|
||||||
|
"\thelp display this help\n"\
|
||||||
|
"\tpower show power state\n"\
|
||||||
|
"\tpower on switch power on\n"\
|
||||||
|
"\tpower off switch power off\n"\
|
||||||
|
"\tfan show fan speed\n"\
|
||||||
|
"\tch X Y show channel [1-2].[1-5] brightness\n"\
|
||||||
|
"\tch X Y Z set channel [1-2].[1-5] brightness [0-255]\n"\
|
||||||
|
"\tir learn power learn the IR command to power on/off\n"\
|
||||||
|
"\tir learn mode learn the IR command to change between modes\n"\
|
||||||
|
"\tir learn brightness up learn the IR command to increase brightness\n"\
|
||||||
|
"\tir learn brightness down learn the IR command to decrease brightness\n"\
|
||||||
|
"\tir learn channel next learn the IR command to select next channel\n"\
|
||||||
|
"\tir learn channel previous learn the IR command to select previous channel\n"\
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_action(char* str)
|
||||||
|
{
|
||||||
|
const char* delimiter = " ";
|
||||||
|
char* word = strtok(str,delimiter);
|
||||||
|
if (!word) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (0==strcmp(word,"help")) {
|
||||||
|
help();
|
||||||
|
} else if (0==strcmp(word,"power")) {
|
||||||
|
word = strtok(NULL,delimiter);
|
||||||
|
if (!word) {
|
||||||
|
if (PINB&(1<<nPS_ON)) {
|
||||||
|
puts("power is off");
|
||||||
|
} else {
|
||||||
|
puts("power is on");
|
||||||
|
}
|
||||||
|
} else if (0==strcmp(word,"on")) {
|
||||||
|
PORTB &= ~(1<<nPS_ON);
|
||||||
|
} else if (0==strcmp(word,"off")) {
|
||||||
|
PORTB |= (1<<nPS_ON);
|
||||||
|
} else {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else if (0==strcmp(word,"fan")) {
|
||||||
|
if (tachometer) {
|
||||||
|
uint16_t prescale = TIMER2_PRESCALE[TCCR2B&((1<<CS22)|(1<<CS21)|(1<<CS20))];
|
||||||
|
if (prescale) {
|
||||||
|
if (timer2_ovf<0xff) {
|
||||||
|
uint32_t speed = ((60*F_CPU)/(prescale*(uint32_t)tachometer))/2; // calculate speed. 2 pulses per revolution
|
||||||
|
printf("fan speed: %lurpm\n",speed);
|
||||||
|
} else {
|
||||||
|
printf("fan is off (or not detected)\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("fan speed measurement not started\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("fan is off (or not detected)\n");
|
||||||
|
}
|
||||||
|
} else if (0==strcmp(word,"ir")) {
|
||||||
|
word = strtok(NULL,delimiter);
|
||||||
|
if (0==strcmp(word,"learn")) {
|
||||||
|
word = strtok(NULL,delimiter);
|
||||||
|
if (0==strcmp(word,"power")) {
|
||||||
|
to_learn = POWER;
|
||||||
|
learn_flag = true;
|
||||||
|
} else if (0==strcmp(word,"mode")) {
|
||||||
|
to_learn = MODE;
|
||||||
|
learn_flag = true;
|
||||||
|
} else if (0==strcmp(word,"brightness")) {
|
||||||
|
word = strtok(NULL,delimiter);
|
||||||
|
if (0==strcmp(word,"up")) {
|
||||||
|
to_learn = BRIGHTNESS_UP;
|
||||||
|
learn_flag = true;
|
||||||
|
} else if (0==strcmp(word,"down")) {
|
||||||
|
to_learn = BRIGHTNESS_DOWN;
|
||||||
|
learn_flag = true;
|
||||||
|
} else {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else if (0==strcmp(word,"channel")) {
|
||||||
|
word = strtok(NULL,delimiter);
|
||||||
|
if (0==strcmp(word,"next")) {
|
||||||
|
to_learn = CHANNEL_NEXT;
|
||||||
|
learn_flag = true;
|
||||||
|
} else if (0==strcmp(word,"previous")) {
|
||||||
|
to_learn = CHANNEL_PREVIOUS;
|
||||||
|
learn_flag = true;
|
||||||
|
} else {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (learn_flag) {
|
||||||
|
puts("press button on remote to learn code");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
error:
|
||||||
|
puts("command not recognized");
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
ioinit(); /* initialize IOs */
|
ioinit(); /* initialize IOs */
|
||||||
|
@ -234,8 +345,11 @@ int main(void)
|
||||||
puts("can't store setting");
|
puts("can't store setting");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
puts("settings created");
|
||||||
|
} else {
|
||||||
|
load_settings();
|
||||||
|
puts("settings loaded");
|
||||||
}
|
}
|
||||||
load_settings();
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
/* calculated PWM values */
|
/* calculated PWM values */
|
||||||
|
@ -276,7 +390,16 @@ int main(void)
|
||||||
c = input[command_i++];
|
c = input[command_i++];
|
||||||
putchar(c);
|
putchar(c);
|
||||||
}
|
}
|
||||||
uart_action(c);
|
if ('\n'==c || '\r'==c) {
|
||||||
|
if ('\r'==c) {
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
if (command_i>1) {
|
||||||
|
input[command_i-1] = '\0';
|
||||||
|
uart_action(input);
|
||||||
|
}
|
||||||
|
input_i = command_i = 0;
|
||||||
|
}
|
||||||
uart_flag = false;
|
uart_flag = false;
|
||||||
}
|
}
|
||||||
/* handle power state */
|
/* handle power state */
|
||||||
|
@ -308,7 +431,18 @@ int main(void)
|
||||||
ir_repeat = 0;
|
ir_repeat = 0;
|
||||||
}
|
}
|
||||||
if (ir_repeat==0 || ir_repeat>3) {
|
if (ir_repeat==0 || ir_repeat>3) {
|
||||||
ir_action(ir_data.address,ir_data.command);
|
if (learn_flag) {
|
||||||
|
if (to_learn<IR_ACTION_END) {
|
||||||
|
ir_keys[to_learn][0] = ir_data.address;
|
||||||
|
ir_keys[to_learn][1] = ir_data.command;
|
||||||
|
}
|
||||||
|
save_settings();
|
||||||
|
puts("IR code learned");
|
||||||
|
to_learn = IR_ACTION_END;
|
||||||
|
learn_flag = false;
|
||||||
|
} else {
|
||||||
|
ir_action(ir_data.address,ir_data.command);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pulse = 0; /* reset burst */
|
pulse = 0; /* reset burst */
|
||||||
|
@ -318,82 +452,40 @@ int main(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_action(char c)
|
|
||||||
{
|
|
||||||
switch (c) {
|
|
||||||
case 'l':
|
|
||||||
PIND |= (1<<LED);
|
|
||||||
printf("LED: ");
|
|
||||||
if (PIND&(1<<LED)) {
|
|
||||||
puts("off");
|
|
||||||
} else {
|
|
||||||
puts("on");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
printf("switching power supply ");
|
|
||||||
if (PINB&(1<<nPS_ON)) {
|
|
||||||
puts("on");
|
|
||||||
} else {
|
|
||||||
puts("off");
|
|
||||||
}
|
|
||||||
PINB |= (1<<nPS_ON);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
printf("power: ");
|
|
||||||
if (PINB&(1<<PWR_OK)) {
|
|
||||||
puts("ok");
|
|
||||||
} else {
|
|
||||||
puts("ko");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '1':
|
|
||||||
//ch_1[0] = (ch_1[0]+1)%(LEVELS+1);
|
|
||||||
channel_flag = true;
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
if (OCR0A>0) {
|
|
||||||
OCR0A--;
|
|
||||||
}
|
|
||||||
printf("decreasing LED: %u\n",OCR0A);
|
|
||||||
break;
|
|
||||||
case '+':
|
|
||||||
if (OCR0A<0xff) {
|
|
||||||
OCR0A++;
|
|
||||||
}
|
|
||||||
printf("increasing LED: %u\n",OCR0A);
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
if (tachometer) {
|
|
||||||
uint16_t prescale = TIMER2_PRESCALE[TCCR2B&((1<<CS22)|(1<<CS21)|(1<<CS20))];
|
|
||||||
if (prescale) {
|
|
||||||
if (timer2_ovf<0xff) {
|
|
||||||
uint32_t speed = ((60*F_CPU)/(prescale*(uint32_t)tachometer))/2; /* calculate speed. 2 pulses per revolution */
|
|
||||||
printf("fan speed: %lurpm\n",speed);
|
|
||||||
} else {
|
|
||||||
printf("fan off (or not detected)\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("fan speed measurement not started\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("fan off (or not detected)\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ir_action(uint8_t address, uint8_t command)
|
void ir_action(uint8_t address, uint8_t command)
|
||||||
{
|
{
|
||||||
if (0==address && 72==command) {
|
enum IR_ACTIONS ir_code = IR_ACTION_END;
|
||||||
printf("switching power supply ");
|
for (ir_code=0; ir_code<IR_ACTION_END; ir_code++) {
|
||||||
if (PINB&(1<<nPS_ON)) {
|
if (ir_keys[ir_code][0]==address && ir_keys[ir_code][1]==command) {
|
||||||
puts("on");
|
break;
|
||||||
} else {
|
}
|
||||||
puts("off");
|
}
|
||||||
|
if (ir_code<IR_ACTION_END) {
|
||||||
|
switch (ir_code) {
|
||||||
|
case POWER:
|
||||||
|
printf("switching power supply ");
|
||||||
|
if (PINB&(1<<nPS_ON)) {
|
||||||
|
puts("on");
|
||||||
|
} else {
|
||||||
|
puts("off");
|
||||||
|
}
|
||||||
|
PINB |= (1<<nPS_ON);
|
||||||
|
break;
|
||||||
|
case MODE:
|
||||||
|
break;
|
||||||
|
case BRIGHTNESS_UP:
|
||||||
|
break;
|
||||||
|
case BRIGHTNESS_DOWN:
|
||||||
|
break;
|
||||||
|
case CHANNEL_NEXT:
|
||||||
|
break;
|
||||||
|
case CHANNEL_PREVIOUS:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unhandled IR action: %u\n", ir_code);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
PINB |= (1<<nPS_ON);
|
|
||||||
} else {
|
} else {
|
||||||
printf("IR addr: %u, command: %u\n", address, command);
|
puts("IR command not learned");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,5 +31,6 @@ extern volatile uint8_t* DDRS[CHANNELS_1+CHANNELS_2]; /* channel I/O configurati
|
||||||
extern const uint8_t BITS[CHANNELS_1+CHANNELS_2]; /* channel bits */
|
extern const uint8_t BITS[CHANNELS_1+CHANNELS_2]; /* channel bits */
|
||||||
|
|
||||||
void ioinit(void);
|
void ioinit(void);
|
||||||
void uart_action(char c);
|
void help(void);
|
||||||
|
void uart_action(char* str);
|
||||||
void ir_action(uint8_t address, uint8_t command);
|
void ir_action(uint8_t address, uint8_t command);
|
||||||
|
|
|
@ -9,8 +9,8 @@ enum IR_ACTIONS { /* the actions for the infrared remote control */
|
||||||
MODE,
|
MODE,
|
||||||
BRIGHTNESS_UP,
|
BRIGHTNESS_UP,
|
||||||
BRIGHTNESS_DOWN,
|
BRIGHTNESS_DOWN,
|
||||||
CHANNEL_UP,
|
CHANNEL_NEXT,
|
||||||
CHANNEL_DOWN,
|
CHANNEL_PREVIOUS,
|
||||||
IR_ACTION_END
|
IR_ACTION_END
|
||||||
};
|
};
|
||||||
extern uint8_t ir_keys[IR_ACTION_END][2]; // the IR NEC values (address+command) for the actions
|
extern uint8_t ir_keys[IR_ACTION_END][2]; // the IR NEC values (address+command) for the actions
|
||||||
|
|
Loading…
Reference in New Issue