В предыдущих публикациях (Часть 1 и Часть 2) рассказывалось, как изготовить самодельный счётчик объектов, пересекающих единственный инфракрасный луч (барьер). В счётчике использовался механизм внешних прерываний микроконтроллера. Соответственно, скетч для Arduino выглядит крайне простым.
Теперь мне хочется чуть-чуть пошалить и предложить вашему вниманию альтернативный вариант: странный инфракрасный счётчик с одним лучом. В нём не используются внешние прерывания. И скетч выглядит посложнее.
Зато он может определить, сколько времени объект провёл в инфракрасном луче.
Сенсорная система
Подходящая для странного счётчика сенсорная система (с импульсным излучателем) описана в публикации «Очень самодельная сенсорная система для инфракрасного счётчика людей.»
Вход инфракрасного излучателя следует подключить к цифровому выходу D2 Arduino, выход инфракрасного приёмника - к аналоговому входу A0.
Скетч
// Однолучевой инфракрасный счётчик
//(с измерением продолжительности прохода через луч)
// Используемые пины Arduino
#define TRANSMITTER 2
#define RECEIVER A0
// Минимальное значение сигнала на выходе приёмника, означающее: "ИК луч есть"
#define SIGNAL_MIN 50 //соответствует напряжению 250 mV
unsigned long in_time, //отметка времени входа объекта в луч
out_time, //отметка времени выхода объекта из луча
pass_counter; //счётчик прохождений объектов
float time; //продолжительность нахождения объекта в луче
int fone_level, //фоновый уровень на выходе приёмника при выключенном излучателе
signal, //сигнал (превышение над фоном) при включенном излучателе
channel_now, //состояние сенсорного оптического канала
channel_before; //состояние канала в предыдущем опросе
// Инициализация
void setup() {
// Пин излучателя - в режим вывода
pinMode(TRANSMITTER, OUTPUT);
// Состояние сенсорного канала априори - открыт
channel_before = 1;
// Сброс счётчика прохождений объектов
pass_counter = 0;
// Ожидание начальной зарядки буферного конденсатора излучателя до нормы
delay(100); // 0.1 сек.
Serial.begin(9600);
Serial.println(" ");
Serial.println("----- Start ------");
}
// Основной цикл
void loop() {
// Пробуждение сенсорного оптического канала и определение его состояния (250 мксек)
fone_level = analogRead(RECEIVER);
digitalWrite(TRANSMITTER, HIGH);
signal = analogRead(RECEIVER) - fone_level;
digitalWrite(TRANSMITTER, LOW);
if (signal >= SIGNAL_MIN) channel_now = 1; else channel_now = 0;
// Проверка наличия события в канале
if (channel_now != channel_before) {//событие есть
channel_before = channel_now; //запоминание состояния канала
//Определение типа события и его обработка
if (channel_now == 0) {//объект вошёл в луч
in_time = micros(); //отметка времени входа, мксек.
}
else {//объект вышел из луча
out_time = micros(); //отметка времени выхода, мксек.
// Продолжительность нахождения объекта в луче, сек.
time = 1.0e-6 * (out_time - in_time);
// Подсчёт очередного прохождения объекта
pass_counter++;
Serial.print(" ");
Serial.print(pass_counter);
Serial.print(" ");
Serial.print(time);
Serial.println(" sec.");
}
}
delayMicroseconds(750); //задержка для обеспечения периода основного цикла ~1000 мксек
}
Вывод результатов счёта
Чтобы увидеть результаты работы счётчика нужно активировать монитор последовательного порта, встроенный в среду программирования Arduino. При каждом проходе объекта через инфракрасный барьер (луч) в монитор выводится номер прохода и время, проведённое объектом в инфракрасном луче.
Пример реального использования странных счётчиков
Двухлучевые «собратья» странного счётчика круглосуточно несут сетевую совместную «службу» на одном из этажей учебного корпуса вуза. Их работу можно увидеть онлайн.