Меню

Схема счетчика нажатий кнопки

Arduino – работа с кнопками

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

  • С фиксацией – кнопка остаётся нажатой после отпускания, без фиксации – отключается обратно.
  • Нормально разомкнутая (Normal Open, NO) – при нажатии замыкает контакты. Нормально замкнутая (Normal Closed, NC) – при нажатии размыкает контакты.
  • Тактовые кнопки – замыкают или размыкают контакт. У обычных тактовых кнопок ноги соединены вдоль через корпус (см. картинку ниже). Переключатели – обычно имеют три контакта, общий COM, нормально открытый NO и нормально закрытый NC. При отпущенной кнопке замкнута цепь COM-NC, при нажатой замыкается COM-NO.

Подключение и подтяжка

Из урока про цифровые пины вы помните, что микроконтроллер может считывать напряжение со своей ноги. Соответственно кнопка может подать на пин тот уровень, к которому подключена её вторая нога. В том же уроке мы обсуждали, что не подключенный никуда цифровой пин принимает наводки из воздуха, и считанное с него значение будет практически случайным. То есть подключив к пину 5V (сигнал высокого уровня) через кнопку, мы ничего не добьёмся: при нажатой кнопке на пине будет считываться четкий сигнал высокого уровня, а при отпущенной – случайное значение. Для решения этой проблемы существует такое понятие, как подтяжка (pull) пина. Подтяжка выполняется к земле (pull down) или питанию (pull up) микроконтроллера при помощи резистора. Подтяжка выполняется противоположно принимаемому сигналу, т.е. если нужно ловить высокий сигнал, подтяжка выполняется к земле, если ловить нужно сигнал земли – подтяжка выполняется к питанию. Вот два варианта подключения кнопки, с подтяжкой к VCC и GND соответственно:


Как выбирается сопротивление резистора? Тут всё очень просто: при нажатии на кнопку через резистор потечёт ток, так как в любом случае замыкается цепь питание-земля. Чем выше ток, больше потери энергии и нагрев резистора, а это никому не нужно, поэтому сопротивление резистора подтяжки обычно выбирается в диапазоне 5-50 кОм. Если ставить больше – подтяжка может не обеспечить стабильный уровень сигнала на пине, а если ставить меньше – будут больше потери энергии в нагрев резистора: при сопротивлении в 1 ком через него потечёт ток величиной 5 В/1000 Ом = 5 мА, для сравнения плата Ардуино с МК в активном режиме потребляет 20-22 мА. Чаще всего для подтяжки используется резистор на 10 кОм.

Как вы помните из урока о цифровых пинах, у МК AVR есть встроенные резисторы для всех GPIO, эти резисторы подключены к питанию (к VCC), то есть буквально дублируют первую схему из этого урока и позволяют не использовать внешний резистор. У микроконтроллеров другой архитектуры бывает подтяжка к GND, или вообще может не быть внутренней подтяжки. При использовании подтяжки к питанию мы получим инвертированный сигнал – функция digitalRead() вернёт 1 при отпущенной кнопке, и 0 при нажатой (при использовании нормально-разомкнутой кнопки). Давайте подключим кнопку на пин D3 (и GND):

Алгоритмы

Отработка нажатия

В большинстве реальных применений работать с текущим состоянием кнопки очень неудобно, например когда действие должно быть выполнено однократно при нажатии на кнопку, т.е. по клику. Чуть усложним конструкцию, добавив один флаг, который будет помнить состояние кнопки. Такая конструкция позволяет отслеживать нажатие и отпускание кнопки и реагировать на них однократно:

Дребезг контактов

Кнопка не идеальна, и контакт замыкается не сразу, какое-то время он “дребезжит”. Прогоняя данный алгоритм, система опрашивает кнопку и условия приблизительно за 6 мкс, то есть кнопка опрашивается 166’666 раз в секунду! Этого достаточно, чтобы получить несколько тысяч ложных срабатываний.

Читайте также:  Сколько дней до зимних каникул счетчик

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


Программно можно ввести простейший таймер нажатия, основанный на millis() , время гашения дребезга примем 100 миллисекунд. Вот так будет выглядеть код:

