====== Сканер ИК-пультов с записью на SD-карту ====== **[[arduino-projects:start|Проекты на Arduino Uno и Slot Shield]]** {{ :arduino-projects:ir-remote-with-noise-sensor:smarthomefin2.png |}} Устройство построено на оригинальной [[amp>product/arduino-uno?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|Arduino Uno]]. Плата управляет бытовой техникой с помощью [[amp>product/troyka-ir-transmitter-5mm-led-module?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|ИК-передатчика]]. Коды команд управления заранее считываются [[amp>product/troyka-ir-receiver?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|ИК-приёмником]] с родного пульта и сохраняются на microSD. Сохранённую команду можно запустить из консоли монитора порта. * Платформы: [[amp>product/arduino-uno?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|Arduino Uno]], [[amp>product/arduino-leonardo?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|Arduino Leonardo]], [[amp>product/iskra-neo?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|Iskra Neo]] * Язык программирования: Arduino (C++) ===== Видеоинструкция ===== {{youtube>vK16efpSEi8?large}} ===== Что потребуется ===== [[amp>collection/ir-remote?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki | Полный сет]] компонентов проекта. В сет входят: * [[amp>product/arduino-uno?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|Arduino Uno]] * [[amp>product/arduino-troyka-slot-shield?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|Troyka Slot Shield]] * [[amp>product/troyka-ir-transmitter-5mm-led-module?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|ИК-передатчик]] * [[amp>product/troyka-ir-receiver?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|ИК-приёмник]] * [[amp>product/troyka-sd?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|SD-картридер]] ===== Как собрать ===== Установите [[amp>product/arduino-troyka-slot-shield?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|Troyka Slot Shield]] на [[amp>product/arduino-uno?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|Arduino Uno]] {{ :arduino-projects:ir-remoute-with-temperature-sensor:smarthome0.png |}} Вставьте [[amp>product/troyka-ir-receiver?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|ИК-приёмник]] в разъём ''С''. Ножка ''S'' должна подключится к пину ''4''. Аналогично подключите [[amp>product/troyka-ir-transmitter-5mm-led-module?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|ИК-передатчик]] к пину ''9'' слота ''E''. {{ :arduino-projects:ir-remoute-with-temperature-sensor:smarthome1.png |}} Подключите [[amp>product/troyka-sd?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|SD-картридер]] к пинам ''SPI'' слота ''D''. {{ :arduino-projects:ir-remoute-with-temperature-sensor:smarthome2.png |}} ===== Скетч ===== [[articles:arduino-ide-install|Как прошить контроллер через Arduino IDE]]. Оперативной памяти Arduino Uno не хватает для одновременной работы сканера и SD-карты. Поэтому приходится разбить задачу на два скетча. С помощью первого просканируем коды команд пульта дистанционного управления и сохраним их в текстовые файлы на SD-карту. // Библиотека для работы с SPI #include // Библиотека для работы с SD-картами #include // Библиотека для работы с ИК-приёмником и передатчиком #include // Имя пина, которому подключен приёмник #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\""); } } Чтобы вызвать записанные команды из памяти, прошейте плату вторым скетчем. // Библиотека для работы с SPI #include // Библиотека для работы с SD-картами #include // Библиотека для работы с ИК-приёмником и передатчиком #include // Имя пина, которому подключен приёмник #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-projects:ir-remote-with-temperature-sensor:arduino-irremote.7z |}} * [[программирование:библиотеки|Как устанавливать библиотеки]] ===== Что дальше ===== * Добавьте [[amp>product/arduino-power-shield-li-ion?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|Power Shield]] — контроллер можно будет переносить по разным помещениям. * Вставьте устройство в корпус из #cтруктора. [[amp>product/structor-slot-box?utm_source=proj&utm_campaign=arduino-slot-proj-17&utm_medium=wiki|Slot Box]] придаст игре законченный вид.