ПМК 3 курс Практические задания 06 Практическая работа 6 - BysonHunter/Tavrich_college GitHub Wiki
🏠 Главная · Программирование микроконтроллеров · 3 курс · Практические работы по программированию микроконтроллеров — 3 курс
Практическая работа №6
Тема: «Разработка многофункциональных устройств на базе Arduino с индикацией»
Текст описания, целей и постановки заданий сохранён по исходному PDF. Технические замечания ниже исправляют или уточняют только обнаруженные неоднозначности и ошибки.
Технические корректировки и уточнения
- В исходных схемах заданий есть конфликты пинов: базовая распиновка 4-разрядного индикатора занимает D2–D13, а последующие задания повторно назначают эти же выводы кнопкам, HC-SR04, DHT22 и Servo. При сборке необходимо перераспределить выводы или использовать дополнительный драйвер/регистр.
- Для каждого сегмента нужен токоограничивающий резистор. Общие выводы разрядов желательно коммутировать транзисторными ключами, чтобы не превышать допустимый ток вывода Arduino.
- В секундомере при паузе необходимо отдельно хранить уже накопленное время; простое переопределение
startTime = millis()при каждом запуске приведёт к потере времени до паузы. - Код сегментов зависит от типа общего анода/катода и фактической распиновки A–G/DP; двоичный шаблон нельзя считать универсальным.
- Для DHT22, динамической индикации, Servo и датчиков следует использовать независимые неблокирующие таймеры, а не длительные
delay().
Описание работы и задания
1. Цель работы: Закрепление практических навыков программирования
микроконтроллеров Arduino и интеграции различных периферийных устройств, с фокусом на освоение методов вывода информации на семисегментный индикатор (статическая и динамическая индикация) и символьный LCD-дисплей, а также на организацию взаимодействия этих устройств с датчиками и исполнительными механизмами.
2. Задачи работы
-
Изучить устройство, распиновку и принципы работы семисегментных
индикаторов (одноразрядного и четырехразрядного).
-
Освоить метод динамической индикации для экономии выводов
микроконтроллера.
-
Научиться выводить текстовую и числовую информацию на LCD1602 через
I²C.
-
Исследовать принципы работы датчиков (потенциометр, DHT22, HC-SR04) и
исполнительных устройств (сервопривод).
-
Разработать пять цифровых устройств возрастающей сложности, в каждом из
которых обязательно задействованы 7-сегментный индикатор и LCD.
-
Научиться отлаживать программы, использующие неблокирующие задержки
(таймеры millis()) для одновременной работы нескольких компонентов.
Студент должен знать:
-
Основы цифрового ввода/вывода на Arduino.
-
Принципы работы шины I²C.
-
Понятие ШИМ (PWM) и его применение.
-
Принципы работы ультразвуковых дальномеров, цифровых датчиков температуры/влажности, потенциометров и сервоприводов.
-
Методы динамической индикации и работу с матрицами сегментов. Студент должен уметь:
-
Читать электрические схемы.
-
Подключать внешние устройства к Arduino.
-
Использовать среду разработки Arduino IDE.
-
Подключать и использовать библиотеки (LiquidCrystal_I²C.h, Servo.h, DHT.h, NewPing.h).
-
Разрабатывать алгоритмы и писать код на C++ для Arduino.
-
Использовать функцию millis() для создания неблокирующих таймеров. Практические навыки, приобретаемые студентом:
-
Сборка сложных макетных схем.
-
Программирование динамической индикации для 4-разрядного индикатора.
-
Вывод информации одновременно на два типа дисплеев (сегментный и символьный).
-
Программирование обмена данными по протоколам I²C.
-
Обработка аналоговых сигналов (потенциометр) и данных с цифровых датчиков.
-
Реализация многозадачности на микроконтроллере с помощью конечных автоматов и millis().
Основные теоретические сведения
- 7-сегментный индикатор:
-
Представляет собой набор из 7 (или 8 с точкой) светодиодов, соединенных катодами (общий катод) или анодами (общий анод).
-
Для зажигания цифры необходимо подать HIGH (для ОК) или LOW (для ОА) на соответствующие сегменты A-G.
-
Для многоразрядных индикаторов используется динамическая индикация: разряды зажигаются по очереди с высокой частотой (>50 Гц на каждый разряд). Человеческий глаз не замечает мерцания, создается иллюзия одновременного свечения.
-
LCD1602 (I²C): Символьный дисплей 16x2, управляемый по двум проводам (SDA, SCL). Адрес на шине I²C чаще всего 0x27 или 0x3F. Библиотека LiquidCrystal_I²C.h.
-
Потенциометр: Аналоговый датчик. Используется как делитель напряжения. Значение на среднем выводе считывается функцией analogRead() (0-1023).
-
Сервопривод: Управляется ШИМ-сигналом с периодом 20 мс и длительностью импульса от 0.5-1 мс (0°) до 2-2.5 мс (180°). Библиотека Servo.h.
-
Ультразвуковой датчик HC-SR04: Измеряет расстояние методом эхолокации. Время между отправкой и приемом сигнала преобразуется в расстояние: Расстояние (см) = (длительность импульса (мкс) * скорость звука) / 2. В воздухе скорость звука ~340 м/с или 0.034 см/мкс. Часто используют формулу см = мкс / 58.2.
-
Датчик DHT22: Цифровой датчик температуры и влажности. Имеет свой протокол связи. Требует библиотеки DHT.h.
Задания Для Практической Работы
Задание 1.
Разработать цифровое устройство: Счетчик от 0 до 9999 с шагом 1, управляемый одной кнопкой. Текущее значение счетчика отображается на 4-разрядном семисегментном индикаторе. На LCD-дисплей выводится сообщение: "Counter: XXXX".
Схема подключения:
- 4x7-сегментный индикатор (общий катод): Сегменты A-G через резисторы (220 Ом) к пинам 6-12. Разряды (D1, D2, D3, D4) к пинам 2,3,4,5.
− Lcd1602 (I²C): Vcc -> 5V, Gnd -> Gnd, Sda -> A4, Scl -> A5.
- Кнопка: Один контакт к пину 13, другой к GND (используем
Input_Pullup).
Описание алгоритма:
-
В setup() настроить пины, инициализировать LCD, создать буфер для хранения кодов цифр для каждого разряда.
-
В loop():
-
Постоянно вызывать функцию dispTick() (динамическая индикация).
-
Проверять, нажата ли кнопка (с антидребезгом). Если нажата, увеличить переменную counter на 1. Если counter > 9999, сбросить в 0.
-
Разбить число counter на отдельные цифры (тысячи, сотни, десятки, единицы).
-
Поместить в буфер индикатора коды цифр для отображения.
-
Каждые 300 мс (или при изменении значения) обновлять информацию на LCD, выводя "Counter: N".
Код для Arduino:
- Библиотека LiquidCrystal_I²C.h.
- Реализация динамической индикации (как в лекции 9).
- Функция для разбиения числа на цифры.
Задание 2. Аналоговый вольтметр
Разработать цифровое устройство измерения напряжения на потенциометре (0-5 В)
с отображением:
-
На 7-сегментном индикаторе - текущее значение напряжения с точностью до десятых долей (например, 2.5 В).
-
На LCD - сырое значение АЦП (0-1023) и уровень сигнала в процентах. Схема подключения:
-
4x7-сегментный индикатор (подключение как в Задании 1).
-
LCD1602 (I²C) (подключение как в Задании 1).
-
Потенциометр: средний вывод -> A0. Описание алгоритма:
-
Реализовать динамическую индикацию для 4 разрядов. Для отображения числа 2.5 нужно вывести 2.5 (зажечь десятичную точку на втором разряде). Это требует модификации функции вывода: добавить отдельный массив для точек или специальный код для цифры с точкой.
-
В loop():
-
Считать значение с A0 (adcValue).
-
Преобразовать его в напряжение: voltage = (adcValue / 1023.0) * 5.0.
-
Подготовить данные для 7-сегментного индикатора: извлечь целую часть и первый знак после запятой. Установить флаг десятичной точки для нужного разряда.
-
Вывести на LCD: "ADC: 1023" на первой строке и "Level: 100%" на второй.
-
Вызвать функцию dispTick().
-
Небольшая задержка (50-100 мс) для стабильности. Код для Arduino:
-
Модифицированная функция dispTick(), умеющая зажигать DP (десятичную точку).
-
Логика преобразования float в цифры для индикатора.
Задание 3. Секундомер
Разработать цифровое устройство: Секундомер с точностью до десятых долей секунды, отображающий время на 7-сегментном индикаторе в формате СС.Д (секунды и десятые). Управление: кнопка "Старт/Стоп", кнопка "Сброс". На LCD выводится общее время в секундах и состояние секундомера ("RUN", "STOP").
Схема подключения:
- 4x7-сегментный индикатор (подключение как в Задании 1).
- LCD1602 (I²C) (подключение как в Задании 1).
- Кнопка 1 (Старт/Стоп) -> Пин 13.
- Кнопка 2 (Сброс) -> Пин 12. Описание алгоритма:
-
Использовать таймер на millis() для неблокирующего отсчета времени.
-
Переменная state (true/false) для хранения состояния "RUN/STOP".
-
При нажатии "Старт/Стоп" инвертировать state. При переходе из STOP в RUN запомнить текущее millis() в переменной startTime.
-
Если state == RUN, то текущее время currentTime = millis() - startTime. Иначе время не меняется.
-
При нажатии "Сброс" обнулить startTime и currentTime, перевести state в
Stop.
- Преобразовать currentTime (мс) в секунды и десятые доли. Например, 1234 мс
-
1.2 с (отобразить как 01.2).
- Вывести на 7-сегментный индикатор, зажигая точку на втором разряде.
- Вывести на LCD состояние и общее время.
- Постоянно вызывать dispTick(). Код для Arduino:
- Неблокирующий код на millis().
- Обработка дребезга кнопок.
- Преобразование миллисекунд в формат для индикатора.
Задание 4. Парктроник
Разработать цифровое устройство измерения расстояния с помощью HC-SR04.
-
На 7-сегментном индикаторе отображается расстояние в сантиметрах (например, 186).
-
На LCD выводится: "Dist: XXX cm" и индикаторная шкала (например, [#####---]) для визуализации близости препятствия (0-200 см).
Схема подключения:
- 4x7-сегментный индикатор (подключение как в Задании 1).
- LCD1602 (I²C) (подключение как в Задании 1).
- HC-SR04: Trig -> Пин 3, Echo -> Пин 2, VCC -> 5V, GND -> GND. Описание алгоритма:
-
Функция getDistance() отправляет импульс на Trig и с помощью pulseIn() получает время на Echo. Возвращает расстояние в см (duration / 58.2).
-
В loop():
-
Вызывать dispTick() постоянно.
-
Каждые 200 мс (неблокирующая проверка) вызывать getDistance(). Полученное значение ограничить, например, до 200 см.
-
Поместить расстояние в буфер 7-сегментного индикатора (только целая часть).
-
На LCD: на первой строке вывести "Dist: XXX cm".
-
На второй строке нарисовать шкалу. Например, количество закрашенных сегментов = map(distance, 0, 200, 10, 0). Использовать 10 символов, например, # для заполнения и - для пустого места.
Код для Arduino:
- Библиотека NewPing.h или собственная реализация.
- Неблокирующий таймер для опроса датчика.
- Генерация псевдографической шкалы для LCD.
Задание 5. Климат-контроль с регистратором пиковых значений
Разработать цифровое устройство мониторинга температуры и влажности (датчик DHT22) с возможностью управления сервоприводом (например, для открытия/закрытия форточки) и регистрации минимальной и максимальной температуры за время работы.
На 7-сегментном индикаторе циклически (по нажатию кнопки) отображается:
текущая температура (t. 23), текущая влажность (h. 55), минимальная температура (L. 21), максимальная температура (H. 25). Формат: одна буква-идентификатор и три цифры. На LCD отображается подробная информация: "Temp:23C Hum:55%" на первой строке и "Min:21C Max:25C" на второй. Серводвигатель управляется вторым потенциометром: крайнее левое положение потенциометра соответствует 0° (форточка закрыта), крайнее правое — 90° (форточка открыта). Положение серво также отображается на LCD.
Схема подключения:
- 4x7-сегментный индикатор, LCD1602 (I²C), DHT22 (Pin 7), сервопривод (Pin 9), потенциометр для серво (A1), кнопка переключения режима индикатора (Pin 8). Описание алгоритма
- Многозадачность: Все работает на millis():
-
dispTick() (каждые 5 мс).
-
Опрос DHT22 (каждые 2000 мс).
-
Опрос потенциометра серво и управление серво (каждые 50 мс).
-
Антидребезг кнопки и переключение режима отображения на 7-сегм. индикаторе (mode 0-3).
-
Обновление LCD (при изменении данных или режима).
- Логика:
-
При каждом успешном чтении с DHT22 сравнивать значение с переменными minTemp, maxTemp и обновлять их.
-
Считывать значение с потенциометра (A1), маппить на угол 0-90, подавать на серво.
-
По нажатию кнопки циклически переключать mode.
-
В dispTick() в зависимости от mode в буфер индикатора помещаются данные: для mode0 — буква t и текущая температура, mode1 — h и влажность, mode2 — L и мин. температура, mode3 — H и макс. температура.
Код для Arduino:
-
Библиотеки: LiquidCrystal_I²C.h, DHT.h, Servo.h.
-
Полностью событийно-ориентированный код на таймерах.
-
Работа с массивами символов для подготовки вывода на 7-сегментный индикатор (включая буквы).
-
Обновление LCD только при изменении данных для уменьшения мерцания.
Содержание Отчета
Отчёт о выполнении лабораторной работы должен содержать:
– титульный лист с номером и названием работы;
– цель работы;
– краткие теоретические сведения о подключаемых устройствах и особенностях их
работы; – схемы соединения элементов, выполненные в программе Fritzing или Tinkercad; – описание алгоритма работы собранного устройства; – текст программ, содержащий необходимые комментарии и пояснения; – описание особенностей подключения библиотек и функции, которые были использованы из импортированных библиотек; – общие выводы по работе.
Контрольные Вопросы Для Защиты Работы:
-
В чем разница между индикатором с общим анодом и общим катодом? Как это влияет на код программы?
-
Объясните суть динамической индикации. Почему без нее невозможно использовать многоразрядный индикатор, подключенный напрямую к микроконтроллеру?
-
Какие резисторы и для чего используются в цепи семисегментного индикатора? Что произойдет, если их не поставить?
-
Как с помощью одного 4-разрядного индикатора отобразить число с плавающей точкой (например, 3.14)?
-
Каковы преимущества и недостатки использования библиотеки LiquidCrystal_I²C перед прямым подключением LCD1602?
-
Как организовать на Arduino выполнение нескольких задач одновременно (например, опрос кнопки, динамическая индикация и измерение расстояния)? Приведите пример с функцией millis().
-
Почему при работе с ультразвуковым датчиком HC-SR04 не рекомендуется использовать длительную задержку delay() в основном цикле?
-
Каким образом функция pulseIn() измеряет длительность импульса и в чем ее ограничение?
-
Для чего нужна функция map() и как она применяется при работе с потенциометром и сервоприводом?
-
Опишите алгоритм преобразования двоичного кода цифры (например, 0b01111101 для цифры 6) в сигналы на пинах для зажигания соответствующих сегментов.