[частично решено] Проблема с экспериментом 20. Обработка прерываний - виснет ардуино.

Тема в разделе "Arduino & Shields", создана пользователем altex, 2 авг 2014.

  1. Unixon

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

    Подтвердить наличие\отсутствие проблемы со стороны AVRки при гарантированном отсутствии дребезга по входу.
     
  2. altex

    altex Гик

    Получилось что-нибудь выяснить?
     
  3. xopkep

    xopkep Нуб

    Господа, я ниразу не специалист, но добавил бы подавление дребезга и отключение прерываний. Примерно так:
    Код (Text):
    #define BUZZER_PIN  0
    #define FIRST_BAR_PIN  4
    #define BAR_COUNT  10
    #define MAX_SCORE  20
    // глобальные переменные, используемые в прерываниях (см. далее)
    // должны быть отмечены как нестабильные (англ. volatile)
    volatile int score = 0;
    unsigned long OTime, lOTime, O2Time, lO2Time;

    void setup()
    {
      for (int i = 0; i < BAR_COUNT; ++i)
      pinMode(i + FIRST_BAR_PIN, OUTPUT);
      //pinMode(BUZZER_PIN, OUTPUT);
      // Прерывание (англ. interrupt) приостанавливает основную
      // программу, выполняет заданную функцию, а затем возобновляет
      // основную программу. Нам нужно прерывание на нажатие кнопки,
      // т.е. при смене сигнала с высокого на низкий, т.е. на
      // нисходящем (англ. falling) фронте
      attachInterrupt(INT1, pushP1, FALLING); // INT1 — это 3-й пин
      attachInterrupt(INT0, pushP2, FALLING); // INT0 — это 2-й пин

      Serial.begin(9600);
      OTime, lOTime, O2Time, lO2Time = millis();
    }

    void pushP1() {
      OTime = millis();
      if(OTime >= (lOTime + 100)){
      ++score;
      lOTime = OTime;
      }
    } // функция-прерывание 1-го игрока

    void pushP2() {
      O2Time = millis();
      if(O2Time >= (lO2Time + 100)){
      --score;
      lO2Time = O2Time;
      }
    } // функция-прерывание 2-го игрока

    void loop()
    {
      Serial.println("Start");
      //tone(BUZZER_PIN, 2000, 1000); // даём сигнал к старту.
      // пока никто из игроков не выиграл, обновляем «канат»
      while (abs(score) < MAX_SCORE) {
      detachInterrupt(0);
      detachInterrupt(1);
      Serial.print("Score=");
      Serial.println(score);
      delay(100);
      int bound = map(score, -MAX_SCORE, MAX_SCORE, 0, BAR_COUNT);
      int left = min(bound, BAR_COUNT / 2 - 1);
      int right = max(bound, BAR_COUNT / 2);
      for (int i = 0; i < BAR_COUNT; ++i)
      digitalWrite(i + FIRST_BAR_PIN, i >= left && i <= right);
      attachInterrupt(INT1, pushP1, FALLING); // INT1 — это 3-й пин
      attachInterrupt(INT0, pushP2, FALLING); // INT0 — это 2-й пин
      }
      //tone(BUZZER_PIN, 4000, 1000); // даём сигнал победы
      Serial.println("End");
      while (true) {
      Serial.print("Score=");
      Serial.println(score);
      delay(100);
      } // «подвешиваем» плату до перезагрузки
    }
     
  4. altex

    altex Гик

    Спасибо, но так работать не будет :)

    Программный дребезгоподавитель - это очевидное и рабочее решение, в принципе чаще всего подойдёт программный способ. По логике вещей не получится давить на кнопку чаще 10 раз в секунду (10 раз в секунду можно моргать, но кнопку давить получится только раз 7 в секунду, хотя бывают исключения), поэтому задержка в 100мс кажется адекватной. Наверное даже 50мс, чтобы уж наверняка.

    А вот отключение прерываний мало того что не имеет смысла (смысл программы именно в обработке прерываний), так ещё и в данном случае прерывание будет работать только когда будет работать строчка while(), тоесть 0.01% времени работы всей программы. В этот момент времени успеть нажать на кнопку - это везение.
     
  5. xopkep

    xopkep Нуб

    Ну я пытался передать суть идеи.
    Отключение прерываний уже вторично, но имел в виду - отключать прерывания на время счета\вывода, дабы не срывать его.
     
  6. altex

    altex Гик

    Зачем отключать прерывания, если их суть как раз в том чтобы обрабатывать внешние события в момент возникновения этого события? Ошибки то не из-за этого.
     
  7. xopkep

    xopkep Нуб

    Отключать их затем, чтобы они не мешали обработке информации о них
     
  8. altex

    altex Гик

    Они не мешают, они помогают :) Без них информация о них не обрабатывается.
     
  9. ALev

    ALev Гик

    Долго терзал сегодня триггер шмитта с кнопкой. Часто видел такое: IMG_7337.JPG

    Жёлтый — непосредственно с кнопки, красный - после триггера.

    Не знаю пока откуда оно возникает, но скорее всего это происходит из-за высокого импеданса при отжатой кнопке. Иначе бы всё стекло через подтяжку.

    Пока нет времени разбираться, т.ч. могу предложить только программную фильтрацию. Немного позже попытаюсь всё-таки найти красивое аппаратное решение да и вообще разобраться, что же это такое.
     
  10. altex

    altex Гик

    Спасибо за ответ, действительно очень интересно.
    На графике изображено, как я понял, отпускание кнопки, а затем нажатие.
    При нажатии ток резко сменился, потому что конденсатор разрядился мгновенно через кнопку (если между конденсатором и кнопкой не было резистора, какая была схема?).
    При отпускании кнопки начинает заряжаться конденсатор через подтягивающий резистор, поэтому такой плавный жёлтый график.
    Такое ощущение, что в определённый момент триггер переключается, но это приводит почему-то к тому, что сигнал проседает, и он назад переключается из-за этого, и так пока конденсатор не зарядится почти полностью. По идее гистерезис должен был убрать подобный эффект, значит либо он не работает, либо просадка больше гистерезиса. Если просадка была бы больше гистерезиса, то это было бы видно на жёлтом графике (наверное, хотя и на красном тоже была бы не ровная линия тогда)

    В-общем буду ждать с нетерпением дальнейшего развития событий, очень интересная проблема.
     
  11. ALev

    ALev Гик

    Вы всё правильно поняли: в свободном состоянии кнопка подтянута к «+» через 100 кОм, в нажатом — накоротко на землю, между кнопкой и землёй всегда конденсатор 100 нФ.

    В 95% случае всё происходит как должно: при нажатии на выходе без задержки появляется «1» (т.к. триггер инвертирующий), при отжатии конденсатор начинает заряжаться и, когда заряжается до порога срабатывания триггера, на выходе появляется «0». Но иногда (точно не могу сказать, но похоже только при спаде) при прохождении через пороговое для триггера напряжение как будто возникают автоколебания. Причём на одном (⚠) уровне, т.е. незатухающие колебания или медленно затухающие. И через ≈10 мс этот процесс прекращается и всё возвращается в логичную картину.

    Надо смотреть, что там у этого триггера внутри.
     
  12. altex

    altex Гик

    Насколько я понимаю график, сигнал держится на уровне 2 вольта в момент возникновения непонятных колебаний, и нужно понимать это не как ровный сигнал, а как усреднённое значение именно колебаний, которые сами по себе от 0 до 5 вольт, но за счёт быстрого переключения складывается картинка, как будто бы более менее ровный сигнал 2 вольта на выходе триггера.

    А вы пробовали максимальное разрешение поставить на осциллографе, чтобы убедиться, что там именно переключение сигнала от 0 до 5 вольт, а не просто прямая линия? Или частоты осциллографа не хватает, чтобы можно было посмотреть форму сигнала?

    Я попробовал поискать устройство этих триггеров или даже их аналогов, но ничего не смог найти.
     
  13. ALev

    ALev Гик

    Дело в том, что осциллограф пишет N экранов в заданном разрешении и M точек на экран. И если в данный момент выставлено разрешение «100 мс на экран», то при увеличении плотность точек падает. Поэтому идеальный вариант — поймать этот сигнал с высоким разрешением. А это неудаётся сделать, т.к. не за что зацепиться. Триггер осциллографа реагирует на все перепады импульсов, ему нельзя сказать «поймай мне фигню» ☺.
     
  14. altex

    altex Гик

    То есть если сделать разрешение, 1 мкс, то есть считывать значения с выхода триггера с частотой в 1 МГц, и поставить в осциллографе срабатывание на падение сигнала 5 в до 4 хотя бы, и отпустить тактовую кнопку, то осциллограф не зафиксирует, что сигнал на выходе триггера упал, и что нужно начать сохранять 1 000 000 значений в секунду?
     
  15. Unixon

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

    Может триггер из другой КМОП серии попробовать? Была точно такая же фигня в одном проекте, триггеры не сразу "отпускало". Если правильно помню, решил проблему стяжкой выхода триггера.
     
    altex нравится это.
  16. altex

    altex Гик

    Чувствую себя дураком, погуглил "стяжку выхода триггера", ничего не нашёл. Имеется ввиду замкнуть выход триггера через резистор 10кОм на землю?
     
  17. Unixon

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

    Да, верно. Обычно это лишено смысла, т.к. выходы все низкоомные, но в моменты переключения, особенно если они затягиваются из-за какой-то неустойчивости, может получиться так, что и вход и выход будут с большим импедансом, вот тогда могут быть неожиданные неприятности.
     
  18. ALev

    ALev Гик

    Любопытно, надо попробовать. По идее должно решить проблему.

    [offtop]Кстати, термин «стяжка» был придуман каким-то неучем в инете и по ошибке популяризован в Амперке. На самом деле нет понятия «стяжка», есть только «подтяжка». К земле тоже «подтяжка».[/offtop]
     
  19. Unixon

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

    1) для сравнения, в англоязычной литературе есть и pull-up и pull-down, и никто не говорит, что "pull-down - это, на самом деле, то же самое, что и pull-up, только наоборот";
    2) т.н. "неуч" использовал механизм словообразования русского языка по назначению и выдал фонетически и семантически оптимальный перевод;
    3) использование двух различных слов для указания двух противоположных направлений вдоль шкалы потенциала облегчает понимание и исключает путаницу между "верхом" и "низом", неизбежную при использовании одних только "подтяжек";
    4) считаю идею с использованием слов/выражений "стяжка"/"стягивающий резистор" и "подтяжка"/"подтягивающий резистор", как прямых аналогов "pull-up"/"pull-up resistor" и "pull-down"/"pull-down resistor", отличной идеей, безусловно нуждающейся в том, чтобы ее узаконить в правилах языка и специальной терминологии.
     
    acos нравится это.
  20. altex

    altex Гик

    Я конечно не филолог, но тогда уж не стягивать, а прижимать.
    Подтянуть к Vin, а прижать к земле

    P.S. Просто как предложение. На самом деле мне всё равно как называть, если есть схема.
     
    Unixon нравится это.