Нерешаемо Ик датчик препятствий (своими руками)

Тема в разделе "Arduino & Shields", создана пользователем FlavieBrilliants, 15 июл 2020.

  1. Здравствуйте.

    Разрабатываю прототип ик-датчика препятствия.

    Моя идея базируется на использовании ШИМ технологии в качестве замены подстроечного резистора. Датчик работает по принципу: обнаружен барьер – загорается красный светодиод.

    Я уже достиг некоторых результатов, научился работать с ик-приемником (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
     
    Последнее редактирование модератором: 15 июл 2020
  2. parovoZZ

    parovoZZ Гуру

    Нужен кривой кварц. Впрочем, как рассчитывается частота ШИМ-а досконально описано в даташите.
     
  3. Отраженный сигнал будет искаженный, условно вместо "СИГНАЛ" я буду получать что-то вроде "ИСГАНАЛ", поэтому мой вариант отпадает.

    Мне пришел ответ от знатока, но я все равно ничего не понял. Что мне делать? Я разрабатывают ИК датчик препятствия.
    Я запутался и не понимаю принцип, зачем нужен импульсный сигнал от диода, что он даст? - в таком же случае нужно одновременно выключать/включать сам ик датчик? Есть примеры таких решений?

     
  4. parovoZZ

    parovoZZ Гуру

    Что-то этот знаток совсем не знаток. Приёмник TSOP выдаёт единицу когда не видит сигнал и ноль (или наоборот), когда видит. Но модулированный сигнал не может быть длиннее сколько то там периодов (надо читать даташит на TSOP). Поэтому в сигнале необходимо чередовать нолики и единички, т.е произвести отбеливание.
     
  5. Дружище, я слово отбеливание понимаю на уровне ваниша. Я не понимаю что делать.
     
  6. Заменил 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();
    }
     
     
  7. parovoZZ

    parovoZZ Гуру

    И зачем? В чём проблема cгенерировать частоту 36кГц и промодулировать её так, как написано в даташите?
     
  8. Да можно было шим 36кГц поставить.
    В попыхах забыл совсем, что светодиод изначально луч определенной частоты испускает, а не кодированный сигнал.

    Что вообще думаешь? Что стоит доработать?
     
  9. parovoZZ

    parovoZZ Гуру

    Там не ШИМ, а пачки импульсов.

    О какой частоте речь?