Найти в Дзене
Igor_CAD

Arduino и инфракрасный датчик на компараторе LM393

В данной статье рассмотрим создание класса счётчика срабатываний датчика инфракрасного света на компараторе LM393. На датчике расположены три контакта, GND, OUT и VCC. Сигнал будем считывать с контакта OUT функцией digitalRead. Исходный код класса на Arduino C++: class TriggerCounter { public: enum TickMode { ENTER = 0, // Увеличение/уменьшение значения счётчика на вход препятствия LEAVE = 1, // Увеличение/уменьшение значения счётчика на выход препятствия BOTH = 2 // Увеличение/уменьшение значения счётчика на вход и выход препятствия }; /* int input_pin - Контакт TickMode tick_mode - Режим тикания, на вход, выхлд или на вход и выход int input_straight = 0 - Признак движения (ленты) в прямом порядке, увеличение счётика на единицу на каждый тик int input_reversed = 0 - Признак движения (ленты) в обратном порядке, уменьшение счётчика на единицу на каждый тик int input_reset = 0 - Пин кнопки сброса счётчика в ноль */ TriggerCounter(int input_pin, TickMode tick_mode, int input_straight = 0,

В данной статье рассмотрим создание класса счётчика срабатываний датчика инфракрасного света на компараторе LM393.

Датчик инфракрасного света на LM393
Датчик инфракрасного света на LM393

На датчике расположены три контакта, GND, OUT и VCC. Сигнал будем считывать с контакта OUT функцией digitalRead.

Исходный код класса на Arduino C++:

class TriggerCounter

{

public:

enum TickMode

{

ENTER = 0, // Увеличение/уменьшение значения счётчика на вход препятствия

LEAVE = 1, // Увеличение/уменьшение значения счётчика на выход препятствия

BOTH = 2 // Увеличение/уменьшение значения счётчика на вход и выход препятствия

};

/*

int input_pin - Контакт

TickMode tick_mode - Режим тикания, на вход, выхлд или на вход и выход

int input_straight = 0 - Признак движения (ленты) в прямом порядке, увеличение счётика на единицу на каждый тик

int input_reversed = 0 - Признак движения (ленты) в обратном порядке, уменьшение счётчика на единицу на каждый тик

int input_reset = 0 - Пин кнопки сброса счётчика в ноль

*/

TriggerCounter(int input_pin, TickMode tick_mode, int input_straight = 0, int input_reversed = 0, int input_reset = 0)

: m_tick_mode(tick_mode)

, m_input_pin(input_pin)

, m_input_reset(input_reset)

, m_input_straight(input_straight)

, m_input_reversed(input_reversed)

{

pinMode(m_input_pin, INPUT);

if (m_input_reset)

{

pinMode(m_input_reset, INPUT_PULLUP);

}

};

/* Вызывается при изменении состояния датчика, происходит увеличение/уменьшение счётчика на единицу,

если заданы пины направления. Если пины направления не заданы, всегда работает в сторону увеличения.

*/

void onTick()

{

if ((m_tick_mode == ENTER && m_state == 0)

|| (m_tick_mode == LEAVE && m_state == 1))

return;

if (m_input_straight)

{

int dir_straight = digitalRead(m_input_straight);

if (dir_straight)

++m_counter;

int dir_reversed = digitalRead(m_input_reversed);

if (dir_reversed)

--m_counter;

return;

}

++m_counter;

}

int counter()

{

return m_counter;

}

void scan()

{

if (m_input_reset)

{

int input_reset = digitalRead(m_input_reset);

if (input_reset == 0)

{

onReset();

}

}

int input_value = digitalRead(m_input_pin);

if (m_state != input_value)

{

m_state = input_value;

onTick();

}

}

// Сброс счётчика в ноль

void onReset()

{

m_counter = 0;

}

private:

TickMode m_tick_mode{ ENTER }; // Исходное значение ENTER

int m_counter{0}; // Поле счётчик, начинаем считать с нуля, при движении в прямом направлении, значение увеличивается на единицу

bool m_state{false}; // Текущее состояние датчика

int m_input_pin;

int m_input_reset;

int m_input_straight;

int m_input_reversed;

};

Пример использования:

Объявляем глобальную переменную типа TriggerCounter.

Входные параметры в конструктор класса имеют следующее назначение:

PIN_INFRARED_INPUT - пин на который приходят с данные контакта OUT датчика, TriggerCounter::ENTER - увеличение счётчика на вход препятствия, PIN_DIRECTION_STRAIGHT - контакт, обозначающий прямое направление счёта, PIN_DIRECTION_REVERSED - контакт, означающий обратное направление счёта, PIN_COUNTER_RESET - контакт, на который приходит сигнал сброса счётчика в ноль

В конфигурации с LM393 это дефайны

#define PIN_INFRARED_INPUT 6

#define PIN_COUNTER_RESET 3

#define PIN_DIRECTION_STRAIGHT 0

#define PIN_DIRECTION_REVERSED 0

TriggerCounter g_triggerCounter(PIN_INFRARED_INPUT, TriggerCounter::ENTER, PIN_DIRECTION_STRAIGHT, PIN_DIRECTION_REVERSED, PIN_COUNTER_RESET);

В функции цикла работы Arduino просто вызываем метод TriggerCounter::scan() и после сканирования выводим текущее значение счётчика (поля m_counter) на дисплей TM1637 (о нём речь пойдёт в другой статье):

void loop() {

g_triggerCounter.scan();

// gTM1637_6D.displayInteger(g_triggerCounter.counter(), false);

}

В видео можно посмотреть на работу класса в реальных условиях, с датчиком LM и с датчиком магнитофона: