No Image

Ардуино семисегментный индикатор таймер

СОДЕРЖАНИЕ
658 просмотров
12 декабря 2019

РАБОТАЕМ ПО ТАЙМЕРУ В ARDUINO

Я думаю все знают классический алгоритм создания таймера на millis() – счётчике аптайма:

Классический таймер на millis()

Несколько таймеров

Данный алгоритм позволяет спокойно переходить через переполнение millis() без потери периода, но имеет один большой минус – время считается с момента последнего вызова таймера, и при наличии задержек в коде таймер будет накапливать погрешность, отклоняясь от “ритма”. Недавно я придумал более точный алгоритм таймера на миллис, который соблюдает свой период даже после пропуска хода!

Улучшенный таймер

Данный таймер имеет механику классического таймера с хранением переменной таймера, а его период всегда кратен PERIOD и не сбивается. Эту конструкцию можно упростить до

В этом случае алгоритм получается короче, кратность периодов сохраняется, но теряется защита от пропуска вызова и переполнения millis().

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

Примечание: таких таймеров можно создать сколько душе угодно (пока хватит памяти), что позволяет создавать сложные программы с кучей подзадач, но для функционирования данного таймера нужен “чистый” loop с минимальным количеством задержек, или вообще без них. Всё таки таймер “опрашивается” в ручном режиме. Таймер, который не боится задержек, делается на прерывании таймера, смотрите вот эту библиотеку.

БИБЛИОТЕКА GYVERTIMER

GyverTimer v3.2

