Сканер ИК-пультов с записью на SD-карту
Проекты на Arduino Uno и Slot Shield
Устройство построено на оригинальной Arduino Uno. Плата управляет бытовой техникой с помощью ИК-передатчика. Коды команд управления заранее считываются ИК-приёмником с родного пульта и сохраняются на microSD. Сохранённую команду можно запустить из консоли монитора порта.
- Язык программирования: Arduino (C++)
Видеоинструкция
Что потребуется
Полный сет компонентов проекта. В сет входят:
Как собрать
Установите Troyka Slot Shield на Arduino Uno
Вставьте ИК-приёмник в разъём С
. Ножка S
должна подключится к пину 4
. Аналогично подключите ИК-передатчик к пину 9
слота E
.
Подключите SD-картридер к пинам SPI
слота D
.
Скетч
Как прошить контроллер через Arduino IDE.
Оперативной памяти Arduino Uno не хватает для одновременной работы сканера и SD-карты. Поэтому приходится разбить задачу на два скетча. С помощью первого просканируем коды команд пульта дистанционного управления и сохраним их в текстовые файлы на SD-карту.
- ir-remote-with-sd-scan.ino
// Библиотека для работы с SPI #include <SPI.h> // Библиотека для работы с SD-картами #include <SD.h> // Библиотека для работы с ИК-приёмником и передатчиком #include <IRremote.h> // Имя пина, которому подключен приёмник #define RECV_PIN 4 // Имя пина, к которому подключен передатчик #define SEND_PIN 9 // Имя для CS пина microSD-карты #define SD_CS_PIN 8 // Строка с хранением данных введенных в последовательный порт #define command_S1 "C_S1.txt" #define command_S2 "C_S2.txt" #define command_S3 "C_S3.txt" #define command_S4 "C_S4.txt" // Создаём объект для ИК-приёмника IRrecv irrecv(RECV_PIN); // Создаём объект для ИК-передатчика IRsend irsend; // Создаём объект для декодированных команд с ИК-пульта decode_results results; // Строка с хранением данных введенных в последовательный порт String command = ""; void setup() { // открываем последовательный порт Serial.begin(9600); // Запускаем работу ИК-приёмника irrecv.enableIRIn(); // выводим сообщение в Serial-порт о поиске карты памяти Serial.println("Initializing SD card..."); // если microSD-карта не была обнаружена if (!SD.begin(SD_CS_PIN)) { // выводим сообщение об ошибке Serial.println("Card failed, or not present"); // завершаем процесс return; } else { Serial.println("Card initialized."); } } void loop() { // пока в Serial port поступают символы... while (Serial.available() > 0) { // ...символ записываем в переменную char symbol = Serial.read(); // если приходит символ разрыва строки... if (symbol == '\n') { // выводим полученную команду Serial.println(command); // идентифицируем полученную команду if ( command == "RC_S1") { // удаляем предыдущую команду SD.remove(command_S1); // если пришла команда C_S1, выполняем отправку соответствующей команды reading (&results, command_S1); // выводим сообщение об отправке Serial.println("Signal \"C_S1\" sent."); } else if (command == "RC_S2") { // удаляем предыдущую команду SD.remove(command_S2); // если пришла команда C_S2, выполняем отправку соответствующей команды reading (&results, command_S2); // выводим сообщение об отправке Serial.println("Signal \"C_S2\" sent."); } else if (command == "RC_S3") { // удаляем предыдущую команду SD.remove(command_S3); // если пришла команда C_S3, выполняем отправку соответствующей команды reading (&results, command_S3); // выводим сообщение об отправке Serial.println("Signal \"C_S3\" sent."); } else if (command == "RC_S4") { // удаляем предыдущую команду SD.remove(command_S4); // если пришла команда C_S4, выполняем отправку соответствующей команды reading (&results, command_S4); // выводим сообщение об отправке Serial.println("Signal \"C_S4\" sent."); } command = ""; } else { // ... если символ не является символом разрыва строки, то вписываем его в последовательность command += symbol; } } } // функция режима "чтение ИК-сигнала" void reading (decode_results *results, String command) { // создаём файл для записи File dataWrine = SD.open(command, FILE_WRITE); // если файл доступен для записи if (dataWrine) { // "Введите команду с пульта дистанционного управления" Serial.println("Enter the command from the remote control. "); while (1) { // ожидаем, пока придет команда с пульта if (irrecv.decode(results)) { for (int i = 1; i < results->rawlen; i++) { dataWrine.print(results->rawbuf[i] *USECPERTICK, DEC); dataWrine.print(' '); } break; } } dataWrine.close(); // перезапустим ИК-приёмник irrecv.resume(); } else { // если файл не доступен Serial.println("Error opening in \"reading\""); } }
Чтобы вызвать записанные команды из памяти, прошейте плату вторым скетчем.
- ir-remote-with-sd-send.ino
// Библиотека для работы с SPI #include <SPI.h> // Библиотека для работы с SD-картами #include <SD.h> // Библиотека для работы с ИК-приёмником и передатчиком #include <IRremote.h> // Имя пина, которому подключен приёмник #define RECV_PIN 4 // Имя пина, к которому подключен передатчик #define SEND_PIN 9 // Имя для CS пина microSD-карты #define SD_CS_PIN 8 // Строка с хранением данных введенных в последовательный порт #define command_S1 "C_S1.txt" #define command_S2 "C_S2.txt" #define command_S3 "C_S3.txt" #define command_S4 "C_S4.txt" // Создаём объект для ИК-передатчика IRsend irsend; // Частота (КГц) с которой будут передаваться сигналы int khz = 38; // Строка с хранением данных введенных в последовательный порт String command = ""; void setup() { // открываем последовательный порт Serial.begin(9600); // выводим сообщение в Serial-порт о поиске карты памяти Serial.println("Initializing SD card..."); // если microSD-карта не была обнаружена if (!SD.begin(SD_CS_PIN)) { // выводим сообщение об ошибке Serial.println("Card failed, or not present"); // завершаем процесс return; } else { Serial.println("Card initialized."); } } void loop() { // пока в Serial port поступают символы... while (Serial.available() > 0) { // ...символ записываем в переменную char symbol = Serial.read(); // если приходит символ разрыва строки... if (symbol == '\n') { // выводим полученную команду Serial.println(command); // идентифицируем полученную команду if ( command == "C_S1") { // если пришла команда C_S1, выполняем отправку соответствующей команды sending (command_S1); // выводим сообщение об отправке Serial.println("Signal \"C_S1\" sent."); } else if (command == "C_S2") { // если пришла команда C_S2, выполняем отправку соответствующей команды sending (command_S2); // выводим сообщение об отправке Serial.println("Signal \"C_S2\" sent."); } else if (command == "C_S3") { // если пришла команда C_S3, выполняем отправку соответствующей команды sending (command_S3); // выводим сообщение об отправке Serial.println("Signal \"C_S3\" sent."); } else if (command == "C_S4") { // если пришла команда C_S4, выполняем отправку соответствующей команды sending (command_S4); // выводим сообщение об отправке Serial.println("Signal \"C_S4\" sent."); } command = ""; } else { // ... если символ не является символом разрыва строки, то вписываем его в последовательность command += symbol; } } } // функция отправки ИК-команд void sending (String command) { // создаём файл для отправки File dataRead = SD.open(command, FILE_READ); // если файл доступен для чтения if (dataRead) { // промежуточный массив для декодирования символов int num [6]; // счетчик степеней декодированного сигнала int count = 0; // счетчик массива сигналов int j = 0; // пока считываются данные из файла while (dataRead.available()) { // записываем из файла посимвольно данные в промежуточный массив for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++) { // переменная для хранения полученного символа char point = dataRead.read(); if (point == ' ') { break; } else { // преобразуем полученные символы в числа num[i] = point - '0'; count++; } } // преобразуем массив с отдельными числами в единый сигнал и записываем его в массив for (int i = 0; i < count; i++) { irparams.rawbuf[j] += num[i] * ceil (pow(10, count - i - 1)); } // переходим к следующему элементу массива j++; count = 0; } // отправляем массив сигналов irsend.sendRaw(irparams.rawbuf, sizeof(irparams.rawbuf) / sizeof(irparams.rawbuf[0]), khz); // после отправки очищаем массив for (int i = 0; i < sizeof(irparams.rawbuf) / sizeof(irparams.rawbuf[0]); i++) { irparams.rawbuf[i] = 0; } // закрываем файл dataRead.close(); } else { // если файл не доступен Serial.println("Error opening in \"sending\""); } }
Часто задаваемые вопросы
Где скачать необходимые библиотеки и как их установить?
- Библиотека эмуляции ИК-пультов: arduino-irremote.7z
Что дальше
- Добавьте Power Shield — контроллер можно будет переносить по разным помещениям.
- Вставьте устройство в корпус из #cтруктора. Slot Box придаст игре законченный вид.