Здравствуйте. Разрабатываю прототип ик-датчика препятствия. Моя идея базируется на использовании ШИМ технологии в качестве замены подстроечного резистора. Датчик работает по принципу: обнаружен барьер – загорается красный светодиод. Я уже достиг некоторых результатов, научился работать с ик-приемником (vs1838) и принимать сигналы с ик-пульта. Нынешняя задача заключается в том, чтобы отправить уникальный сигнал через ик-светодиод. Это нужно сделать для того, чтобы в дальнейшем откалибровать радиус действия датчика, а так же избежать частотных помех. Я изучил, что кодирование ик-сигнала происходит через протокол, например NEC, итак вопросы: · Есть ли готовая библиотека/примеры кодирования сигнала и дальнейшая его отправка? · Как настроить ШИМ канал с ик-светодиодом, если приемник работает на частоте 38кГЦ? Скетч: Код (C++): #include <boarddefs.h> #include <IRremote.h> #include <IRremoteInt.h> #include <ir_Lego_PF_BitStreamEncoder.h> int redled = 8; // красный светодиод IRrecv irrecv(9); //ик приемник int irsend = 6; // ик светодиод boolean off = true; //состояние красного диода по-умолчанию decode_results results; //объект класса decode_result void setup() { Serial.begin(9600); // запускаем прослушку в мониторе порта pinMode(redled, OUTPUT); //порт с красным светодом работает в режиме OUTPUT pinMode(irsend, OUTPUT); //порт с ик светодом работает в режиме OUTPUT irrecv.enableIRIn(); // инициализация ик-приемника } void loop() { readIR(); } //Читаем ИК-сигналы void readIR() { if (irrecv.decode( &results )) { //Если это сигнал «отпуска» кнопки, //То игнорируем этот сигнал unsigned long IRval = results.value; if (IRval == 0xffffffff) { irrecv.resume(); return; } if (results.decode_type == NEC) { Serial.print("NEC: "); } else if (results.decode_type == SONY) { Serial.print("SONY: "); } else if (results.decode_type == RC5) { Serial.print("RC5: "); } else if (results.decode_type == RC6) { Serial.print("RC6: "); } else if (results.decode_type == UNKNOWN) { Serial.print("UNKNOWN: "); } //Выводим информацию о полученном сигнале в HEX Serial.println(results.value, HEX); decodeIR(); irrecv.resume(); // Ждем следующий сигнал } } // определяем значение void decodeIR(){ switch(results.value){ //включаем или выключаем красный светодиод case 0x40507C87: if(off){ digitalWrite(redled, HIGH); off = false; } else { digitalWrite(redled, LOW); off = true; } break; } } void sendIR(){ } Моя плата arduino uno
Отраженный сигнал будет искаженный, условно вместо "СИГНАЛ" я буду получать что-то вроде "ИСГАНАЛ", поэтому мой вариант отпадает. Мне пришел ответ от знатока, но я все равно ничего не понял. Что мне делать? Я разрабатывают ИК датчик препятствия. Я запутался и не понимаю принцип, зачем нужен импульсный сигнал от диода, что он даст? - в таком же случае нужно одновременно выключать/включать сам ик датчик? Есть примеры таких решений?
Что-то этот знаток совсем не знаток. Приёмник TSOP выдаёт единицу когда не видит сигнал и ноль (или наоборот), когда видит. Но модулированный сигнал не может быть длиннее сколько то там периодов (надо читать даташит на TSOP). Поэтому в сигнале необходимо чередовать нолики и единички, т.е произвести отбеливание.
Заменил TSOP на ИК-фотодиод. В моем новом скетче "меандр" представлен как частный случай ШИМ, как по-другому реализовать его - я не представляю. Повесил обработчик прерываний, который после отправки ик-сигнала передает управление функции чтения аналогово сигнала с фотодиода с дальнейшней калибровкой считываемых данных. Что делать дальше? С чем ознакомиться? Код (C++): int ik_pin = 3; int diode_pin = 7; int fotoel = A0; int sensorval = 0; void setup() { Serial.begin(9600); pinMode(diode_pin, OUTPUT); pinMode(ik_pin, OUTPUT); } void loop() { ikledFlash(); attachInterrupt(1, ikRecv, CHANGE); } // Включаем ик-диод void ikledFlash(){ analogWrite(ik_pin, 127); //488 hz "меандр" Serial.println("ir signal sent"); } // Выключаем ик-диод void ikledFlashOFF(){ digitalWrite(ik_pin, 0); } // Обрабатываем данные с ик-фотодиода void ikRecv(){ Serial.print("Value: "); sensorval = analogRead(fotoel); Serial.println(sensorval); //если аналоговое значение с ик-фотодиода //меньше 980, то включаем светодиод (препятсвие обнаружено) if(sensorval<980) { digitalWrite(diode_pin,1); } else { digitalWrite(diode_pin,0); } detachInterrupt(1); ikledFlashOFF(); }
И зачем? В чём проблема cгенерировать частоту 36кГц и промодулировать её так, как написано в даташите?
Да можно было шим 36кГц поставить. В попыхах забыл совсем, что светодиод изначально луч определенной частоты испускает, а не кодированный сигнал. Что вообще думаешь? Что стоит доработать?