Рекомендуется конечно же использовать аппаратный способ, так как он не нагружает ядро лишними расчетами. В 99.99% проектов будет достаточно программного антидребезга, так то смело используйте конструкцию с millis() .

“Импульсное” удержание

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

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

Источник



СЧЁТЧИК НА МИКРОКОНТРОЛЛЕРЕ

Счётчик на микроконтроллере довольно прост для повторения и собран на популярном МК PIC16F628A с выводом индикации на 4 семисегментных светодиодных индикатора. Счётчик имеет два входа управления: «+1» и «-1», а также кнопку «Reset». Управление схемой нового счётчика реализовано таким образом, что как бы долго или коротко не была нажата кнопка входа, счёт продолжится только при её отпускании и очередном нажатии. Максимальное количество поступивших импульсов и соответственно показания АЛС — 9999. При управлении на входе «-1» счёт ведётся в обратном порядке до значения 0000. Показания счётчика сохраняются в памяти контроллера и при отключении питания, что сохранит данные при случайных перебоях питающего напряжения сети.

Принципиальная схема реверсивного счётчика на микроконтроллере PIC16F628A:

Сброс показаний счётчика и одновременно состояния памяти в 0, осуществляется кнопкой «Reset». Следует помнить, что при первом включении реверсивного счётчика на микроконтроллере, на индикаторе АЛС может высветиться непредсказуемая информация. Но при первом же нажатии на любую из кнопок информация нормализируется. Где и как можно использовать эту схему — зависит от конкретных нужд, например установить в магазин или офис для подсчёта посетителей или как индикатор намоточного станка. В общем думаю, что этот счётчик на микроконтроллере кому-нибудь принесёт пользу.

Если у кого-то под рукой не окажется нужного индикатора АЛС, а будет какой-нибудь другой (или даже 4 отдельных одинаковых индикатора), я готов помочь перерисовать печатку и переделать прошивку. В архиве на форуме схема, плата и прошивки под индикаторы с общим анодом и общим катодом. Печатная плата показана на рисунке ниже:

Имеется также новая версия прошивки для счётчика на микроконтроллере PIC16F628A. при этом схема и плата счётчика остались прежними, но поменялось назначение кнопок: кнопка 1 — вход импульсов (например, от геркона), 2 кнопка включает счёт на вычитание входных импульсов, при этом на индикаторе светится самая левая точка, 3 кнопка — сложение импульсов — светится самая правая точка. Кнопка 4 — сброс. В таком варианте схему счётчика на микроконтроллере можно легко применить на намоточном станке. Только перед намоткой или отмоткой витков нужно сначала нажать кнопку «+» или «-«. Питается счётчик от стабилизированного источника напряжением 5В и током 50мА. При необходимости можно питать от батареек. Корпус зависит от ваших вкусов и возможностей. Схему предоставил — Samopalkin

Источник

Счетчики. Вариант 1 — Простейший счетчик на базе Arduino

Опубликовано: 01.06.2017 19:27

Читайте также:  Котлы отопления все газовые счетчики

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

  • Плата Arduino Nano, либо Uno, в общем то подойдёт любая плата семейства Arduino
  • Две тактовые кнопки, в нашем прототипе мы используем готовые модули кнопок
  • 7-ми сегментный дисплей на базе драйвера TM1637
  • Корректная библиотека для дисплеев на базе драйвера TM1637. Скачать можно по ссылке.
  • Набор проводов с разъёмом Dupont(Тип окончания Папа-Папа)
  • Ну и конечно же желание, куда же без него.

Вот фото всего того что нам понадобится, плата Arduino Nano установлена на отладочный шилд I/O Wireless Shield for Nano:

Соединяем провода согласно нижеприведённой схеме:

Если вдруг у вас нет модулей кнопок, то можно решить эту задачу согласно следующей схеме:

Это тоже самое что и предыдущий чертеж, только модули кнопок здесь как бы разнесены на свои принципиальные схемы.

