Это самодельный универсальный пульт дистанционного управления, у которого можно запрограммировать до пяти кнопок. Пульт поддерживает самые популярные протоколы дистанционного управления: Philips RC-5, NEC, Samsung и Sony.
Пульт построен на микроконтроллере ATtiny85. При бездействии пульта схема переходит в спящий режим, обеспечивая продолжительный срок службы батареи питания.
Для управления инфракрасным светодиодом использована одна линия ввода/вывода ATtiny85, остальные четыре линии ввода/вывода предназначены для кнопок. Вывод сброса микроконтроллера можно использовать для подключения пятой кнопки.
Если вам нужно более пяти кнопок, вы можете сделать так, чтобы одна кнопка переключала между различными параметрами, или использовать одну кнопку для изменения режимов.
Принципиальная схема
Чтобы пульт дистанционного управления был как можно компактнее и имел плоское основание, было решено собрать его на SMD компонентах. Изначально планировалось сделать его длиннее и запитать от двух последовательно соединенных батареек ААА по 1,5 В.
Однако с появлением перезаряжаемых литиевых батареек формата AAA на 3,7 В, лучшим решением было использовать одну из них, чтобы уменьшить длину печатной платы. Вся схема размещена на печатной плате размером 10 мм x 100 мм.
В качестве ИК-светодиода использован SMD инфракрасный светодиод с длиной волны 940 нм, хотя подойдет любой ИК-светодиод. Зеленый светодиод, включенный параллельно с ИК-светодиодом, дает визуальную индикацию того, что ИК-пульт дистанционного управления работает.
Микроконтроллер ATtiny85 в корпусе SOIC, а остальные компоненты имеют размер 0805, поэтому их относительно легко паять вручную с помощью паяльника с тонким жалом.
Код программы меньше 1500 байт, поэтому вместо ATtiny85 можно использовать ATtiny25 или ATtiny45.
Программа
Генерация несущей
Все протоколы дистанционного управления работают на одинаковой несущей частоте от 36 кГц до 40 кГц. Точная частота кажется не критической, поэтому была выбрана частота 38,5 кГц. Она генерируется на OC1A (порт PB1) с использованием Timer/Counter1. Соотношение mark/space установлено примерно на уровне 25%, что снижает потребление тока ИК-светодиодом:
const int top = 25; // 1000000/26 = 38.5kHz const int match = 19; // 25% mark/space // Настраиваем Timer/Counter1 для вывода PCM на OC1A (PB1) void SetupPCM () { TCCR1 = 1<<PWM1A | 3<<COM1A0 | 1<<CS10; // Инвертированный выход ШИМ на OC1A делится на 1 OCR1C = top; // 38.5kHz OCR1A = top; // Держим выход на низком уровне }
Несущая может быть включена или выключена записью в регистр сравнения OCR1A.
Генерация кодов кнопок
Подпрограмма Send генерирует IR-код. Параметр IRtype указывает IR протокол следующим образом:
- N — NEC (32 бита)
- M — Samsung (32 бита)
- 12 — Sony 12 бит
- 15 — Sony 15 бит
- 20 — Sony 20 бит
- R — Philips RC-5 (14 бит)
void Send (char IRtype, unsigned int Address, unsigned int Command) { // Коды NEC или Samsung if ((IRtype == 'N') || (IRtype == 'M')) { unsigned long code = ((unsigned long) Command<<16 | Address); TCNT1 = 0; // Начинаем считать с 0 // Отправить стартовый импульс if (IRtype == 'N') Pulse(342, 171); else Pulse(190, 190); // Отправляем 32 бита for (int Bit=0; Bit<32; Bit++) if (code & ((unsigned long) 1<<Bit)) Pulse(21, 64); else Pulse(21, 21); Pulse(21, 0); // 12-, 15- или 20-битные коды Sony } else if (IRtype == 12 || IRtype == 15 || IRtype == 20) { unsigned long code = ((unsigned long) Address<<7 | Command); TCNT1 = 0; // Начинаем считать с 0 // Отправить стартовый импульс Pulse(96, 24); // Отправляем 12, 15 или 20 бит for (int Bit=0; Bit<IRtype; Bit++) if (code & ((unsigned long) 1<<Bit)) Pulse(48, 24); else Pulse(24, 24); // Код Philips RC-5 } else if (IRtype == 'R') { static int toggle = toggle ^ 1; int nextbit, extended = Command>>6 ^ 1; unsigned int code = 0x2000 | extended<<12 | toggle<<11 | Address<<6 | (Command & 0x3F); TCNT1 = 0; // Начинаем считать с 0 for (int b=0; b<14; b++) { nextbit = code>>(13-b) & 1; for (uint8_t i=0; i<2; i++) { if (nextbit) OCR1A = top; else OCR1A = match; // Ожидание 32 переполнений Timer/Counter1 for (int c=0; c<32; c++) { while ((TIFR & 1<<TOV1) == 0); TIFR = 1<<TOV1; // Очистить флаг переполнения } nextbit = !nextbit; } } OCR1A = top; // Оставляем вывод выключенным } }
Обнаружение кнопок
Четыре кнопки настроены на генерацию прерываний по изменению контакта. Затем процедура обслуживания прерывания просто проверяет, какая кнопка нажата, и отправляет ИК-код, назначенный этой кнопке:
// Процедура обслуживания прерывания смены контакта ISR (PCINT0_vect) { int in = PINB; if ((in & 1<<S1) == 0) Send('M', 0x0707, 0xFD02); else if ((in & 1<<S2) == 0) Send('M', 0x0707, 0xFB04); else if ((in & 1<<S4) == 0) Send('R', 0x0013, 0x0011); else if ((in & 1<<S5) == 0) Send('R', 0x0013, 0x0010); }
Пятая кнопка, S3, связана со сбросом. Код, назначенный этой кнопке, отправляется в Setup(). Обратите внимание, что в этом случае работа кнопки вступает в силу, когда вы отпускаете кнопку, тогда как другие четыре кнопки вступают в силу, когда вы нажимаете кнопку. Поэтому S3 — хороший выбор для кнопки изменения режима.
Компиляция программы
Программа скомпилирована с помощью Spence Konde ATTinyCore. Выберите опцию ATtiny25/45/85 под заголовком AttinyCore в меню Board. Затем выберите из последующих пунктов меню:
- Timer 1 Clock: CPU
- BOD Disabled
- ATtiny85
- 1 MHz (internal)
При необходимости выберите «Записать загрузчик», чтобы правильно установить фьюзы. Затем загрузите программу с помощью ISP (внутрисистемное программирование).
Скачать файлы проекта (10,1 KiB, скачано: 230)