Мне нужна помощь с кодом для двух ИК- датчиков с использованием ATMega16.

c avr ir atmega

Я работаю над проектом по подсчёту мячей с использованием двух ИК-датчиков для определения количества мячей, входящих и выходящих из комнаты, но сейчас я застрял. Мне нужна помощь в доработке логики цикла while. Вот как это должно работать:

Первый датчик обнаруживает мяч. Первый датчик перестает обнаруживать. Второй датчик обнаруживает мяч. Второй датчик перестает обнаруживать. Счетчик должен увеличиваться или уменьшаться в зависимости от того, какой датчик первым обнаружил мяч. Сейчас мой код работает только тогда, когда оба датчика обнаруживают объект одновременно.

if (!(PINA & (1<<PA0))) { //Проверка S1
    
    while (!(PINA & (1<<PA0)));

    // Теперь проверим, обнаруживает ли S2
    if (!(PINA & (1<<PA1))) {
    
        while (!(PINA & (1<<PA1)));

        // Увеличиваем количество посетителей
        visitor_count++;
    }
}

// Проверяем, обнаруживает ли S2
if (!(PINA & (1<<PA1))) { 
    while (!(PINA & (1<<PA1)));

    // Теперь проверим, обнаруживает ли S1
    if (!(PINA & (1<<PA0))) {
        // Подождать, пока S1 прекратит обнаружение
        while (!(PINA & (1<<PA0)));

        // Уменьшить количество посетителей
        visitor_count--;
    }
}

Первый датчик обнаруживает Второй датчик обнаруживает Первый датчик перестает обнаруживать Второй датчик перестает обнаруживать Счетчик увеличивается или уменьшается Но датчики расположены недостаточно близко и никогда не обнаружат мяч одновременно. Я пытался спросить ChatGPT, но он постоянно даёт один и тот же ответ. Я думал, вы лучше поймёте мою проблему.

Буду признателен за любой совет.

Редактировать: Вход только один, с двумя датчиками.

, 👍0

Обсуждение

Вам нужно реализовать конечный автомат. Конечный автомат — настолько распространённое решение, что если вы не знаете, что это такое, сейчас самое время узнать., @st2000


2 ответа


1

Распространённый метод подсчёта объектов (мячей или людей) в пространстве с одним проходом (входом/выходом) заключается в использовании двух детекторов прерывания луча, расположенных достаточно близко друг к другу таким образом, чтобы интересующий объект в какой-то момент при входе или выходе из пространства одновременно перекрыл оба луча. В частности, сначала будет перекрыт один луч, затем оба, и, наконец, перекроется третий. Для определения направления движения объекта (вход или выход) используется хорошо известный метод, называемый квадратурным декодированием. Поскольку это распространённое решение, ИИ, вероятно, предположил, что запрос был выполнен.

В приведённом выше случае можно реализовать простой с четырьмя состояниями для определения направления движения. Обозначим лучи как A и B. Эти четыре состояния таковы: 1) ни один луч не заблокирован, 2) заблокирован только луч A, 3) заблокированы оба луча B и A и 4) заблокирован только луч B. Счётчик объектов может увеличиваться или уменьшаться в зависимости от направления движения объекта. Предполагается, что только один объект пройдёт детектор за раз, и что объект полностью пройдёт детектор, не меняя направления.

Если детекторы расположены достаточно далеко друг от друга, чтобы их оба не могли быть одновременно заблокированы одним и тем же объектом, решение может остаться идентичным предыдущему. Однако мы не сможем точно определить, в каком из двух перечисленных состояний (нет заблокированных лучей и заблокированы оба луча) мы находимся. Поэтому нам потребуется дополнительное предположение. В любой момент времени между двумя детекторами может находиться только один объект. Если это так, нам по-прежнему потребуется только 4 состояния. Но состояние, в котором заблокированы оба луча, нужно будет изменить так, чтобы оно стало идентичным состоянию, в котором нет заблокированных лучей. Они будут идентичны, за исключением того, что одно из этих идентичных состояний будет представлять отсутствие объекта между детекторами, а другое — наличие объекта между детекторами.

В заключение, первый вариант более надёжный и его сложнее спутать в реальном мире (где предположения часто игнорируются). Второй вариант менее надёжный и его легче спутать в реальном мире.

,

1

Проблема заключается в порядке операций и логике проверки датчиков. Логика должна обрабатывать случаи, когда мяч сначала обнаруживается одним датчиком, а затем другим, в зависимости от направления движения. Код можно изменить следующим образом:

// Переменные для отслеживания состояний датчиков
bool s1_detected = false;
bool s2_detected = false;

if (!(PINA & (1<<PA0))) { // Проверяем, обнаруживает ли S1 первым
    s1_detected = true;
    
    // Подождать, пока S1 прекратит обнаружение
    while (!(PINA & (1<<PA0)));

    // Теперь проверим, обнаруживает ли S2 после S1
    if (!(PINA & (1<<PA1))) {
        s2_detected = true;
        
        // Подождать, пока S2 прекратит обнаружение
        while (!(PINA & (1<<PA1)));

        // Увеличиваем количество посетителей
        if (s1_detected && s2_detected) {
            visitor_count++;
        }

        // Сбросить состояния обнаружения
        s1_detected = false;
        s2_detected = false;
    }
}

// Проверяем, обнаруживает ли S2 первым
if (!(PINA & (1<<PA1))) { 
    s2_detected = true;
    
    // Подождать, пока S2 прекратит обнаружение
    while (!(PINA & (1<<PA1)));

    // Теперь проверим, обнаруживает ли S1 после S2
    if (!(PINA & (1<<PA0))) {
        s1_detected = true;

        // Подождать, пока S1 прекратит обнаружение
        while (!(PINA & (1<<PA0)));

        // Уменьшить количество посетителей
        if (s2_detected && s1_detected) {
            visitor_count--;
        }

        // Сбросить состояния обнаружения
        s1_detected = false;
        s2_detected = false;
    }
}

Когда S1 обнаруживает мяч, код ждёт, пока S1 не прекратит обнаружение. Затем он проверяет, обнаруживает ли мяч S2. Если это так, и S2 прекращает обнаружение, он увеличивает счётчик. Если S2 первым обнаруживает мяч, код ждёт, пока S2 прекратит обнаружение, а затем проверяет, обнаруживает ли мяч S1 следующим. Если да, счётчик уменьшается. Надеюсь, этот метод сработает. Если вам также нужны инструкции по подключению ИК-датчиков к ATmega16, вы можете посмотреть их здесь:

https://www.pcbway.com/project/shareproject/Interfacing_IR_Sensor_Module_with_Arduino_Nano_31dcd7c1.html

,

Это именно тот фрагмент кода, который автор вопроса опубликовал в своём вопросе. Вы ничего не изменили, кроме нескольких комментариев., @chrisl

Спасибо. Отредактировано., @liaifat85