После того как все провода соединены, остаётся только загрузить скетч в контроллер, и испытать полученный прототип. Скетч выложен ниже, его можно просто скопировать в свой проект на Arduino IDE, но прежде всего, чтобы всё правильно откомпилировалось, нужно установить библиотеку для дисплеев на базе драйвера TM1637.

Как работает прототип счетчика? Всё в общем то просто — зеленая кнопка имитирует событие, к примеру проход изделия по конвейеру, сигнал с кнопки считывается программой и далее происходит инкремент значения счетчика. Красная кнопка служит для сброса значения счетчика в ноль. Также в программе реализована функция обработки дребезга контактов кнопки(либо концевого датчика), чтобы избежать ложных подсчетов импульсов. Вместо кнопки имитации импульсов можно использовать любой из концевых датчиков, например вот такие:

но, при этом предварительно подтянув порт подключения датчика к земле. Из плат можно использовать любую доступную, будь то UNO, Mega, и даже такого малыша как Digispark ATTiny85. На этом в общем то и всё, в конце хотелось представить вам обзорное видео по статье:

Источник

Чебоксары

Данный счетчик будет считать количество нажатых кнопок или к примеру количество срабатываний геркона, кнопку в свою очередь можно прицепить куда угодно, например к двери, чтоб считать количество открываний. В качестве устройства индикации мы будем использовать 4-х разрядный семисегментный индикатор. Поскольку мы ваяем счётчик нажатий кнопки, то считать он будет целые числа, а следовательно точка нам ни к чему.

Каждый сегмент индикатора это один обычный светодиод. А значит для того чтоб он не сгорел, нужно ограничить ток который через него проходит. Для этого мы будем использовать семь резисторов на на 220 ом каждый. Таким образом ток через каждую ножку подключенную к сегментам не превысит 15 мА что вполне допустимо. Для того чтоб уменьшить нагрузку на общие выводы, в схеме применяются ключевые транзисторы. Когда на базу транзистора поступает лог 1 с контроллера, он открывается и соединяет общий вывод индикатора с землёй, тем самым принимая всю нагрузку на себя.

схему в большем разрешении.

Транзисторы можно применить вообще любые n-p-n типа. У меня нашлись BC547 вот их то я и использовал. Четыре резистора по 1К обязательны, они ограничивают ток базы. Если таких нет, то можно заюзать другие (не слишком большого сопротивления) лишь бы транзистор полностью открывался. Теперь о кнопке. у нас она будет подключена к ноге PA0, это удобно так как эта кнопка уже есть на STM32vl Discovery и припаивать её мне не придётся. На этом описание аппаратной части можно считать законченным.

#include «stm32f10x.h»
#include «stm32f10x_gpio.h»
#include «stm32f10x_rcc.h»
// Порт к которому подключен индикатор
#define IND_PORT GPIOB
// Общие выводы индикатора
#define D0 GPIO_Pin_7
#define D1 GPIO_Pin_8
#define D2 GPIO_Pin_9
#define D3 GPIO_Pin_10
// К какой ноге какой сегмент подключен
#define SEG_A GPIO_Pin_0
#define SEG_B GPIO_Pin_1
#define SEG_C GPIO_Pin_2
#define SEG_D GPIO_Pin_3
#define SEG_E GPIO_Pin_4
#define SEG_F GPIO_Pin_5
#define SEG_G GPIO_Pin_6
//Собираем цифры из сегментов
#define DIG0 ( SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F )
#define DIG1 ( SEG_B | SEG_C )
#define DIG2 ( SEG_A | SEG_B | SEG_G | SEG_E | SEG_D )
#define DIG3 ( SEG_A | SEG_B | SEG_G | SEG_C | SEG_D )
#define DIG4 ( SEG_F | SEG_G | SEG_B | SEG_C)
#define DIG5 ( SEG_A | SEG_F | SEG_G | SEG_C | SEG_D )
#define DIG6 ( SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G )
#define DIG7 ( SEG_A | SEG_B | SEG_C )
#define DIG8 ( SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
#define DIG9 ( SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G)
#define ALL_PINS (DIG8 | D0 | D1 | D2 | D3 )

Читайте также:  Куда вставить код счетчика яндекс метрика joomla

