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 pwm_flag = false; /* to trigger a PWM tick */
|
||||
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 */
|
||||
ISR(USART_RX_vect) {
|
||||
|
@ -208,6 +210,115 @@ void ioinit(void)
|
|||
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)
|
||||
{
|
||||
ioinit(); /* initialize IOs */
|
||||
|
@ -234,8 +345,11 @@ int main(void)
|
|||
puts("can't store setting");
|
||||
return 0;
|
||||
}
|
||||
puts("settings created");
|
||||
} else {
|
||||
load_settings();
|
||||
puts("settings loaded");
|
||||
}
|
||||
load_settings();
|
||||
|
||||
while (true) {
|
||||
/* calculated PWM values */
|
||||
|
@ -276,7 +390,16 @@ int main(void)
|
|||
c = input[command_i++];
|
||||
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;
|
||||
}
|
||||
/* handle power state */
|
||||
|
@ -308,7 +431,18 @@ int main(void)
|
|||
ir_repeat = 0;
|
||||
}
|
||||
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 */
|
||||
|
@ -318,82 +452,40 @@ int main(void)
|
|||
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)
|
||||
{
|
||||
if (0==address && 72==command) {
|
||||
printf("switching power supply ");
|
||||
if (PINB&(1<<nPS_ON)) {
|
||||
puts("on");
|
||||
} else {
|
||||
puts("off");
|
||||
enum IR_ACTIONS ir_code = IR_ACTION_END;
|
||||
for (ir_code=0; ir_code<IR_ACTION_END; ir_code++) {
|
||||
if (ir_keys[ir_code][0]==address && ir_keys[ir_code][1]==command) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
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 {
|
||||
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 */
|
||||
|
||||
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);
|
||||
|
|
|
@ -9,8 +9,8 @@ enum IR_ACTIONS { /* the actions for the infrared remote control */
|
|||
MODE,
|
||||
BRIGHTNESS_UP,
|
||||
BRIGHTNESS_DOWN,
|
||||
CHANNEL_UP,
|
||||
CHANNEL_DOWN,
|
||||
CHANNEL_NEXT,
|
||||
CHANNEL_PREVIOUS,
|
||||
IR_ACTION_END
|
||||
};
|
||||
extern uint8_t ir_keys[IR_ACTION_END][2]; // the IR NEC values (address+command) for the actions
|
||||
|
|
Loading…
Reference in New Issue