Проверка датчика, на протяжении всей программы

Тема в разделе "Arduino & Shields", создана пользователем Alex19, 18 фев 2014.

  1. Корней

    Корней Гик

    Вполне возможно. Мне не попадалась статистическая информация такого рода.
     
  2. Unixon

    Unixon Оракул Модератор

    Тут стоит определиться с атомарностью операций и тогда с теми же прерываниями задача решается сразу.
    Ставите обработчик прерывания, который просто поднимает флаг. Вместо функций Wiring объявляете свои функции-обертки, которые проверяют этот флаг. Заменяете вызовы стандартных функций на вызовы своих функций-оберток. Нзвание может отличаться всего на один символ. Код остается визуально таким же, но работает уже с учетом особенности.
     
    Alex19 нравится это.
  3. Tomasina

    Tomasina Сушитель лампочек Модератор

    Код (Text):
    boolean doorClosed = true;
    // Пишем функцию проверки состояния двери, которая возвращает true/false
    void checkDoor();
    {
    doorClosed = DigitalRead...;
    if  (!doorClosed) stop();   // сразу прыгаем на stop
    return doorClosed;
    }

    // Дальше ко всем действиям прибавляем вызов этой функции в режиме И:
    if (checkDoor() && DigitalRead...)
    { ... }

    // либо просто все действия обертываем проверкой
    if (checkDoor())
    { timeAB = timeA + timeB; }
    Версия 2: через прерывание ISR каждую секунду вызывать проверку checkDoor(), но это может тормозить и не очень точно соответствует ТЗ - за 0,5 сек может что-нибудь произойти.

    Версия 3, но надо проверить - будет ли оно вызываться единожды, либо каждый раз
    Код (Text):
    while (checkDoor())
    { ... }
     
  4. Alex19

    Alex19 Гуру

    Извините, за паузу в диалоге. Много работы.
    Сейчас в перерывах между работой, попробую прочесть и понять все предложения. Увы дергают.
     
  5. Alex19

    Alex19 Гуру

    Вчера оговорили возможность работы. Главное, чтобы при открытии двери не был включен ни один из управляющих магнитов, клапанов и т.д. Даже если он пару лишних раз пробежится, но при этом ни чего не включит, норм.

    Задача не стоит вернутся. Это был как вариант решение проблемы.

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

    Подумал, что можно было вернутся средствами Arduino в нужную точку.

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

    Версия 1 от Tomasina. Рабочая, но лучше проверять в функции void checkDoor(), флаг от прерывания. Так как есть опасность потерять открытие. Необходимо не пропустить открытие закрытие двери.

    И лучше объявить свои функции Write и там непосредственно проверять, все что надо. Так проще читать. Плюс меньше повторяемости.

    Тут вы правы, может что-нибудь произойти.

    Тут вопрос даже в другом. Если while уже прошел проверку и там включение 10 магнитов, он включил 5, а потом дверь была открыта, он все равно продолжит включение остальных. И нужна доп. проверка на каждом шаге и тогда отпадает смысл в while.

    Хоть это 3 уровень защиты, но нужно все сделать надежно.
    Радует, что нашел с вашей помощью, нормальное решение. И расширил совой кругозор.

    Большое спасибо всем откликнувшимся!
     
  6. geher

    geher Гуру

    Тут
    http://www.arduino.ru/forum/programmirovanie/programmnyi-reset
    вычитал.
    Из написанного там следует, что есть теоретическая возможность после прерывания "безнаказанно" уйти в начало.
    Т.е. дверь открылась - прерывание - в функции прерывания все останавливается (по барабану, что пока прерывание, остальная часть программы "стоит", все одно, с начала начнет) и делается ресет.
    Программа начинает работу с самого начала с тем же состоянием пинов, что и непосредственно перед ресетом (то, что в функции прерывания установилось).
    Остается в начале программы не забыть проверить состояние двери и не включать ничего, пока она не закроется.
     
    Alex19 нравится это.
  7. Tomasina

    Tomasina Сушитель лампочек Модератор

    ну тогда логика еще проще: настраиваем прерывания для всех критических зон на CHANGE (с проверкой текущего состояния), или на RISING (если точно известно, что при открытии LOW изменится на HIGH), а в прерывании только выставляем инверсный флаг (flagZone1 = false), это не снизит быстродействие.
    А все действия обертываем проверкой:
    Код (Text):
    if (flagZone1)
    { timeAB = timeA + timeB; }
    Тогда с программной стороны защиту не пробить.
    А с аппаратной (механической) свои заморочки - дребезг контактов, обрыв линии с датчика и прочее.

    P.S. обрыв несложно словить программно: ставим на каждую зону минимум два датчика и флаг устанавливаем если хотя бы один из них сработал:
    Код (Text):
    if (!flagZone1Sensor1 && !flagZone1Sensor2) flagZone1 = false;
     
  8. Alex19

    Alex19 Гуру

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

    Есть гидравлическая (механическая) защита, электронная не зависимая, и программная.
    В программной есть 2 линии, одна дает 1, другая 0. Только если 1 и 0 дверь считается закрытой, на случай обрыва датчика. Может в будущем подумаем о проверке всех линий. Чтобы моментом определять проблемы на линиях.

    Дребезг я думаю победим, столько разных решений, если стандартный не поможет.
     
  9. Alex19

    Alex19 Гуру

    Этот прием отлично работает.
    Всем большое спасибо!