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

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

  1. altex

    altex Гик

    Ну да, всё правильно, просто по схеме
    http://chipenable.ru/index.php/how-...t-komparatora-na-operatsionnom-usilitele.html
    используется компаратор lm358d
    а у него судя по даташиту есть подтягивающий резистор, и на выходе будет либо земля, либо Vin

    А в 339 нужен обязательно внешний подтягивающий резистор
     
  2. Unixon

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

    Ну вот, разобрались. Самое время проверить схемы на практике. :)

    p.s. LM358 это операционный усилитель, а не компаратор.
     
  3. altex

    altex Гик

    Получилась во такая схема http://c2n.me/iZ8vcn.png
    Например я хочу чтобы нижний порог срабатывания был 0.5 В, а верхний - 4.5В.
    Чтобы обеспечить такой высокий верхний уровень, нужно довольно высокое опорное напряжение Uоп.
    Например 4В подойдёт.

    Чтобы получить 4В опорного напряжения, можно воспользоваться делителем напряжения, и поделить 5В источника питания через резисторы на (R3)100К и (R4)400К.

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

    Для этого нужно 4В поделить ещё раз, например через резисторы (R1)70К и (R2)10К.

    А для того, чтобы верхний уровень был 4.5, нужно Rк выбрать например 60К.

    Проверим.
    Возьмём формулы http://c2n.me/iZ8D6F.png
    Посчитаем Uп1 и Uп2, насколько получилось то что требовалось (тоесть 0.5В и 4.5В)
    Uп1 = 4 * 10 000 / (70 000 + 10 000) = 0.5
    Uп2 = (5 * 70 000 + 4 (10 000 + 60 000)) / (70 000 + 10 000 + 60 000) = (350 + 280) / 140 = 4.5

    И вроде бы всё правильно.
    Но Uоп будет сильно скакать в зависимости от того, включен выход компаратора или нет (включен, всмысле открыт транзистор на выходе).
    Или нужно взять просто ещё больше резисторы R3 и R4, например 1М и 4М ?
    Вообще до каких пор можно увеличивать номиналы этих резисторов?
     
  4. Unixon

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

    Смотрите на входное сопротивление компаратора или ОУ. Сопротивление в обвязке должно быть меньше сопротивления входа хотя бы на порядок, чтобы не искажать параметров схемы, рассчитанных на идеальный модельный компаратор.

    Т.е. если входное сопротивление порядка 1M, то в схеме лучше за 100k особо не залазить. А ежели вам нужна еще большая точность, тогда отношение характерных сопротивлений снаружи (стяжки-подтяжки, обратная связь) к входному сопротивлению должно быть еще сильнее.
     
  5. altex

    altex Гик

  6. Unixon

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

    Ну, в общем, старайтесь в пределах 1МОм оставаться. В качестве эмпирического правила.
     
  7. altex

    altex Гик

    Для экспериментов использовал код:

    Код (Text):
    // глобальные переменные, используемые в прерываниях (см. далее)
    // должны быть отмечены как нестабильные (англ. volatile)
    volatile int score1 = 0;
    volatile int score2 = 0;

    void setup()
    {
      attachInterrupt(INT1, pushP1, RISING); // INT1 — это 3-й пин
      attachInterrupt(INT0, pushP2, RISING); // INT0 — это 2-й пин
     
      Serial.begin(9600);
    }

    void pushP1() { ++score1; } // функция-прерывание 1-го игрока
    void pushP2() { ++score2; } // функция-прерывание 2-го игрока

    void loop()
    {
      Serial.print("Score1=");
      Serial.print(score1);
      Serial.print(" Score2=");
      Serial.println(score2);
      delay(100);
    }
    Номиналы резисторов для схемы http://c2n.me/iZ8vcn.png
    R1=56К
    R2=22К
    Rк=56К
    R3=100К
    R4=390К

    И вот в таком виде схема работает как надо. Ни одного зацикливания или лишнего нажатия воспроизвести не удалось. Провёл два эксперимента, с RISING и FALLING для фронтов прерываний, и на каждую кнопку по 500 раз нажимал, одновременно на обе кнопки сразу.

    Получается, что триггер Шмитта на микросхеме из "эксперимента 20" не подходит.
    Зато компаратор с настраиваемым гистерезисом подошёл.
    Фото конструкции - http://c2n.me/iZaVu3.png
     
  8. altex

    altex Гик

    Кстати, я не понял как оно работало, у меня на схеме ошибка (на фото видно), я не подключил второй вывод R4 к земле - он просто не подключен остался. Получается Uоп было +5В. И Uп2 тоже при этом было +5В. А значит оно не должно было работать.
     
    Последнее редактирование: 27 сен 2014
  9. altex

    altex Гик

  10. Unixon

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

    Маленький совет: возьмите как-нибудь несколько вот таких перемычек и внутри одной макетки используйте только их, а длинными проводами соединяйте части схемы за пределами макетки.
     
  11. altex

    altex Гик

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

    Код (Text):
    // глобальные переменные, используемые в прерываниях (см. далее)
    // должны быть отмечены как нестабильные (англ. volatile)
    volatile int score1 = 0;
    volatile int score2 = 0;

    void setup()
    {
      attachInterrupt(INT1, pushP1, RISING); // INT1 — это 3-й пин
      attachInterrupt(INT0, pushP2, RISING); // INT0 — это 2-й пин

      pinMode(A0, INPUT);
      pinMode(A1, INPUT);

      Serial.begin(9600);
    }

    void pushP1() { ++score1; } // функция-прерывание 1-го игрока
    void pushP2() { ++score2; } // функция-прерывание 2-го игрока

    float a0volts = 0;
    float a1volts = 0;

    void loop()
    {
      Serial.print("Score1=");
      Serial.print(score1);
      Serial.print(" Score2=");
      Serial.print(score2);


      a0volts = 5.0 * (analogRead(A0) / 1023.0);
      Serial.print(" A0=");
      Serial.print(a0volts);

      a1volts = 5.0 * (analogRead(A1) / 1023.0);
      Serial.print(" A1=");
      Serial.print(a1volts);

      Serial.println("");
      delay(100);
    }
     
    Выяснилось, что на выходе компаратора либо 0В либо 4.73В (полностью совпадает с расчётной)
    Нижняя граница гистерезиса 0.56В (полностью совпадает с расчётной)
    Верхняя граница 4.63В (полностью совпадает с расчётной)
    Причём получился инвертирующий триггер Шмитта.
     
    Последнее редактирование: 27 сен 2014
  12. altex

    altex Гик

    У меня такие есть, я просто ими не пользуюсь пока что.
     
  13. altex

    altex Гик

    Взял триггер Шмитта, и как рекомендовано в даташите заземлил все неиспользуемые входы.
    После этого фантомные нажатия на кнопку, когда я нажимаю на одну кнопку, а срабатывает прерывание с другой кнопки, полностью исчезли.
    В режиме FALLING мне не с первого раза удалось даже зациклить триггер (поребовалось под 480 одновременных нажатий).
    В режиме RISING при одновременном нажатии на кнопки всё ещё получается зациклить триггер.
    Вызвать зацикливания многократным нажатием только на одну кнопку вообще не удалось.
    При некоторых прогонах тестов одновременными нажатиями даже иногда получалось вообще без багов досчитать до 500 нажатий на каждую кнопку.
     
    Последнее редактирование: 27 сен 2014
  14. altex

    altex Гик

    Обнаружил очень странное поведение у компаратора, которое не могу объяснить.
    Посмотрите схему - http://c2n.me/iZfwM8.png
    Здесь я с помощью переменного сопротивления регулирую напряжение, которое подаётся на отрицательный вход компаратора.
    С обоих входов компаратора я сделал выводы на аналоговые входы Arduino PINA0 и PINA1, на которых я считываю значение напряжения на входах компаратора.

    Так вот проблема.

    Когда на положительном входе компаратора 0.56В, то компаратор меняет своё состояние, когда я с помощью переменного сопротивления пересекаю именно это значение, тоесть с 0.57В снижаю до 0.55В. В этот момент происходит переключение.

    Когда же на положительном входе компаратора 4.63В, то компаратор меняет своё состояние, когда я с помощью переменного сопротивления пересекаю другое значение, а именно 3.90В. Тоесть с 3.89 В повышаю до 3.91В. В этот момент происходит переключение.

    Как это можно объяснить?

    Скетч
    Код (Text):
    // глобальные переменные, используемые в прерываниях (см. далее)
    // должны быть отмечены как нестабильные (англ. volatile)
    volatile unsigned long score1 = 0;
    volatile unsigned long score2 = 0;

    void setup()
    {
      attachInterrupt(INT1, pushP1, RISING); // INT1 — это 3-й пин
      attachInterrupt(INT0, pushP2, RISING); // INT0 — это 2-й пин
     
      pinMode(A0, INPUT);
      pinMode(A1, INPUT);
     
      Serial.begin(9600);
    }

    void pushP1() { ++score1; } // функция-прерывание 1-го игрока
    void pushP2() { ++score2; } // функция-прерывание 2-го игрока

    float a0volts = 0;
    float a1volts = 0;

    void loop()
    {
      Serial.print("Score1=");
      Serial.print(score1);
      Serial.print(" Score2=");
      Serial.print(score2);

      a0volts = 5.0 * (analogRead(A0) / 1023.0);
      Serial.print(" A0=");
      Serial.print(a0volts);

      a1volts = 5.0 * (analogRead(A1) / 1023.0);
      Serial.print(" A1=");
      Serial.print(a1volts);

      Serial.println("");
      delay(100);
    }
     
     
  15. ALev

    ALev Гик

    Ух, пойду в то место, где я «потерялся» и попытаюсь осилить всё это :) Очень здорово, что есть такие упёртые и пытливые люди, как вы! :)
     
  16. altex

    altex Гик