//Функция выводит в порт нужную цифру
void digit_to_port (uint8_t digit) <
uint8_t digitsp[]=;
IND_PORT->ODR &=

DIG8; //Выключаем все сегменты
IND_PORT->ODR |= digitsp[digit]; //Зажигаем нужные
>

//Функция формирующая небольшую задержку
void Delay(void) <
volatile uint32_t i;
for (i=0; i != 0x1000; i++);
>

int main(void) <
uint16_t counter=0; //Счётчик нажатий
uint16_t tmp; // Содержит копию counter
// (из него по очереди исключаются последние цифры)
uint8_t digit; // В эту переменную поочередно записываются цифры
// из которых состоит число counter
uint8_t button_flag=0;
//Выключаем JTAG (он занимает ноги нужные нам)
RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO , ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
//Настраиваем на выход все ноги подключенные к индиакатору
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitTypeDef PORT; //Структура содержащая настройки порта
PORT.GPIO_Pin = ALL_PINS; //Указываем какие ноги нужно настроить
PORT.GPIO_Mode = GPIO_Mode_Out_PP; // Настраиваем как выход Push-pull
PORT.GPIO_Speed = GPIO_Speed_2MHz; // Частота 2 МГц
GPIO_Init(IND_PORT, &PORT); //Вызываем функцию настройки порта
//Настраиваем ногу (PA0) с кнопкой на вход
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE);
PORT.GPIO_Pin = GPIO_Pin_0;
PORT.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &PORT);
while(1) <
if ((GPIOA->IDR & 0x01)==0x01) < //Кнопка нажата ?
if (!button_flag) counter++;
if (counter==10000) < //Досчитали до предела ?
counter=0; //обнуляем счётчик
>
button_flag=1;
> else <
button_flag=0;
>
tmp=counter;
//Вытаскиваем первую справа цифру из числа counter
digit = tmp % 10;
tmp = tmp / 10;
//Выключаем все разряды
IND_PORT->ODR &=

(D0|D1|D2|D3);
//Включаем нулевой разряд индикатора
IND_PORT->ODR |= D0;
//Выводим цифру в нулевой разряд
digit_to_port(digit);
//Небольшая задержка. Пусть цифра погорит некоторое время
Delay();
//Вытаскиваем вторую справа цифру из числа counter
digit = tmp % 10;
tmp = tmp / 10;
//Выключаем все разряды
IND_PORT->ODR &=

(D0|D1|D2|D3);
//Включаем первый разряд индикатора
IND_PORT->ODR |= D1;
//Выводим цифру в первый разряд
digit_to_port(digit);
//Небольшая задержка. Пусть цифра погорит некоторое время
Delay();
//Вытаскиваем третью справа цифру из числа counter
digit = tmp % 10;
tmp = tmp / 10;
//Выключаем все разряды
IND_PORT->ODR &=

(D0|D1|D2|D3);
//Включаем второй разряд индикатора
IND_PORT->ODR |= D2;
//Выводим цифру в второй разряд
digit_to_port(digit);
//Небольшая задержка. Пусть цифра погорит некоторое время
Delay();
//Тут мы цифр не вытаскиваем. В переменной counter уже самая старшая цифра
//Выключаем все разряды
IND_PORT->ODR &=

(D0|D1|D2|D3);
//Включаем третий разряд индикатора
IND_PORT->ODR |= D3;
//Выводим цифру в третий разряд
digit_to_port(tmp);
//Небольшая задержка. Пусть цифра погорит некоторое время
Delay();
>
>

При создании новго проекта в CooCox’e нужно не забыть поставить галку GPIO. С использованием этой библиотеки код становится более читаемым, не нужно помнить о том для чего нужен каждый бит. Многое в этом коде откомментировано, думаю что особых проблем с пониманием написанного не возникнет. Ну а если вопросы появятся то можно задать их чуть ниже. Компилируем, прошиваем, запускаем и получаем в результате что-то типа такого:

Работает! Жмем кнопку — значение счётчика увеличивается. Теперь можно сделать для всего этого отдельный корпус и найти счётчику достойное применение 🙂

Источник