GTimer – полноценный таймер на базе системных millis() / micros(), обеспечивающий удобную мультизадачность и работу с временем, используя всего одно родное прерывание таймера (Timer 0)

  • Миллисекундный и микросекундный таймер
  • Два режима работы:
  • Режим интервала: таймер “срабатывает” каждый заданный интервал времени
  • Режим таймаута: таймер “срабатывает” один раз по истечении времени (до следующего перезапуска)
  • Служебные функции:
    • Старт
    • Стоп
    • Сброс
    • Продолжить
    • Поддерживаемые платформы: все Arduino (используются стандартные Wiring-функции)

      ДОКУМЕНТАЦИЯ

      Документация

      Конструктор

      Класс GTimer позволяет работать как с миллисекундным, так и с микросекундным таймером. В общем виде пример выглядит так:

      Где type это MS (,мс, миллисекундный таймер) или US (мкс, микросекундный), period – период в мс или мкс соответственно.

      Настройки по умолчанию

      • При создании таймера можно ничего не указывать : GTimer myTimer; , тогда таймер будет сконфигурирован как миллисекундный и не запустится
      • Если указать только тип таймера (MS/US) GTimer myTimer(MS); , таймер настроится на выбранный режим (мс/мкс) и не запустится
      • Если указать тип таймера и интервал GTimer myTimer(US, 5000); , таймер настроится на выбранный режим (мс/мкс) и запустится в режиме интервала
      Читайте также:  Домкрат гидравлический подкатной зубр отзывы

      Режимы работы

      Таймер может работать в режиме интервалов и в режиме таймаута:

      • Интервалы. Запуск – метод setInterval(время) с указанием времени. В режиме интервалов таймер срабатывает (метод isReady() возвращает true) каждый раз при достижении указанного периода и автоматически перезапускается. Удобно для периодических действий
      • Таймаут. Запуск – метод setTimeout(время) с указанием времени. В режиме таймаута таймер срабатывает (метод isReady() возвращает true) только один раз при достижении указанного периода и автоматически отключается. Для повторного запуска нужно вызвать .setTimeout() с указанием периода, или просто .start() – запустит таймер на новый круг с прежним периодом

      Управление таймером

      Для управления состоянием таймера есть следующие методы:

      • start() – запускает (перезапускает) таймер с последним установленным временем
      • stop() – останавливает таймер
      • resume() – продолжает отсчёт таймера с момента остановки
      • reset() – сбрасывает таймер (отсчёт периода/таймаута начинается заново)
      • isEnabled() – возвращает true, если таймер работает (если он не stop() или не вышел таймаут)

      цифровая электроника вычислительная техника встраиваемые системы

      Простой Arduino-счетчик на 7-сегментном индикаторе

      Это простой проект на Arduino, заключающийся в создании счетчика на обычном 7-сегментном индикаторе с общим катодом. Код, приведенный ниже, позволяет при нажатии кнопки запускать счет от 0 до 9.

      Вся схема может быть запитана от стандартной 9-вольтовой батарейки или от любого Arduino-совместимого блока питания.

      7-сегментный индикатор – очень простое устройство. Он представляет собой комбинацию 8 светодиодов (восьмой светодиод отвечает за точку) с общим катодом, которые можно включать в определенной последовательности так, чтобы они образовывали цифры. Следует обратить внимание, что в данном случае выводы 3 и 8 отведены под катод.

      Ниже показана таблица соответствия выводов Arduino и выводов индикатора.

      Наверняка у многих валяется вот такая светодиодная панелька:

      Правильное название: семисегментный индикатор

      Он получил такое названия благодаря тому, что в его корпусе находится 7 сегментов — светодиодов (часто добавляют ещё 8-й — точку).

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

      Читайте также:  Волнистые асбестоцементные листы вес м2

      Работать с семисегментом надо как со сборкой светодиодов (с общим катодом или анодом). Распиновку можно узнать, прозванивая ножки мультиметром. У меня получилось так: ( общий катод)

      Каждый сегмент — это отдельный светодиод (красный или зелёный). Если подключаем к источнику 5V, то последовательно с каждым из них нужно подключить по резистору (150-300 ом) — чтобы не перегорели.

      А соединять с Arduino я предлагаю через сдвиговый регистр 74HC595N (интерфейс SPI)

      схема на BreadBoard:

      Принципиальную схему не смог нарисовать в sPlan (нет 28-пиновой Atmega), так-что сделал в Fritzing:

      Описание схемы:

      — ноги 15,1,2,3,4.5,6,7 — это выходы регистра. Их подключаем к соответствующим ногам индикатора (A к Q0, B к Q1, C к Q3, ну и т. д.. Главное, чтобы было по порядку — тогда часть программирования будет проще)
      — ноги 8 и 16 — это питание микросхемы (подключаем к GND и +5V Arduino)
      — 10 ногу к +5V
      — 13 ногу к GND
      — Ноги 14, 12, 11 — управляющие пины шины SPI .
      11 (SH_CP) — тактовая шина (clock) к 13 контакту Arduino (не принципиально)
      12 (ST_CP) — защёлка (latch) к 12 контакту Arduino (не принципиально)
      14 (DS) — данные (data) к 8 контакту Arduino (не принципиально)

      Прошивка

      Код очень простой. Мы даже не будем использовать библиотеку SPI. Посылать данные будем функцией shiftOut()

      Она будет отправлять регистру 1 байт (8 бит). Каждый сегмент — это 1 бит. ( Если отправить вот такой байт: 0b10000000, то получим такую вот картину: (зажжётся первый сегмент — А)

      Суть: Зажигая определённую комбинацию сегментов, мы получаем на экране цифру. Так, например, если зажечь сегменты B и С то загорится единичка. A, B, C — семёрка, и т. д..

      Сам код: SevSeg1_SPI.ino

      Список радиоэлементов

      Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
      Плата Arduino 1 Поиск в Utsource В блокнот
      Сдвиговый регистр 1 Поиск в Utsource В блокнот
      Резистор 100-300 Ом 8 Поиск в Utsource В блокнот
      Семисегментный индикатор 1 Поиск в Utsource В блокнот
      Добавить все

      Прикрепленные файлы:

      Оценить статью

      • Техническая грамотность

      Средний балл статьи: 0 Проголосовало: 0 чел.

      Комментарии (4) | Я собрал ( 0 ) | Подписаться

      Для добавления Вашей сборки необходима регистрация

      #define CLOCK 13 //SH_CP
      #define DATA 12 //DS
      #define LATCH 8 //ST_CP
      int val = 0;

      Читайте также:  Бойлер дражице okc 160 ntr

      //настраиваем контакты на выход
      pinMode(CLOCK, OUTPUT);
      pinMode(DATA, OUTPUT);
      pinMode(LATCH, OUTPUT);

      //отключаем LATCH (чтобы регистр не ждал данных)
      digitalWrite(LATCH, HIGH);
      >

      0b12345678
      */
      switch (val) <
      case -1: //точка
      shiftOut(DATA, CLOCK, LSBFIRST, 0b00000001);
      break;
      case 0: //0
      shiftOut(DATA, CLOCK, LSBFIRST, 0b11111100);
      break;
      case 1: //1
      shiftOut(DATA, CLOCK, LSBFIRST, 0b01100000);
      break;
      case 2: //2
      shiftOut(DATA, CLOCK, LSBFIRST, 0b11011010);
      break;
      case 3: //3
      shiftOut(DATA, CLOCK, LSBFIRST, 0b11110010);
      break;
      case 4: //4
      shiftOut(DATA, CLOCK, LSBFIRST, 0b01100110);
      break;
      case 5: //5
      shiftOut(DATA, CLOCK, LSBFIRST, 0b10110110);
      break;
      case 6: //6
      shiftOut(DATA, CLOCK, LSBFIRST, 0b10111110);
      break;
      case 7: //7
      shiftOut(DATA, CLOCK, LSBFIRST, 0b11100000);
      break;
      case 8: //8
      shiftOut(DATA, CLOCK, LSBFIRST, 0b11111110);
      break;
      case 9: //9
      shiftOut(DATA, CLOCK, LSBFIRST, 0b11110110);
      break;
      case 10: //A
      shiftOut(DATA, CLOCK, LSBFIRST, 0b11101110);
      break;
      case 11: //b
      shiftOut(DATA, CLOCK, LSBFIRST, 0b00111110);
      break;
      case 12: //C
      shiftOut(DATA, CLOCK, LSBFIRST, 0b10011100);
      break;
      case 13: //d
      shiftOut(DATA, CLOCK, LSBFIRST, 0b01111010);
      break;
      case 14: //E
      shiftOut(DATA, CLOCK, LSBFIRST, 0b10011110);
      break;
      case 15: //F
      shiftOut(DATA, CLOCK, LSBFIRST, 0b10001110);
      break;
      case 16: //G
      shiftOut(DATA, CLOCK, LSBFIRST, 0b10111100);
      break;
      case 17: //H
      shiftOut(DATA, CLOCK, LSBFIRST, 0b01101110);
      break;
      case 18: //I
      shiftOut(DATA, CLOCK, LSBFIRST, 0b01100000);
      break;
      case 19: //J
      shiftOut(DATA, CLOCK, LSBFIRST, 0b01110000);
      break;
      case 20: //L
      shiftOut(DATA, CLOCK, LSBFIRST, 0b00011100);
      break;
      case 21: //n
      shiftOut(DATA, CLOCK, LSBFIRST, 0b00101010);
      break;
      case 22: //O
      shiftOut(DATA, CLOCK, LSBFIRST, 0b11111100);
      break;
      case 23: //P
      shiftOut(DATA, CLOCK, LSBFIRST, 0b11001110);
      break;
      case 24: //q
      shiftOut(DATA, CLOCK, LSBFIRST, 0b11100110);
      break;
      case 25: //S
      shiftOut(DATA, CLOCK, LSBFIRST, 0b10110110);
      break;
      case 26: //U
      shiftOut(DATA, CLOCK, LSBFIRST, 0b01111100);
      break;
      //некоторые буквы невозможно отобразить. их нет в списке
      >

      //включаем LATCH (Начинаем общение)
      digitalWrite(LATCH, HIGH);
      if(val==26) <
      val=-2;
      >
      delay(1000);
      val=val+1;
      >

      #define CLOCK 13 //SH_CP 11 74СН
      #define DATA 12 //DS 14 74СН
      #define LATCH 8 //ST_CP 12 74СН

      // — распиновка сегментов
      byte numberSegments[10] = <
      0b11111101, 0b01100000, 0b11011010, 0b11110010, 0b01100110,
      0b10110110, 0b10111110, 0b11100000, 0b11111110, 0b11110110,
      >;

      //настраиваем контакты на выход
      pinMode(CLOCK, OUTPUT);
      pinMode(DATA, OUTPUT);
      pinMode(LATCH, OUTPUT);

      //отключаем LATCH (чтобы регистр не ждал данных)
      digitalWrite(LATCH, HIGH);
      >

      void loop() <
      for (int i = 0; i

      Комментировать
      658 просмотров
      Комментариев нет, будьте первым кто его оставит

      Это интересно
      Adblock detector