Поделитесь мыслями по коду
- Войдите на сайт для отправки комментариев
Ср, 01/07/2020 - 19:57
Всем доброго!
Имеется задача: В программе имеется несколько действий, запускаемых ИК-пультами. Например: ВКЛ, ВЫКЛ, ВВЕРХ, ВНИЗ. ИК-пультов может быть несколько, разных производителей. Посылают они свой адрес и команду.
#define ПУЛЬТ_1 0х1111
#define ПУЛЬТ_2 0х2222
#define ПУЛЬТ_3 0х3333
#define ВКЛ_1 0х01
#define ВЫКЛ_1 0х02
#define ВВЕРХ_1 0х03
#define ВНИЗ_1 0х04
#define ВКЛ_2 0хС1
#define ВЫКЛ_2 0хС2
#define ВВЕРХ_2 0хС3
#define ВНИЗ_2 0хС4
#define ВКЛ_3 0хA1
#define ВЫКЛ_3 0хA2
#define ВВЕРХ_3 0хA3
#define ВНИЗ_3 0хA4
void Пришел_сигнал(uint16_t адрес, uint16_t команда) {
if (адрес == ПУЛЬТ_1) {
switch (команда) {
ВКЛ_1 { Действие 1 }
ВЫКЛ_1 { Действие 2 }
ВВЕРХ_1 { Действие 3 }
ВНИЗ_1 { Действие 4 }
}
}
if (адрес == ПУЛЬТ_2) {
switch (команда) {
ВКЛ_2 { Действие 1 }
ВЫКЛ_2 { Действие 2 }
ВВЕРХ_2 { Действие 3 }
ВНИЗ_2 { Действие 4 }
}
}
if (адрес == ПУЛЬТ_3) {
switch (команда) {
ВКЛ_3 { Действие 1 }
ВЫКЛ_3 { Действие 2 }
ВВЕРХ_3 { Действие 3 }
ВНИЗ_3 { Действие 4 }
}
}
}
void Действие 1() {
...
}
void Действие 2() {
...
}
void Действие 3() {
...
}
void Действие 4() {
...
}
Сейчас у меня так сделано. Вот думаю, как бы это всё оптимизировать, если будут появляться новые действия и пульты? Есть у кого рекомендации?
Указатели на функции действий - в массив. Можно в паре с кодом команды. Эти коды сами выбираете? Так номеруйте их подряд, проще жить будет. Не совсем понятно, если как в примере, коды команд уникальны, зачем адреса пульта?
Не совсем понятно, если как в примере, коды команд уникальны, зачем адреса пульта?
Команда ВКЛ одного пульта может совпасть с ВЫКЛ другой, поэтому адреса нужно сверять.
Указатели на функции действий - в массив.
Спасибо за идею. Пока не соображу как мне это может помочь.
Т.е. команды не уникальны, а пара адрес-команда уникальна. Каждой функции Действие ххх(), соответствует одна или несколько пар адрес-команда? тогда делаете структуру из 3-х полей адрес, команда и указатель на функцию соответствующего ей Действие ххх(). И массив из таких структур. А в Пришел_сигнал будет просто поиск в этом массиве по совпадению адрес, команда и вызов соответствующей Действие ххх() по указател. Можно и по забористей и по экономичнее придумать. То самый простой подход.
А нужно было подумать, зачем вообще оптимизировать то что и так работает.
А нужно было подумать, зачем вообще оптимизировать то что и так работает.
В целях самообразования :)
делаете структуру из 3-х полей адрес, команда и указатель на функцию соответствующего ей Действие ххх(). И массив из таких структур.
Вот, что сварганил
#define CMD_COUNT 4 #define PULT_1 0x10 #define PULT_2 0x20 #define PULT_3 0x30 struct IR_DATA { uint16_t cmd; void (*pfn_my)(); }; void fn_UP() { Serial.print("UP"); } void fn_DN() { Serial.print("DN"); } void fn_LEFT() { Serial.print("LEFT"); } void fn_RIGHT() { Serial.print("RIGHT"); } IR_DATA Pult[][CMD_COUNT] = {{0x123, *fn_UP, 0x124, *fn_DN, 0x125, *fn_LEFT, 0x126, *fn_RIGHT}, {0x127, *fn_UP, 0x123, *fn_DN, 0x120, *fn_LEFT, 0x124, *fn_RIGHT}, {0x122, *fn_UP, 0x126, *fn_DN, 0x123, *fn_LEFT, 0x121, *fn_RIGHT}}; void setup() { Serial.begin(9600); } void loop() { Check_IR(PULT_1, 0x123); delay(1000); Check_IR(PULT_2, 0x123); delay(1000); Check_IR(PULT_3, 0x123); delay(1000); Check_IR(PULT_1, 0x126); delay(1000); } void Check_IR(uint16_t ir_adr, uint16_t ir_cmd) { uint8_t col = 0; switch (ir_adr) { case PULT_1: col = 0; break; case PULT_2: col = 1; break; case PULT_3: col = 2; break; } for (uint8_t n = 0; n < CMD_COUNT; n++) { if (Pult[col][n].cmd == ir_cmd) { Pult[col][n].pfn_my(); break; } } }Пультов не много, решил адреса не вносить в структуру. Код смотрится компактнее, но не знаю, конкретно в этом случае есть ли выигрыш? Оперативки чутка потратил.
Конечно есть! При наращивании кол-ва команд сразу проявится. Каждая новая команда - один элемент в массив, всего 4 байта. Такой компактности тяжело добиться другими способами. Чтоб не тратить оперативку Pult в progmem закинуть можно.