код для КНОПОК - помогите разобраться

Тема в разделе "Микроконтроллеры AVR", создана пользователем Alexandro77, 26 сен 2019.

Метки:
  1. b707

    b707 Гуру

    Остров, сорри за оценку, но это шляпа какаята
    Недостатки:
    - Жеский период, не привязанный к нажатию кнопки. Просто лупим наобум? а если оно "удачно" проскочило со своими 50мс между нажатиями?
    - работа с миллисами корявая,
    - тип подключения кнопки (к плюсу или к минусу ) - не настраивается

    какой-то новичковый уровень.
     
  2. SergeiL

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

    Это те самые кольцевые буфера?
     
  3. ostrov

    ostrov Гуру

    Все настраивается. И периоды и плюс-минус и о проблеме с переполнением я написал, решается в одном месте одним знаком.Кстати, сможете молотить по кнопке чаще чем раз в 50 мс?

    И не новичковый, а учебный. Но рабочий, простой и эффективный.
     
    Последнее редактирование: 28 сен 2019
  4. ostrov

    ostrov Гуру

    По сути, да.
     
  5. offigate

    offigate Нерд

    1. Для каждой кнопки заводите свою 8-битную служебную переменную
    2. Каждые 10 мс сдвигаете значение этой переменной влево и читаете вход. Если кнопка нажата, то устанавливаете младший бит переменной в 1.
    3. Состояние кнопки на выходе (булевская переменная) определяете так: если в служебной переменной все единицы - кнопка нажата, если все нули - кнопка отжата, если любое другое значение - состояние кнопки не изменилось и остается таким же, каким было раньше.
    При указанном интервале 10 мс будет подавлены все импульсы дребезга длительностью до 80 мс, это подходит для большинства кнопок.. Маленькие тактильные кнопки можно опрашивать чаще, у них короткий дребезг. Массивные выключатели и контакты больших реле могут дребезжать до пары сотен миллисекунд, их лучше опрашивать пореже.

    Код может быть примерно такой
    Код (C++):

    struct {
      bool pressed;
      byte shreg;
      unsigned long ts;
    }button;

    void loop(void)
    {
      if (millis() >= button.ts)
      {
        button.ts = millis() + 10; // +10 мс
        button.shreg <<= 1;
        if (digitalRead(pinButton)) // читаем пин
          button.shreg |= 1;
        if (button.shreg == 0)
          button.pressed = false; // все нули, кнопка отжата
        if (button.shreg == 0xFF)
          button.pressed = true; // все единицы, кнопка нажата
      }
    }
     
    Последнее редактирование: 20 ноя 2019
    Daniil и ИгорьК нравится это.
  6. ИгорьК

    ИгорьК Гуру

    Здесь не может быть засады?
     
    Последнее редактирование: 20 ноя 2019
  7. DetSimen

    DetSimen Guest

    здесь засада в совокупности с
    if(millis()> button.ts)
     
  8. offigate

    offigate Нерд

    Поправил

    В принципе еще есть еще эффект, связанный с "перескоком" значений millis(), но здесь он вроде бы не возникнет. И еще потенциальный эффект из-за неатомарности работы с millis(), что решается так

    Код (C++):
    void loop(void)
    {
      unsigned long currMillis = millis();
      if (currMillis >= button.ts)
      {
        button.ts = currMillis + 10; // +10 мс
        button.shreg <<= 1;
        if (digitalRead(pinButton)) // читаем пин
          button.shreg |= 1;
        if (button.shreg == 0)
          button.pressed = false; // все нули, кнопка отжата
        if (button.shreg == 0xFF)
          button.pressed = true; // все единицы, кнопка нажата
      }
    }
     
    Последнее редактирование: 20 ноя 2019
  9. ИгорьК

    ИгорьК Гуру

    Мне кажется - нет.
     
    DetSimen нравится это.
  10. ИгорьК

    ИгорьК Гуру

    Та вычитать надо, сравнивать сразу низя.
     
    SergeiL нравится это.
  11. offigate

    offigate Нерд

    Типа

    Код (C++):
    if (currentMillis - startMillis >= period)  //test whether the period has elapsed
    А в чем там мулька?

    Я особо не раздумывая срисовал эту часть с сообщения #18, которое на этот счет возражений ни у кого вроде бы не вызывало.
     
  12. SergeiL

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

    А следующее сообщение?
     
  13. ИгорьК

    ИгорьК Гуру

    Представьте что у вас время uint_8t и сразу поймёте.
     
  14. offigate

    offigate Нерд

    Которое "Много кода"? И в чем же состоит ваш вопрос?
     
  15. SergeiL

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

    Нет, эти мы пропускаем, они же флудерские.
    Я имел в виду #21
     
  16. offigate

    offigate Нерд

    "Работа с миллисами корявая" - это как-то расплывчато. Из-за отсутствия конкретики я это вообще мимо ушей пропустил. Тем более что автор в #23 браво отбился от всех обвинений и все промолчали. А молчание, как известно, знак согласия.
     
  17. SergeiL

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

    Все, все поняли. :)
    С миллис только вычитание правильно работает.
     
  18. DetSimen

    DetSimen Guest

    сиё нерду пока неведомо.
     
  19. offigate

    offigate Нерд

    Я уже понял, что такой код работает только у гур. А вот растолкуйте нерду, что конкретно в данном случае плохого случится из-за "корявой работы с millis()"? Я думаю, это всем будет интересно.
     
  20. DetSimen

    DetSimen Guest

    все нормальные это и так знают. Гугли "Великое Переполнение Millis"