Что не так с моим ИК-датчиком?

ir

Я купил несколько ИК-датчиков «lucky dip» из Китая, понятия не имею, что это такое, но они, похоже, потерялись на почте, поэтому вместо этого я купил несколько из них в надежном месте в Великобритании, к которым прилагается техническое описание.

На следующий день оба товара прибыли вместе!

Я пытаюсь построить очень простой датчик приближения для робота. Я построил следующую схему:

схема

и украл этот код, чтобы проверить его:

#define IRledPin 8
#define D13ledPin 13
#define IRsensorPin 9

void IR38Write() {
  for(int i = 0; i <= 384; i++) {
    digitalWrite(IRledPin, HIGH);
    delayMicroseconds(13);
    digitalWrite(IRledPin, LOW);
    delayMicroseconds(13);
  }
}


void setup(){
  pinMode(IRledPin, OUTPUT);
  digitalWrite(IRledPin, LOW);
  pinMode(D13ledPin, OUTPUT);
  digitalWrite(D13ledPin, LOW);
}



void loop(){
  IR38Write();
  if (digitalRead(IRsensorPin)==LOW){
    digitalWrite(D13ledPin, HIGH);
  } else {
    digitalWrite(D13ledPin, LOW);
  }
}

Если я держу перед ним руку, ничего не происходит (светодиод на плате arduino должен загореться), однако если я направляю на него пульт от телевизора и нажимаю кнопку, светодиод загорается. Я протестировал 2 из тех «затейливых» датчиков, которые у меня были, и оба вели себя одинаково.

Затем я попробовал один из датчиков «счастливого падения», сразу же его подключил, и все заработало идеально — направляю пульт от телевизора, и светодиод загорается, держу руку на расстоянии около 10 см от него, и светодиод загорается!

Итак, где я ошибся?

, 👍2

Обсуждение

@NickAlexeev - это на самом деле не вопрос Arduino, а скорее вопрос о поведении модуля ИК-приемника. Миграция была неправильной - вы должны читать эти вещи, а не просто запускать ключевые слова., @Chris Stratton

Я действительно об этом задумывался — на самом деле это не проблема, связанная исключительно с Arduino, просто так получилось, что я использую ее в данном случае., @MalphasWats

Что происходит с этими вопросами? Они переносятся обратно в EE или просто теряются?, @Nick Gammon


2 ответа


Лучший ответ:

4

См. страницу 5 вашего технического описания — этот «замысловатый» датчик подавляет «• Непрерывные сигналы на любой частоте».

Таким образом, вам нужно будет подать импульсный сигнал частотой 38,4 кГц, чтобы датчик выдал выходной сигнал.

,

Ого, спасибо. Технические описания — это сложно! На самом деле, это довольно сложно сделать на одной плате — к тому времени, как датчик начинает искать сигнал, он уже практически перестал отскакивать. Мне удалось заставить его сработать рукой, заставив его пульсировать, но это действительно ненадежно. Я выбрал совершенно не тот датчик для того, что пытаюсь сделать, я понятия не имел, что некоторые из них настолько умны! Спасибо, @MalphasWats

Вы должны иметь возможность установить задержку в начале вашего цикла, возможно, 100 мс, и настроить количество циклов вывода, чтобы оно находилось в диапазоне того, что детектор считает импульсом. Было бы лучше, если бы вы проверяли результаты *во время* передачи, вычитая время для этого из задержек (вероятно, используйте осциллограф для калибровки). Или вы, вероятно, можете использовать аппаратный таймер для передачи. Лучшие результаты близости будут с синхронным детектором, т. е. синхронным усилителем, а не удаленным приемником., @Chris Stratton

да, возможно, вы можете использовать один из выходов ШИМ на вашем Arduino для управления светодиодом, @Jasen


3

Ответ, который я принял, является правильным, но я хотел бы добавить этот дополнительный бит для полноты. Я переработал свой код, чтобы использовать неблокирующие задержки для ИК-светодиода, чтобы датчик действительно получил возможность увидеть его до того, как он прекратит передачу, и это работает! Дальность действия немного меньше, чем у датчика «счастливого падения» (~ 2 см).

#define IR_LED 8
#define LED 13
#define SENSOR 9

unsigned long burst_timer;
unsigned long gap_timer;

unsigned long timestamp;

char led_state;
char burst_count;

const char BURST_MAX = 20;


void setup()
{
  pinMode(IR_LED, OUTPUT);
  led_state = LOW;
  burst_count = 0;
  digitalWrite(IR_LED, led_state);

  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);

  pinMode(SENSOR, INPUT);

  timestamp = micros();
  burst_timer = timestamp;
  gap_timer = timestamp;
}


void toggle_led()
{
  if (led_state == LOW)
  {
    led_state = HIGH;
  }
  else
  {
    led_state = LOW;
    burst_count++;
  }

  digitalWrite(IR_LED, led_state);
}

void loop()
{
  timestamp = micros();
  if (timestamp - burst_timer > 13 && burst_count < BURST_MAX)
  {
    toggle_led();
    burst_timer = timestamp;
    gap_timer = timestamp;
  }

  if (burst_count >= BURST_MAX && timestamp - gap_timer > (13*2*BURST_MAX) )
  {
    burst_count = 0;
    burst_timer = timestamp;
    gap_timer = timestamp;
  }


  if (digitalRead(SENSOR) == LOW)
  {
    digitalWrite(LED, HIGH);
  } 
  else 
  {
    digitalWrite(LED, LOW);
  }
}

Каждый раз, когда я использую delay() (или delayMicroseconds()), я нахожу новую причину этого не делать!

,

Тогда это хороший урок. Delay() — второй в очереди после String в списке злых ставков., @Majenko