Введение
Оптический разрывной датчик (slot/break-beam sensor) и комплексный модуль «умная машинка, датчик препятствий, инфракрасный датчик, фотоэлектрический переключатель» — оба относятся к категории оптических датчиков обнаружения объекта, но с разной геометрией применения: разрывной датчик обнаруживает объект, проходящий через специальную щель датчика, а модуль обхода препятствий — объект, отражающий ИК-излучение перед датчиком на некотором расстоянии, что типично для роботов, объезжающих препятствия.
Концепция
Оптический разрывной датчик содержит излучатель и приёмник, расположенные друг напротив друга через небольшую щель — пока щель свободна, приёмник получает излучение непрерывно, и любой тонкий объект, проходящий через щель (например, спица колеса, перфорированная полоса), временно прерывает этот луч, что датчик регистрирует как дискретное событие — классическое применение — счётчики оборотов (аналогично датчику Холла, но через оптический, а не магнитный принцип) или детекторы прохождения объекта через определённую точку. Модуль обхода препятствий для робота, в отличие от разрывного датчика, использует отражённое излучение — излучатель и приёмник расположены рядом друг с другом, направленными в одну сторону, и приёмник регистрирует количество отражённого от близко расположенного объекта излучения, что позволяет обнаруживать препятствие перед роботом без необходимости физического контакта.
Пример кода
// Оптический разрывной датчик — счётчик прохождений объекта через щель
const int SLOT_SENSOR_PIN = 2;
volatile unsigned long passCount = 0;
void slotSensorInterrupt() {
passCount++;
}
void setupSlotSensor() {
pinMode(SLOT_SENSOR_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(SLOT_SENSOR_PIN), slotSensorInterrupt, FALLING);
}
// Практическое применение — измерение скорости через перфорированный диск
float calculateRpm(int slotsPerRevolution, unsigned long measurementWindowMs) {
float revolutions = (float)passCount / slotsPerRevolution;
float rpm = revolutions / (measurementWindowMs / 60000.0);
passCount = 0;
return rpm;
}
// ИК-модуль обхода препятствий — типичная конфигурация двух датчиков для робота
const int LEFT_OBSTACLE_PIN = 4;
const int RIGHT_OBSTACLE_PIN = 5;
void setupObstacleAvoidance() {
pinMode(LEFT_OBSTACLE_PIN, INPUT);
pinMode(RIGHT_OBSTACLE_PIN, INPUT);
}
enum class RobotAction { FORWARD, TURN_LEFT, TURN_RIGHT, STOP };
RobotAction decideNextAction() {
// Большинство ИК-модулей обхода препятствий дают LOW при обнаружении препятствия
bool leftBlocked = !digitalRead(LEFT_OBSTACLE_PIN);
bool rightBlocked = !digitalRead(RIGHT_OBSTACLE_PIN);
if (leftBlocked && rightBlocked) return RobotAction::STOP;
if (leftBlocked) return RobotAction::TURN_RIGHT; // препятствие слева — уходим вправо
if (rightBlocked) return RobotAction::TURN_LEFT; // препятствие справа — уходим влево
return RobotAction::FORWARD;
}
Пояснения к коду
slotSensorInterrupt()/calculateRpm() показывают практически идентичный по структуре подход к измерению скорости вращения, что и для датчика Холла — оба используют прерывание для подсчёта дискретных событий за известный промежуток времени, отличаясь лишь физическим принципом обнаружения (оптическим прерыванием луча против магнитного поля), что подтверждает общий паттерн: многие разные по физике датчики решают концептуально одну и ту же задачу подсчёта дискретных событий, и код их обработки часто структурно похож. decideNextAction() показывает простую, но практичную логику принятия решения для робота с двумя датчиками препятствий — при обнаружении препятствия только с одной стороны робот поворачивает в противоположную, свободную сторону, а при обнаружении препятствий с обеих сторон одновременно — останавливается, не имея однозначно безопасного направления для продолжения движения вперёд.
Подводные камни
- Использование оптического разрывного датчика на ярком, прямом солнечном свете без защиты от внешней засветки — поскольку датчик опирается на собственный, относительно слабый ИК-излучатель, интенсивный посторонний источник ИК-излучения (солнечный свет содержит значительную ИК-составляющую) может «ослепить» приёмник, делая невозможным надёжное обнаружение прерывания луча собственным излучателем датчика; для применений на открытом воздухе стоит рассмотреть экранирование датчика от прямого попадания посторонних источников излучения.
- Слишком простая, «реактивная» логика обхода препятствий без какой-либо памяти о предыдущих решениях, как в показанном упрощённом примере
decideNextAction()— робот, реагирующий исключительно на текущие, мгновенные показания датчиков, может попасть в колебательный цикл (например, поочерёдно «видя» препятствие то слева, то справа в узком проходе, постоянно дёргаясь между поворотами без реального продвижения), и для более надёжного поведения стоит добавить логику, учитывающую недавнюю историю принятых решений, а не только мгновенный снимок показаний датчиков. - Использование только двух ИК-датчиков обхода препятствий (направленных вперёд) для робота, движущегося с заметной скоростью, без датчика, направленного вперёд по центру — конфигурация из примера хорошо обнаруживает препятствия по бокам, но может пропустить узкое препятствие прямо по центру направления движения, если оно находится между зонами обнаружения левого и правого датчика; для более надёжного обхода препятствий стоит рассмотреть добавление третьего, центрального датчика или датчика с более широким углом обнаружения (например, ультразвукового, который часто комбинируют именно с боковыми ИК-датчиками для более полного покрытия).
- Игнорирование того, что дальность срабатывания ИК-модулей обхода препятствий обычно нерегулируема программно (хотя у многих физических модулей есть подстроечный потенциометр непосредственно на самой плате для аппаратной регулировки чувствительности) — попытка изменить эффективную дальность обнаружения исключительно через изменение кода (без физической настройки потенциометра на модуле) не даст желаемого эффекта, поскольку порог обнаружения в таких модулях обычно устанавливается именно аппаратно, встроенным компаратором на плате, а не считывается как аналоговое значение, доступное для программной интерпретации с произвольным порогом.