Оглавление
- Откуда берётся время?
- Немного о принципах работы OLED дсиплея
- Кухонный таймер Ардуино с энкодером
- Writing datetime #
- Общие сведения
- Немного физики
- Circuit #
- Модули часов реального времени в проектах Arduino
- Работа программного обеспечения
- Мигаем светодиодом без delay()
- Функция delay()
- Управление семисегментными индикаторами
Откуда берётся время?
Начнём с того, откуда вообще микроконтроллер знает, сколько проходит времени. Ведь у него нет часов! Для работы микроконтроллера жизненно важен так называемый тактовый генератор, или кварцевый генератор, или он же кварц. Он же oscillator, он же clock. Clock по-английски это часы. Да, но не всё так просто =) Кварц расположен рядом с МК на плате (также во многих МК есть встроенный тактовый генератор), на Ардуинах обычно стоит кварц на 16 МГц, также встречаются модели на 8 МГц. Кварц выполняет очень простую вещь: он пинает микроконтроллер со своей тактовой частотой, то есть 16 МГц кварц пинает МК 16 миллионов раз в секунду. Микроконтроллер, в свою очередь зная частоту кварца, может прикинуть время между пинками (16 МГц = 0.0625 микросекунды), и таким образом ориентироваться во времени. Но на деле не всё так просто, потому что принимают пинки таймера так называемые таймеры-счётчики (Timer-counter). Это физически расположенные внутри МК устройства, которые занимаются подсчётом пинков тактового генератора. И вот микроконтроллер уже может обратиться к счётчику и спросить, а сколько там натикало? И счётчик ему расскажет. И вот этим мы уже можем пользоваться, для этого у Ардуино есть готовые функции времени. В Ардуино на МК 328 имеются три счётчика, и подсчётом времени занимается таймер под номером 0. Этим может заниматься любой другой счётчик, но работая в Arduino IDE вы сразу получаете такую настройку, т.к. создавая скетч в Arduino IDE вы автоматически работаете с библиотекой Arduino.h, где и реализованы все удобные функции.
Немного о принципах работы OLED дсиплея
Термин OLED расшифровывается как “Organic Light emitting diode”, что в переводе означает органический светоизлучающий диод. Подобные светодиоды применяются в большинстве телевизоров, выпускаемых в настоящее время. В данном проекте мы будем использовать монохромный 4-контактный OLED дисплей SSD1306 с диагональю 0.96”. Этот дисплей может работать только по протоколу I2C. Внешний вид данного дисплея и назначение его контактов показаны на следующем рисунке и таблице.
Наименование контакта | Назначение контакта |
VCC | 3.3v |
GND | земля |
SDA | SDA (Physical pin 3) |
SCL | SCL (Physical pin 5) |
Для работы с OLED дисплеями сообществом Arduino разработано множество библиотек, мы этом проекте применили одну из этих библиотек — Adafruit_SSD1306 Library. Она достаточно проста в использовании и имеет много возможностей для работы с графикой. Также в этом проекте нам понадобится еще одна библиотека, которую необходимо будет скачать и установить — GFX Graphics Library.
Кухонный таймер Ардуино с энкодером
Сейчас рассмотрим, как сделать таймер на Ардуино своими руками с энкодером и LCD. Принцип управления, подобен предыдущему варианту. Поворотом ручки энкодера можно задать необходимый временной интервал, а нажатием на ручку можно запускать и останавливать обратный отсчет времени. Далее размещена схема сборки проекта на Arduino Nano, этот проект можно собрать и на плате Arduino Uno.
Скетч таймера обратного отсчета времени
#include <Wire.h> // библиотека для протокола I2C #include <LiquidCrystal_I2C.h> // библиотека для LCD 1602 LiquidCrystal_I2C LCD(0x27, 20, 2); // присваиваем имя дисплею #include <RotaryEncoder.h> // библиотека для энкодера RotaryEncoder encoder(4, 2); // пины подключение энкодера (DT, CLK) // задаем шаг энкодера, максимальное и минимальное значение #define STEPS 1 #define POSMIN 0 #define POSMAX 30 int lastPos, newPos; boolean buttonWasUp = true; byte w = 0; int SEC = 0; int MIN = 0; unsigned long timer; void setup() { pinMode(6, INPUT_PULLUP); // пин для кнопки энкодера encoder.setPosition(0 / STEPS); pinMode(10, OUTPUT); // подключаем светодиод и зуммер pinMode(12, OUTPUT); digitalWrite(10, HIGH); LCD.init(); // инициализация дисплея LCD.backlight(); // включение подсветки LCD.setCursor(2, 0); LCD.print("TIMER STOP"); LCD.setCursor(5, 1); LCD.print(MIN); LCD.print(" : "); LCD.print(SEC); } void loop() { // проверяем положение ручки энкодера encoder.tick(); newPos = encoder.getPosition() * STEPS; if (newPos < POSMIN) { encoder.setPosition(POSMIN / STEPS); newPos = POSMIN; } else if (newPos > POSMAX) { encoder.setPosition(POSMAX / STEPS); newPos = POSMAX; } // если положение изменилось - меняем переменную MIN и выводим на дисплей if (lastPos != newPos) { MIN = newPos; lastPos = newPos; LCD.clear(); LCD.setCursor(2, 0); LCD.print("TIMER STOP"); LCD.setCursor(5, 1); LCD.print(MIN); LCD.print(" : "); LCD.print(SEC); } // если была нажата кнопка энкодера запускаем отсчет времени boolean buttonIsUp = digitalRead(6); if (buttonWasUp && !buttonIsUp && MIN > 0) { delay(10); buttonIsUp = digitalRead(6); if (!buttonIsUp) { if (SEC == 0) { SEC = 60; MIN = MIN - 1; } if (MIN < 0 ) { MIN = 0; } digitalWrite(10, LOW); w = 1; } } buttonWasUp = buttonIsUp; // запоминаем состояние кнопки while (w == 1 ) { // если прошло 995 мс - вычитаем одну секунду от переменной SEC if (millis() - timer > 993) { timer = millis(); SEC = SEC - 1; // если отсчет закончился - обнуляемся, включаем сигнал и выходим из цикла if (SEC == 0 && MIN == 0) { lastPos = 0; newPos = 0; MIN = 0; SEC = 0; LCD.clear(); LCD.setCursor(2, 0); LCD.print("TIMER STOP"); LCD.setCursor(5, 1); LCD.print(MIN); LCD.print(" : "); LCD.print(SEC); digitalWrite(10, HIGH); tone(12, 100); delay(500); noTone(12); w = 0; } // если секунды дошли до нуля - вычитаем одну минуту if (SEC == 0 && w==1) { SEC = 59; MIN = MIN - 1; if (MIN < 0 ) { MIN = 0; } } // если из цикла while еще не вышли - выводим информацию на дисплей if (w == 1) { LCD.clear(); LCD.setCursor(2, 0); LCD.print("TIMER START"); LCD.setCursor(5, 1); LCD.print(MIN); LCD.print(" : "); LCD.print(SEC); } } // если была нажата кнопка - обнуляем переменные и выходим из цикла buttonIsUp = digitalRead(6); if (buttonWasUp && !buttonIsUp) { delay(10); buttonIsUp = digitalRead(6); if (!buttonIsUp) { lastPos = 0; newPos = 0; MIN = 0; SEC = 0; LCD.clear(); LCD.setCursor(2, 0); LCD.print("TIMER STOP"); LCD.setCursor(5, 1); LCD.print(MIN); LCD.print(" : "); LCD.print(SEC); digitalWrite(10, HIGH); w = 0; } } buttonWasUp = buttonIsUp; // запоминаем состояние кнопки } }
Пояснения к коду:
- частоту звукового сигнала можно изменить через команду tone();
- для скетча потребуется установить библиотеку RotaryEncoder.
Writing datetime #
Create a new patch . We’ll use it only once to write the current time to the memory of RTC module so that it has a proper base point.
- Put an node from the library onto the patch. This node describes an RTC breakout board which communicates via I2C. By default, the I2C device address of the RTC at the pin is which is correct for the most DS1307 modules. The pin of the node outputs the value which contains everything to operate the device.
- Add a node from the library onto the patch. This node’s function is to write time and date to the permanent memory of the RTC board. The pin inputs a type value to be written. The pin triggers a new write. The output pin notifies writing complete.
- Link the pin of the node with the pin of the node.
- The value at the pin means that we write the once after the boot of the device.
The node requires the date and time values having a type. The node is used to pack year, month, day, and hours, minutes, seconds into a type value.
- Put the node onto the patch.
- Link the output pin of the node with the pin of the node.
- Fill the , , , , , and pins with values. Each pin contains a description of what form this values should be.
For example, we set the current date. Now it is the 17-th of September of the 2018 year, and the time is 14 hours 44 minutes and about 31 seconds. To set this date and time values to the RTC, we fill the pins with values.
- The year value to the pin.
- number of the September month to the pin.
- number of the day of the month to the pin.
- number of the hours to the pin.
- number of the minutes to the pin.
- number of the seconds to the pin.
The patch to set up the real-time clock is completed. Let’s quickly load it into the Arduino board, to make the difference between the real and written time be only a few seconds.
Once the board is flashed the RTC module will get the correct current time value which automatically ticks and not get lost as long as the module is powered by either its battery or the device itself. However, note that the time gets re-written on every boot to that exact value we have set. So, if you will reset your board after an hour, it will overwrite the correct time with the now-obsolete hour-lagging value. To protect from this effect it is a good idea to remove the uploaded time setting program. Upload an empty patch right after to clear.
We won’t need the patch anymore.
Общие сведения
Использовании модуля DS1307 зачастую очень оправдано, например, когда данные считываются редко, интервалом более недели, использовать собственные ресурсы контроллера, неоправданно или невозможно. Обеспечивание бесперебойное питание, например платы Arduino, на длительный срок дорого, даже при использовании батареи.
Благодаря собственной памяти и автономностью, можно регистрировать события, (при автономном питании) например изменение температуры и так далее, данные сохраняются в памяти их можно считать из памяти модуля. Так что модуль DS1307 часто используют, когда контроллерам Arduino необходимо знать точное время, для запуска какого то события и так далее.
Обмен данными с другими устройствами осуществляется по интерфейсу I2C с выводов SCL и SDA. Конденсаторы С1 и С2 необходимы для снижения помех по линию питания. Чтобы обеспечить надлежащего уровня сигналов SCL и SDA установлены резисторы R2 и R3 (подтянуты к питанию). Для проверки работоспособности модуля, на вывод 7 микросхему DS1307Z, подается сигнал SQ, прямоугольной формы с частотой 1 Гц. Элементы R4, R5, R6, VD1 необходимы для подзарядку литиевой батарейки. Так же, на плате предусмотрено посадочное место (U1), для установки датчика температуры DS18B20 (при необходимости можно впаять его), считывать показания, можно с вывода DS, который подтянут к пиатнию, через резистор R1 сопротивлением 3.3 кОм. Принципиальную схему и назначение контактов можно посмотреть на рисунках ниже.
На плате расположено две группы контактов, шагом 2.54 мм, для удобного подключения к макетной плате, буду использовать штырьевые разъемы, их необходимо впаять.
Первая группа контактов:► DS: вывод DS18B20 (1-wire)► SCL: линия тактирования (Serial CLock)► SDA: линия данных (Serial Dфta)► VCC: «+» питание модуля► GND: «-» питание модуля
Вторая группа контактов:► SQ: вход 1 МГц► DS: вывод DS18B20 (1-wire)► SCL: линия тактирования (Serial CLock)► SDA: линия данных (Serial Dфta)► VCC: «+» питание модуля► GND:«-» питание модуля► BAT:
Подзарядка батареи
Как описывал ваше модуль может заряжать батарею, реализовано это, с помощью компонентов R4, R5, R6 и диода D1. Но, данная схема имеет недостаток, через резистор R4 и R6 происходит разряд батареи (как подметил пользователь ALEXEY, совсем не большой). Так как модуль потребляем незначительный ток, можно удалить цепь питания, для этого убираем R4, R5, R6 и VD1, вместо R6 поставим перемычку (после удаления компонентов, можно использовать обычную батарейку CR2032).
Немного физики
Для измерения частоты вращения нам понадобится датчик положения колеса/вала/круга/итп. Датчик ставится как правило один. Возможно, что он будет срабатывать не один раз на каждый оборот. Например, у вас датчик Холла и 4 магнита на колесе. Таким образом, для правильного вычисления частоты нужно знать:
- количество срабатываний датчика на один оборот К;
- минимальная ожидаемая частота Мин.
- максимальная ожидаемая частота Макс.
То есть, если частота меньше разумного минимума, то считаем, что она равна нулю, если больше максимума — игнорируем показания.
С количеством срабатываний понятно, но зачем ещё эти мины и максы? Давайте рассмотрим сначала варианты расчёта частоты.
Со скоростью всё проще, достаточно знать число π, диаметр колеса, а частоту вращения мы уже знаем.
Circuit #
- Both the I2C display and the real-time clock board communicate via I2C. To ease the connection, you can create the I2C bus on the breadboard by wiring the and I2C pins from the Arduino board to the contact lines on the breadboard. The display and RTC have different I2C addresses, they do not interfere with each other, so you can connect them to the same I2C bus.
- Connect the and pins from the Arduino board to the corresponding rails on the breadboard.
- Plug the I2C display. Wire its and with the I2C bus on the breadboard. Wire its and pins with the line on the breadboard. Wire pin with the line on the breadboard.
- Plug the I2C RTC breakout board. Wire its and with the I2C bus on the breadboard. Wire its and pins with the corresponding lines on the breadboard.
- Power the RTC board with the battery to keep running even when the external power source is disconnected.
Note
If you are using another model of the I2C display or RTC module, look at their pinout and datasheet to connect them correctly.
Модули часов реального времени в проектах Arduino
Модуль часов представляет собой небольшую плату, содержащей, как правило, одну из микросхем DS1307, DS1302, DS3231.Кроме этого, на плате практически можно найти механизм установки батарейки питания. Такие платы часто применяется для учета времени, даты, дня недели и других хронометрических параметров. Модули работают от автономного питания – батареек, аккумуляторов, и продолжают проводить отсчет, даже если на Ардуино отключилось питание. Наиболее распространенными моделями часов являются DS1302, DS1307, DS3231. Они основаны на подключаемом к Arduino модуле RTC (часы реального времени).
Часы ведут отсчет в единицах, которые удобны обычному человеку – минуты, часы, дни недели и другие, в отличие от обычных счетчиков и тактовых генераторов, которые считывают «тики». В Ардуино имеется специальная функция millis(), которая также может считывать различные временные интервалы. Но основным недостатком этой функции является сбрасывание в ноль при включении таймера. С ее помощью можно считать только время, установить дату или день недели невозможно. Для решения этой проблемы и используются модули часов реального времени.
Электронная схема включает в себя микросхему, источник питания, кварцевый резонатор и резисторы. Кварцевый резонатор работает на частоте 32768 Гц, которая является удобной для обычного двоичного счетчика. В схеме DS3231 имеется встроенный кварц и термостабилизация, которые позволяют получить значения высокой точности.
Работа программного обеспечения
Интерфейс DS5000
Программа, приведённая в Приложении, написана для взаимодействия DS5000 с DS1307 с помощью двухпроводного интерфейса. DS5000 запрограммирован с использованием макетной платы DS5000T фирмы Dallas Semiconductor, которая позволяет использовать ПК в качестве терминала ввода/вывода. Программные средства KIT5K поставляемые вместе с макетной платой DS5000T обеспечивают высокоуровневый интерфейс для загрузки программных приложений в DS5000 или установки его параметров через Program command. Программное обеспечение KIT5K содержит эмулятор терминала ввода/вывода, чтобы позволить пользователю запускать программные приложения в микроконтроллер DS5000, который связан с пользователем через COM порт ПК.
Исходный код DS1307
Первый раздел исходного кода, расположенный в Приложении, используется при конфигурации DS5000 для последовательного соединения с ПК. Также в начале кода находится подпрограмма MASTER_CONTROLLER, которая используется для управления демонстрационной программой.
Подпрограммы, которые следуют непосредственно за подпрограммой MASTER_CONTROLLER, являются драйверами низкого уровня и служат для управления двухпроводным интерфейсом. Они не являются индивидуальными для DS1307, а могут быть использованы с любым совместимым с двухпроводным интерфейсом «ведомым» устройством. Вот эти подпрограммы:
SEND_START
Подпрограмма используется для генерации состояния START на двухпроводной шине.
SEND_STOP
Подпрограмма используется для генерации состояния STOP на двухпроводной шине.
SEND_BYTE
Подпрограмма посылает 8-разрядное слово (первым является старший значащий бит (MSB)) по двухпроводной шине и девятый тактовый импульс для импульса подтверждения приёма.
READ_BYTE
Подпрограмма читает 8-разрядное слово с двухпроводной шины. Она проверяет очищен ли флаг LASTREAD после того, как считан последний байт из «ведомого» устройства. Если это был не последний байт, то DS5000 посылает импульс подтверждения по девятому тактовому импульсу, а если это был последний считанный байт из «ведомого» устройства, то DS5000 посылает «неподтверждение».
SCL_HIGH
Подпрограмма осуществляет переход линии SCL из низкого в высокое состояние и обеспечивает высокое состояние линии SCL перед продолжением.
DELAY и DELAY_4
Эти две подпрограммы включены для обеспечения сохранения временной диаграммы двухпроводной шины.
Остальная часть кода, включённая в приложение, специально предназначена для демонстрации функций DS1307. Продемонстрированы следующие функции:
Setting Time
Время считывается с клавиатуры и сохраняется в сверхоперативной памяти DS5000. Затем оно передаётся по двухпроводной шине в DS1307.
Set RAM
Одиночный байт в шестнадцатеричном виде считывается с клавиатуры и записывается в RAM DS1307.
Read Date/Time
Дата и время считываются по двухпроводной шине и сохраняются в сверхоперативной памяти DS5000. Затем они выводятся на экран. Это продолжается до тех пор, пока не будет нажата кнопка на клавиатуре.
OSC On/OSC Off
Тактовый генератор DS1307 может быть включен или выключен.
SQW/OUT On/SQW/OUT Off
Функция SQW/OUT может быть включена или выключена. Она будет переключаться на частоте 1 Гц.
Таблица 1. AC электрические характеристики
Параметр | Символ | Эффективноезначение | Единицы |
Тактовая частота SCL | fSCL | 59 | кГц |
Время свободного состояния шины между состояниями STOP и START | tBUF | 5.7 | мкс |
Время удержания(повторенного) состояния START | tHD:STA | 6.2 | мкс |
Период низкого состояния тактового импульса SCL | tLOW | 10.5 | мкс |
Период высокого состояния тактового импульса SCL | tHIGH | 6.5 | мкс |
Время установки для повторного состояния START | tSU:STA | 5.3 | мкс |
Время удержания данных | tHD:DAT | 5.5 | мкс |
Время установки данных | tSU:DAT | 3.1 | мкс |
Время установки для состояния STOP | tSU:STO | 5.4 | мкс |
Заключение
Было показано, как правильно подсоединять напрямую DS1307 или любое двухпроводное «ведомое» устройство к 8051-совместимому микроконтроллеру. Соединение должно быть таким, чтобы временная диаграмма двухпроводного интерфейса на микроконтроллере не нарушалась драйверами низкого уровня. Для этого в программный код должны быть включены подпрограммы задержки. Приведённых в таблице 1 эффективных значений, придерживались при конфигурации аппаратной части, описанной в данном техническом руководстве.
Документация
Rus Пример программы на языке Асемблер | ||
100 Kb Engl Исходный фаил | ||
Rus Описание интерфейса I2C | ||
Програмное обеспечение микроконтроллеров MCS-51 | ||
200 Kb Engl Описание DS1307 — часы реального времени с IIC интерфейсом |
Главная —
Микросхемы —
DOC —
ЖКИ —
Источники питания —
Электромеханика —
Интерфейсы —
Программы —
Применения —
Статьи
Мигаем светодиодом без delay()
или всегда ли официальный примеру учат «хорошему».
Обычно это одна из первых проблем с которой сталкивается навичок в микроконтроллерх. Помигал диодом, запустил стандартный скетч blink(), но как только он него возникает желание что-бы контроллер «занимался чем-то еще» его ждет неприятный сюрприз — тут нет многопоточности. Как только он написали где-то что-то типа delay(1000) — обнаруживается что на это строчке «контроллер остановился» и ничего больше не делает (кнопки не опрашивает, датчики не читает, вторым диодом «помигать» не может).
Новичок лезет с этим вопросом на форум и тут же получает ушат поучений: «отказывайтесь от delay()», учитесь работать с millis() и в прочитайте, в конце концов базовые примеры. В частности Мигаем светодиодом без delay()
Приведу его код:
/* Blink without Delay 2005 by David A. Mellis modified 8 Feb 2010 by Paul Stoffregen */ const int ledPin = 13; // номер выхода, подключенного к светодиоду // Variables will change: int ledState = LOW; // этой переменной устанавливаем состояние светодиода long previousMillis = 0; // храним время последнего переключения светодиода long interval = 1000; // интервал между включение/выключением светодиода (1 секунда) void setup() { // задаем режим выхода для порта, подключенного к светодиоду pinMode(ledPin, OUTPUT); } void loop() { // здесь будет код, который будет работать постоянно // и который не должен останавливаться на время между переключениями свето unsigned long currentMillis = millis(); //проверяем не прошел ли нужный интервал, если прошел то if(currentMillis - previousMillis > interval) { // сохраняем время последнего переключения previousMillis = currentMillis; // если светодиод не горит, то зажигаем, и наоборот if (ledState == LOW) ledState = HIGH; else ledState = LOW; // устанавливаем состояния выхода, чтобы включить или выключить светодиод digitalWrite(ledPin, ledState); } }
В принципе отправка к этому примеру — вполне правильна. В нем действительно виден стандартный паттерн как нужно выполнять какое-то переодическое действие (или отложенное):
1. Сохраняем время в какую-то переменную
2. В loop() все время смотрим на разницу «текущие-время — сохраненное»
3. Когда эта разница превысила какое-то значение (нужный нам «интервал переодичности»)
4. Выполняем какое-то действие (меняем состояние диода, заново запоминаем «стартовое время и т.п.»)
С задачей «объяснить идею» — пример справляется. Но, с моей точки зрения, в нем есть несколько методологических ошибок. Написание скетчек в подобно стиле — рано или поздно приведет к проблемам.
Итак, что же тут не так?
1. Не экономно выбираем тип переменных
Переменная ledPin у нас объявлена как тип int. Зачем? Разве номер пина может быть очень большим числом? Или может быть отрицательным числом? Зачем под его хранение выделять два байта, когда вполне хватит одного. Тип byte может хранить числа от 0 до 255. Для номера пина — этого вполне хватит.
const byte ledPIN = 13; // номер выхода, подключенного к светодиоду
Этого будет вполне достаточно.
2. А зачем нам переменная для малых чисел?
А зачем нам тут вообще переменая? (пусть и объявленная как const). Зачем тратить такты процессора на чтение переменной? И расходовать еще один байт? Воспользуемся директивой препроцессора #define
#define LED_PIN 13 // номер выхода, подключенного к светодиоду
Тогда еще на этапе компиляции компилятор просто подставить 13-ть везде где в коде используется LED_PIN и не будет выделять отдельных переменных.
3. Тип int опять выбрали как «первое что в голову пришло»?
И опять спотыкаемся на объявлении следующей же переменной. Почему ledState опять int? Кроме того что снова «два байта там где можно один использовать», так еще и «смысловая нагрузка» теряется. Что у нас хранится в переменной? Состояние светодиода. Включен/выключен. Горит/Не горит. Явно же напрашивается тип boolean. По крайней мере до тех пор, пока светодиод у нас может принимать два состояния.
Функция delay()
Функция delay() позволяет приостановить выполнение текущей программы на указанное в параметре время. Синтаксис команды выглядит следующим образом:
//команды delay(500); //задержка на 0,5 сек //команды delay(1000); //задержка на 1с
Время указывается в миллисекундах (1 сек = 1000 мс). Данный параметр может иметь тип «unsigned long», который находится в диапазоне от 0 до 4294967295. Ниже пример использования команды delay():
#define ledPin 13 void setup() { pinMode(ledPin,13); } void loop() { digitalWrite(ledPin,HIGH); //включить LED delay(500); //подождать 500ms (0,5 сек) digitalWrite(ledPin,LOW); //выключить LED delay(1000); //подождать 1000 мс (1 сек) }
В приведенном выше примере, светодиод загорается на 0,5 секунды, затем гаснет на 1 секунду и так далее, пока питание Arduino не будет отключено.
Управление семисегментными индикаторами
Схема подключения семисегментного индикатора с кнопкой
В следующем примере переключение чисел на индикаторе будет происходить только при нажатии тактовой кнопки. Дойдя до числа 3, таймер вновь обнулится и будет ожидать повторного нажатия на кнопку. Это довольно простые программы для Ардуино и семисегментного индикатора, для более сложных и интересных программ необходимо уже использовать сдвиговый регистр 74hc595 для Ардуино.
Скетч. Одноразрядный семисегментный индикатор и кнопка
#define A 8 #define B 7 #define C 6 #define D 5 #define E 4 #define F 3 #define G 2 #define BUTTON 12 byte v = 0; void setup() { pinMode(A, OUTPUT); pinMode(B, OUTPUT); pinMode(C, OUTPUT); pinMode(D, OUTPUT); pinMode(E, OUTPUT); pinMode(F, OUTPUT); pinMode(G, OUTPUT); pinMode(BUTTON, INPUT); } void loop() { digitalWrite(A, HIGH); //цифра нуль digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, HIGH); digitalWrite(G, LOW); if (digitalRead(BUTTON) == HIGH) { delay(500); v = 1; } while (v == 1) { digitalWrite(A, LOW); //цифра один digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, LOW); if (digitalRead(BUTTON) == HIGH) { delay(500); v = 2; } } while (v == 2) { digitalWrite(A, HIGH); //цифра два digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, LOW); digitalWrite(G, HIGH); if (digitalRead(BUTTON) == HIGH) { delay(500); v = 3; } } while (v == 3) { digitalWrite(A, HIGH); //цифра три digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, HIGH); if (digitalRead(BUTTON) == HIGH) { delay(500); v = 0; } } }
Пояснения к коду:
- переменная используется в программе для перехода одного цикла while к другому. При нажатии на кнопку значение переменной v меняется;
- в программе поставлена небольшая задержка в каждом условии для защиты от быстрого перехода от одного цикла while в другой.
Заключение. Мы ограничились лишь знакомством с данным модулем и его применением с платой Ардуино. Используя несколько панелек или четырехразрядный семисегментный индикатор можно уже сделать полноценный таймер на Ардуино или часы реального времени. Эти схемы мы разместили в разделе Проекты на Ардуино для начинающих, где любой может найти по своему вкусу проект на микроконтроллере.