Что не так с моим ИК-датчиком?
Я купил несколько ИК-датчиков «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 см от него, и светодиод загорается!
Итак, где я ошибся?
@MalphasWats, 👍2
Обсуждение2 ответа
Лучший ответ:
См. страницу 5 вашего технического описания — этот «замысловатый» датчик подавляет «• Непрерывные сигналы на любой частоте».
Таким образом, вам нужно будет подать импульсный сигнал частотой 38,4 кГц, чтобы датчик выдал выходной сигнал.
Ого, спасибо. Технические описания — это сложно! На самом деле, это довольно сложно сделать на одной плате — к тому времени, как датчик начинает искать сигнал, он уже практически перестал отскакивать. Мне удалось заставить его сработать рукой, заставив его пульсировать, но это действительно ненадежно. Я выбрал совершенно не тот датчик для того, что пытаюсь сделать, я понятия не имел, что некоторые из них настолько умны! Спасибо, @MalphasWats
Вы должны иметь возможность установить задержку в начале вашего цикла, возможно, 100 мс, и настроить количество циклов вывода, чтобы оно находилось в диапазоне того, что детектор считает импульсом. Было бы лучше, если бы вы проверяли результаты *во время* передачи, вычитая время для этого из задержек (вероятно, используйте осциллограф для калибровки). Или вы, вероятно, можете использовать аппаратный таймер для передачи. Лучшие результаты близости будут с синхронным детектором, т. е. синхронным усилителем, а не удаленным приемником., @Chris Stratton
да, возможно, вы можете использовать один из выходов ШИМ на вашем Arduino для управления светодиодом, @Jasen
Ответ, который я принял, является правильным, но я хотел бы добавить этот дополнительный бит для полноты. Я переработал свой код, чтобы использовать неблокирующие задержки для ИК-светодиода, чтобы датчик действительно получил возможность увидеть его до того, как он прекратит передачу, и это работает! Дальность действия немного меньше, чем у датчика «счастливого падения» (~ 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
- Использование VS1838B с Arduino
- Как выбрать вывод передачи в библиотеке IRremote для Arduino Uno?
- Как увеличить расстояние обнаружения на датчике обхода препятствий Arduino KY-032?
- Ошибка "collect2.exe: error: ld returned 1 exit status"
- Как подключить ИК-передатчик и модуль приемника?
- Tone() конфликтует с библиотекой IRremote (множественное определение `__vector_7')
- Как остановить вращение сервопривода?
- ESP32 ИК-пульт
@NickAlexeev - это на самом деле не вопрос Arduino, а скорее вопрос о поведении модуля ИК-приемника. Миграция была неправильной - вы должны читать эти вещи, а не просто запускать ключевые слова., @Chris Stratton
Я действительно об этом задумывался — на самом деле это не проблема, связанная исключительно с Arduino, просто так получилось, что я использую ее в данном случае., @MalphasWats
Что происходит с этими вопросами? Они переносятся обратно в EE или просто теряются?, @Nick Gammon