Москва, ул. Пушкинская, д.12
Акции
Бренды
О компании
Помощь
  • Методы оплаты
  • Методы доставки
  • Гарантия
  • Вопрос-ответ
Блог
Информация
  • Политика конфиденциальности
  • Политика использования файлов cookie
  • Договор публичной оферты
Отзывы
Контакты
    +7 100 000-00-11
    +7 100 000-00-11 Консультация
    +7 100 000-00-22 Отдел продаж
    +7 100 000-00-33 Бухгалтерия
    E-mail
    info@site.com
    Адрес
    Москва, ул. Пушкинская, д.12
    Режим работы
    Пн - Вс: 10.00 - 19.00
    3d-xpert
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    • 3D принтеры
      3D принтеры
      • Печать пластиком (FDM/FFF)
      • Печать фотополимером (SLA/DLP/LCD)
      • Печать воском (MJP)
      • Для дома
      • Для бизнеса
      • Для производства
      • Промышленные
    • 3D-сканеры
      3D-сканеры
    • Материалы для 3D печати
      Материалы для 3D печати
      • Пластики
      • Фотополимеры
    • Комплектующие 3D принтера
      Комплектующие 3D принтера
      • Электроника
      • Механика
      • Нагревательные столы и сопутствующие
      • Экструдеры
      • Сушилки для пластика
      • УФ-камеры
      • Мойки
      • Ультразвуковые ванны (мойки)
      • 3D ручки
      • Расходные материалы для SLA / LCD
      • Сопутствующие
      • Наборы для мейкеров
      • Инструменты для 3D печатника
      • Постобработка
      • Адгезивы
      • Автоматические системы подачи пластиков (АМС)
    • Arduino и робототехника
      Arduino и робототехника
      • Arduino
      • Raspberry Pi
      • Обучающие наборы
      • Orange Pi
      • Одноплатники
      • Модули
      • Датчики
      • Дисплеи
      • Механика
      • Макетные платы
      • Светодиоды
      • Провода и кабели
      • Источники питания
      • Радиодетали
    • Комплектующие ЧПУ станка
      Комплектующие ЧПУ станка
      • Шаговые двигатели и аксессуары
      • Зубчатые ременные передачи
      • Шарико-винтовые передачи (ШВП)
      • Трапецеидальные передачи винт-гайка
      • Цилиндрические направляющие
      • Профильные направляющие
      • Муфты соединительные
      • Электроника
      • Фрезы
      • Карбоновый профиль / трубки
      • Пневматическое оборудование
      • Системы подачи смазки
      • Сопутствующие
      • Шпиндели и сопутствующие
      • Механика
      • Конструкционный профиль
      • Комплектующие OpenBuilds
      • Лазерные станки
      • Лазерная резка и аксессуары
    • Инструменты
      Инструменты
      • Зачистка и обрезка кабеля
      • Измерительный инструмент
      • Кабель и провода
      • Клеевые пистолеты (термопистолеты)
      • Напильники и надфили
      • Обжимной инструмент
      • Отвертки
      • Паяльное оборудование
      • Пинцеты
      • Расходные материалы
    • Запчасти для 3D принтеров по брендам
      Запчасти для 3D принтеров по брендам
      • Bambu Lab
      • Creality
      • Flashforge
      • Anycubic
      • ELEGOO
      • Flying Bear
      • Qidi
      • Sovol
      • 3DIY printers
    3D принтеры 3D-сканеры Материалы для 3D печати Комплектующие 3D принтера Arduino и робототехника Комплектующие ЧПУ станка Инструменты Запчасти для 3D принтеров по брендам
    3d-xpert
    • 3D принтеры
      3D принтеры
      • Печать пластиком (FDM/FFF)
      • Печать фотополимером (SLA/DLP/LCD)
      • Печать воском (MJP)
      • Для дома
      • Для бизнеса
      • Для производства
      • Промышленные
    • 3D-сканеры
      3D-сканеры
    • Материалы для 3D печати
      Материалы для 3D печати
      • Пластики
      • Фотополимеры
    • Комплектующие 3D принтера
      Комплектующие 3D принтера
      • Электроника
      • Механика
      • Нагревательные столы и сопутствующие
      • Экструдеры
      • Сушилки для пластика
      • УФ-камеры
      • Мойки
      • Ультразвуковые ванны (мойки)
      • 3D ручки
      • Расходные материалы для SLA / LCD
      • Сопутствующие
      • Наборы для мейкеров
      • Инструменты для 3D печатника
      • Постобработка
      • Адгезивы
      • Автоматические системы подачи пластиков (АМС)
    • Arduino и робототехника
      Arduino и робототехника
      • Arduino
      • Raspberry Pi
      • Обучающие наборы
      • Orange Pi
      • Одноплатники
      • Модули
      • Датчики
      • Дисплеи
      • Механика
      • Макетные платы
      • Светодиоды
      • Провода и кабели
      • Источники питания
      • Радиодетали
    • Комплектующие ЧПУ станка
      Комплектующие ЧПУ станка
      • Шаговые двигатели и аксессуары
      • Зубчатые ременные передачи
      • Шарико-винтовые передачи (ШВП)
      • Трапецеидальные передачи винт-гайка
      • Цилиндрические направляющие
      • Профильные направляющие
      • Муфты соединительные
      • Электроника
      • Фрезы
      • Карбоновый профиль / трубки
      • Пневматическое оборудование
      • Системы подачи смазки
      • Сопутствующие
      • Шпиндели и сопутствующие
      • Механика
      • Конструкционный профиль
      • Комплектующие OpenBuilds
      • Лазерные станки
      • Лазерная резка и аксессуары
    • Инструменты
      Инструменты
      • Зачистка и обрезка кабеля
      • Измерительный инструмент
      • Кабель и провода
      • Клеевые пистолеты (термопистолеты)
      • Напильники и надфили
      • Обжимной инструмент
      • Отвертки
      • Паяльное оборудование
      • Пинцеты
      • Расходные материалы
    • Запчасти для 3D принтеров по брендам
      Запчасти для 3D принтеров по брендам
      • Bambu Lab
      • Creality
      • Flashforge
      • Anycubic
      • ELEGOO
      • Flying Bear
      • Qidi
      • Sovol
      • 3DIY printers
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    3d-xpert
    Телефоны
    +71000000011 Консультация
    +71000000022 Отдел продаж
    +71000000033
    E-mail
    info@site.com
    Адрес
    Москва, ул. Пушкинская, д.12, Москва, ул. Пушкинская, д.12
    Режим работы
    Пн - Вс: 10.00 - 19.00
    0
    0
    0
      • Каталог
      • 3D принтеры
        • 3D принтеры
        • Печать пластиком (FDM/FFF)
        • Печать фотополимером (SLA/DLP/LCD)
        • Печать воском (MJP)
        • Для дома
        • Для бизнеса
        • Для производства
        • Промышленные
      • 3D-сканеры
      • Материалы для 3D печати
        • Материалы для 3D печати
        • Пластики
        • Фотополимеры
      • Комплектующие 3D принтера
        • Комплектующие 3D принтера
        • Электроника
        • Механика
        • Нагревательные столы и сопутствующие
        • Экструдеры
        • Сушилки для пластика
        • УФ-камеры
        • Мойки
        • Ультразвуковые ванны (мойки)
        • 3D ручки
        • Расходные материалы для SLA / LCD
        • Сопутствующие
        • Наборы для мейкеров
        • Инструменты для 3D печатника
        • Постобработка
        • Адгезивы
        • Автоматические системы подачи пластиков (АМС)
      • Arduino и робототехника
        • Arduino и робототехника
        • Arduino
        • Raspberry Pi
        • Обучающие наборы
        • Orange Pi
        • Одноплатники
        • Модули
        • Датчики
        • Дисплеи
        • Механика
        • Макетные платы
        • Светодиоды
        • Провода и кабели
        • Источники питания
        • Радиодетали
      • Комплектующие ЧПУ станка
        • Комплектующие ЧПУ станка
        • Шаговые двигатели и аксессуары
        • Зубчатые ременные передачи
        • Шарико-винтовые передачи (ШВП)
        • Трапецеидальные передачи винт-гайка
        • Цилиндрические направляющие
        • Профильные направляющие
        • Муфты соединительные
        • Электроника
        • Фрезы
        • Карбоновый профиль / трубки
        • Пневматическое оборудование
        • Системы подачи смазки
        • Сопутствующие
        • Шпиндели и сопутствующие
        • Механика
        • Конструкционный профиль
        • Комплектующие OpenBuilds
        • Лазерные станки
        • Лазерная резка и аксессуары
      • Инструменты
        • Инструменты
        • Зачистка и обрезка кабеля
        • Измерительный инструмент
        • Кабель и провода
        • Клеевые пистолеты (термопистолеты)
        • Напильники и надфили
        • Обжимной инструмент
        • Отвертки
        • Паяльное оборудование
        • Пинцеты
        • Расходные материалы
      • Запчасти для 3D принтеров по брендам
        • Запчасти для 3D принтеров по брендам
        • Bambu Lab
        • Creality
        • Flashforge
        • Anycubic
        • ELEGOO
        • Flying Bear
        • Qidi
        • Sovol
        • 3DIY printers
    • Кабинет
    • Сравнение
    • Избранное
    • Корзина
    • Акции
    • Бренды
    • О компании
    • Помощь
      • Помощь
      • Методы оплаты
      • Методы доставки
      • Гарантия
      • Вопрос-ответ
    • Блог
    • Информация
      • Информация
      • Политика конфиденциальности
      • Политика использования файлов cookie
      • Договор публичной оферты
    • Отзывы
    • Контакты
    +71000000011 Бухгалтерия
    • Телефоны
    • +71000000011 Консультация
    • +71000000022 Отдел продаж
    • +71000000033 Бухгалтерия
    • info@site.com
    • Москва, ул. Пушкинская, д.12, Москва, ул. Пушкинская, д.12
    • Пн - Вс: 10.00 - 19.00
    Главная
    Блог
    Проекты
    Электронная мишень

    Электронная мишень

    Электронная мишень
    Проекты 10 апреля 2025

    Содержание

    • Введение
    • Техническое задание
    • Подбор комплектующих
    • Электрическая схема
    • Сборка
    • Программирование

    Введение

    Платформа Arduino прочно закрепилась среди любителей автоматизированных систем и на её основе уже созданы тысячи всевозможных проектов. Данная статья раскроет ещё одно направление, в котором можно применить эту популярную платформу. Здесь будет описан процесс создания электронной мишени, которая должна вести подсчёт количества попаданий и выводить результат на устройство индикации. Но просто считать очки – это скучно, поэтому в проект целесообразно добавить несколько уровней сложности. Данное устройство поможет оценить меткость и скорость реакции стрелка, например, при сдаче зачёта или просто стать хорошим дополнением для любителей пострелять по мишеням ради развлечения.


    Техническое задание

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

    Общие требования и алгоритм работы

    Итак, электронная мишень должна представлять собой некое устройство, которое считывает попадания пластиковым или металлическим шариком, при этом фиксирует его в виде световой и звуковой индикации, и параллельно выводит данные на дисплей. Так как в проекте предусмотрено несколько режимов работы, то для удобства их выбора необходимо реализовать что-то похожее на меню. Ввиду того, что мишень может быть удалена от стрелка, управление меню должно вестись дистанционно, например, при помощи любого пульта ДУ. Чувствительный элемент, фиксирующий попадания, должен быть выполнен в виде ударопрочной пластины с закреплённым на ней датчиком вибрации. «Мозгом» электронной мишени будет само собой плата Arduino.

    Алгоритм работы

    В ходе некоторых размышлений был определён общий концепт и алгоритм работы электронной мишени для каждого из режимов работы, а именно:

    При подаче питания мигают красный и зелёный светодиоды, бузер дважды издаёт звуковой сигнал. На дисплее появляется главное меню по типу нижеследующего:

    Главное меню

    menu1.jpg

    На данном этапе пользователь выбирает для себя один из трёх возможных режимов работы с электронной мишенью. Переключение пунктов меню и выбор одного из них производятся соответствующими клавишами «ВВЕРХ», «ВНИЗ» и «ОК» пульта ДУ.

    Режим «EASY»

    В этом режиме на экран выводится следующая информация:

    menu2.jpg

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

    menu3.jpg

    С этого момента Arduino начинает циклически опрашивать датчик вибрации. Если происходит попадание, бузер в течение 4-х секунд должен пищать на максимально высокой ноте. При этом красный светодиод гаснет и загорается зелёный. В нижней части дисплея вместо нуля появляется цифра «1». Через 4 секунды бузер замолкает и снова загорается красный светодиод, ожидая следующего выстрела. Цикл повторяется.

    Режим «MEDIUM»

    Этот режим, в отличие от предыдущего, немного интереснее, так как в него будет введён дополнительный параметр «RANDOM TIME». Значение устанавливается в секундах и означает время, в течение которого мишень будет активна для попадания. Пример соответствующего экрана показан ниже.

     

    menu4.jpg

    Допустим, это время будет настраиваться в пределах от 3 до 99 секунд. После выбора необходимого значения клавишами «ВВЕРХ» и «ВНИЗ» пульта ДУ и последующего нажатия «ОК», бузер включается на одну секунду. При этом оба светодиода находятся в погасшем состоянии. Стрелок видит следующий экран:

    menu5.jpg

    С этого момента генерируется случайное число из диапазона от 3 секунд до RANDOM TIME, которое установил пользователь. Это и есть тот период, в течение которого необходимо попасть в мишень. Каждый раз он случайный, но всегда лежит в заданном диапазоне.

    Итак, далее загорается красный светодиод, что говорит об ожидании выстрела. Если в течение конкретного интервала стрелок успевает поразить мишень, то он получает 1 балл, в противном случае балл отнимается с соответствующим световым и звуковым сопровождением. Цикл повторяется.

    Режим «HARD»

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

    menu6.jpg

        

    Параметр SHOOT TIME отвечает за общее время активности мишени и лежит в диапазоне от 1 до 999 секунд. SHOOT INTERVAL включает в себя 5 параметров, каждый из которых означает промежуток времени, в течение которого мишень будет доступна для поражения. Это время может быть равно от 1 до 99 секунд. Настройка каждого из значений производиться аналогично предыдущим режимам, нажатие кнопки «ОК» на пульте ДУ сохраняет текущий параметр и переводит курсор к следующему. После сохранения последнего параметра, высвечивается главный действующий экран hard-режима, показанный ниже.

    menau7.jpg

    В левой части экрана отображается количество совершённых попыток, а в правой количество удачных попаданий. Игра длиться до тех пор, пока не закончится время (SHOOT TIME). Попадание засчитывается, если оно произошло в отведённое время для текущего таймслота SHOOT INTERVAL. Таймслоты, установленные пользователем чередуются по кругу. Если попадание не произошло, баллы в правой части экрана уменьшаются. Таким образом можно получить некоторую статистику.

    Также во всех случаях навигации по меню, целесообразно будет предусмотреть кнопку «ВЫХОД», чтобы иметь возможность возврата на верхний уровень.


    Подбор комплектующих

    После теоретического определения требований к проекту, можно приступать к подбору комплектующих. Начнём с главного элемента – платы Arduino. Исходя из вышеизложенного, с указанной задачей способна справиться любая плата из этой линейки. Пусть это будет Arduino Nano. Она имеет небольшой размер и легко программируется без посторонних средств.

    В качестве дисплея будет применён хорошо зарекомендовавший себя графический ЖКИ 84х48 от Nokia5110 на базе контроллера Philips PCD8544.

    Светодиоды, фиксирующие готовность мишени или попадания, подойдут любые. Для удобства лучше взять разные цвета: красный и зелёный. Я в своём проекте использую готовый модуль KY-011.

    Излучатель звука будет применён пьезоэлектрический, чтобы не нагружать выход микроконтроллера. Важным условием является отсутствие в нём встроенного генератора, что позволит управлять частотой звука.

    Для возможности приёма сигнала пульта дистанционного управления с последующей его дешифрацией, в проекте используется модуль ИК-приёмника KY-022 на базе популярной микросхемы TSOP1738.

    Одним из основных элементов схемы является датчик удара/вибрации. Мною были протестированы несколько претендентов, но лучший результат по стабильности показал SW-520D, который не дал ни одного сбоя в течение всего периода тестирования.

    Для наглядности, ниже приведена таблица с внешним видом всех комплектующих.

    spisok-komplektuushih.jpg

    Электрическая схема

    Итак, техническое задание составлено, комплектующие подобраны, осталось все это правильно соединить между собой. Здесь не потребуется прилагать много усилий, так как мы используем довольно распространённые элементы и модули. Единственное, на что следует обратить особое внимание – подключение датчика вибрации. Так как пуля при ударе о мишень даёт очень короткий импульс, то и фиксировать его нужно быстро. Следовательно, датчик удара целесообразно подцепить на вход обработки внешнего прерывания Arduino. Такими входами могут быть пины 2 или 3. Пусть в этом проекте будет использован пин под номером 2. Ниже приведена электрическая схема электронной мишени.

     

    shema.jpg

    Обратите внимание, что пин D2 платы Arduino Nano подтянут к плюсу питания через резистор 10 кОм. Это необходимо для того, чтобы исключить наводки и как следствие ложные срабатывания датчика. Выводы D6 и D7 управляют работой светодиодов через защитные резисторы, номиналом 330 Ом. ЖКИ дисплей Nokia5110 лучше питать от 3.3В, во избежание выхода его из строя.

    На нижеприведенном фото можно наглядно увидеть, как выглядит схема после сборки на макетной плате. На данном этапе датчик удара просто висит в воздухе и впоследствии будет закреплён на ударной части самой мишени.

    sborka-shema.jpg

     


    Сборка чувствительного элемента мишени

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

    mishen.jpg

    Прикрепить датчик удара к пластине можно при помощи пластиковых хомутов. Никакого двухстороннего скотча или термоклея. Крепление должно выдерживать большие встряски.

    И ещё один момент. Те, кто работал с датчиками SW-520D, наверняка знают, что сигнал на его выходе может быть разным и зависит от текущего угла наклона. Это обусловлено особенностью конструктивного исполнения. Наглядно это можно понять из нижеприведенной иллюстрации.

    sw-520-signal.jpg

    В концепции данного проекта не имеет значения, под каким углом будет закреплён датчик на пластите. Программа будет запоминать последнее значение, и принимать его за состояние покоя. Любое изменение этого состояния будет идентифицировано как выстрел. Ниже на фото показан мой вариант исполнения датчика (вид сзади и спереди).

    sborka-mishen.jpg

    Программирование

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

    Итак, для начала нам понадобится библиотека для работы с приёмником TSOP1738, которая называется « IRremote.h». После её добавления в среду Arduino IDE пишем следующий код:

    #include <IRremote.h> int RECV_PIN = 8; // Пин, к которому подключен выход ИК-приёмника IRrecv irrecv(RECV_PIN); decode_results results; void setup() { Serial.begin(9600); Serial.println("Enabling IRin"); irrecv.enableIRIn(); // Активируем ИК-приёмник Serial.println("Enabled IRin"); } void loop() { if (irrecv.decode(&results)) { // Если пришли данные с пульта ДУ Serial.println(results.value, HEX); // Выводим код нажатой клавиши irrecv.resume(); // Принимаем следующее значение } delay(100); }

    После этого, загружаем программу в Arduino Nano, открываем монитор серийного порта и поочерёдно нажимаем клавиши «ВВЕРХ», «ВНИЗ», «ВПРАВО», «ВЛЕВО», «ОК», «EXIT». При этом в терминале должен выводиться шестнадцатеричный код текущей клавиши. В моём случае я получил следующую серию кодов:

    kodu.jpg

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

    Клавиша пульта ДУ

    Код

    Вверх

    0x2FD9867

    Вниз

    0x2FDB847

    Вправо

    0x2FDE21D

    Влево

    0x2FD629D

    Ok

    0x2FD50AF

    Exit

    0x2FD22DD


    Теперь, до написания основного кода остался всего один шаг, а именно скачивание библиотек для работы с LCD Nokia5110. Библиотек понадобится всего две: « Adafruit_PCD8544.h» и « Adafruit_GFX.h». Добавляем их в среду Arduino IDE и следом копируем код основной программы, который я постарался максимально закомментировать.

    #include <IRremote.h> #define RECV_PIN 8 // Пин для подключения ИК-приёмника IRrecv irrecv(RECV_PIN); decode_results results; // ---------------------------------------- // Коды кнопок с пульта управления // Данные коды необходимо заменить на свои #define UP 0x2FD9867 #define DOWN 0x2FDB847 #define RIGHT 0x2FDE21D #define LEFT 0x2FD629D #define OK 0x2FD50AF // ---------------------------------------- // Библиотеки для работы с дисплеем NOKIA_5110 #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_PCD8544.h> // Подключение дисплея к аппаратному SPI Arduino // SCLK - пин №13 // DIN - пин №11 // D/C - пин №5 // CS - пин №4 // RST - пин №3 Adafruit_PCD8544 display = Adafruit_PCD8544(13, 11, 5, 4, 3); #define pinGreenLed 6 // Пин для подключения зелёного светодиода #define pinRedLed 7 // Пин для подключения красного светодиода #define pinBuzzer 9 // Пин для подключения буззера bool flagDraw = true; // Флаг, разрешающий отрисовку изображения на дисплее volatile int menuCursor = 0; // Номер отображаемого в данный момент экрана volatile uint8_t globalState = 0; // Переменная глобального состояния системы uint32_t ledBlinkTimer = 0; // Таймер для отсчёта периода мигания светодиодов // Макроопределения режимов стрельбы #define EASY 1 #define MEDIUM 2 #define HARD 3 volatile uint8_t shootMode = 0; // Текущий режим стрельбы volatile bool shootFlag = false; // Флаг, разрешающий обработку датчика вибрации в прерывании volatile uint16_t shootScore = 0; // Кол-во баллов/попаданий uint8_t randomTime = 3; // Случайное время, в течение которого можно поразить мишень в режиме MEDIUM uint32_t shootTime = 1; // Общее время работы мишени в режиме HARD int shootInterval[5] = {0, 0, 0, 0, 0}; // Секунды, в течение которых мишень доступна для поражения int hardModeCursor = 0; // Курсор для настройки разных параметров в режиме HARD int TRY = 0; // Кол-во попыток, данных в режиме HARD volatile int shootIntervalCursor = 0; // Курсор переключения между интервалами активности мишени // Переменные для режима MEDIUM uint32_t mm_randomTime; // Случайное время в пределах от 3 сек. до RandomTime, установленном в меню uint32_t mm_randomTimer; // Таймер для отсчёта случайного времени // Переменные для режима HARD uint32_t hm_Time; uint32_t hm_Timer; uint32_t shootTimer; /* Функция подачи звукового сигнала низкого тона */ void beep() { for(int i = 0; i < 500; i++) { digitalWrite(pinBuzzer, HIGH); delay(1); digitalWrite(pinBuzzer, LOW); delay(1); } } /* Функция подачи звукового сигнала высокого тона */ void beep_1() { for(int i = 0; i < 500; i++) { digitalWrite(pinBuzzer, HIGH); delayMicroseconds(500); digitalWrite(pinBuzzer, LOW); delayMicroseconds(500); } } /* Функция предустановок */ void setup() { attachInterrupt(0, shoot, CHANGE); // Внешнее прерывание на выводе D2 pinMode(pinGreenLed, OUTPUT); digitalWrite(pinGreenLed, LOW); pinMode(pinRedLed, OUTPUT); digitalWrite(pinRedLed, LOW); pinMode(pinBuzzer, OUTPUT); Serial.begin(9600); // Инициализация серийного порта irrecv.enableIRIn(); // Инициализация ИК-приёмника display.begin(); // Инициализация дисплея display.setContrast(45); // Установка контраста дисплея display.clearDisplay(); // Очистка дисплея display.setTextSize(1); // Установка мелкого шрифта display.setTextColor(BLACK); // Чёрный цвет текста display.setCursor(18, 0); display.println("E-TARGET"); display.display(); beep(); } /* Функция отображения меню */ void showMenu(uint8_t flagMenu) { if(flagDraw) { display.clearDisplay(); // Выводим одну и ту же надпись для 3-х повторяющихся пунктов if(flagMenu < 3) { display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(18, 0); display.println("E-TARGET"); display.drawLine(0, 8, 84, 8, BLACK); display.setCursor(4, 10); display.println("SHOOTING MODE"); display.drawLine(0, 18, 84, 18, BLACK); } if(flagMenu == 0) { display.fillRoundRect(0, 20, 33, 9, 3, BLACK); display.setTextColor(WHITE); display.setCursor(5, 21); display.println("EASY"); display.setTextColor(BLACK); display.setCursor(5, 30); display.println("MEDIUM"); display.setCursor(5, 39); display.println("HARD"); } else if(flagMenu == 10) { display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(18, 0); display.println("E-TARGET"); display.fillRoundRect(0, 8, 83, 9, 3, BLACK); display.setTextColor(WHITE); display.setCursor(15, 9); display.println("EASY MODE"); display.setTextColor(BLACK); display.setCursor(18, 18); display.println("Press OK"); display.setTextSize(3); display.setCursor(35, 27); display.println("0"); } else if(flagMenu == 100) { display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(18, 0); display.println("E-TARGET"); display.fillRoundRect(0, 8, 83, 9, 3, BLACK); display.setTextColor(WHITE); display.setCursor(15, 9); display.println("EASY MODE"); display.setTextColor(BLACK); display.setCursor(9, 18); display.println("SHOOT SCORE"); display.setTextSize(3); if(shootScore < 10) display.setCursor(35, 27); else if(shootScore > 9 && shootScore < 100) display.setCursor(25, 27); else if(shootScore > 99 && shootScore < 1000) display.setCursor(17, 27); else if(shootScore > 999 && shootScore < 10000) display.setCursor(9, 27); display.println(shootScore); } else if(flagMenu == 1) { display.setTextColor(BLACK); display.setCursor(5, 21); display.println("EASY"); display.fillRoundRect(0, 29, 45, 9, 3, BLACK); display.setTextColor(WHITE); display.setCursor(5, 30); display.println("MEDIUM"); display.setTextColor(BLACK); display.setCursor(5, 39); display.println("HARD"); } else if(flagMenu == 11) { display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(18, 0); display.println("E-TARGET"); display.fillRoundRect(0, 8, 83, 9, 3, BLACK); display.setTextColor(WHITE); display.setCursor(9, 9); display.println("MEDIUM MODE"); display.setTextColor(BLACK); display.setCursor(0, 18); display.print("RANDOM TIME:"); if(randomTime < 10) display.print("0"); display.print(randomTime); display.setTextSize(3); display.setCursor(35, 27); display.println("0"); } else if(flagMenu == 110) { display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(18, 0); display.println("E-TARGET"); display.fillRoundRect(0, 8, 83, 9, 3, BLACK); display.setTextColor(WHITE); display.setCursor(9, 9); display.println("MEDIUM MODE"); display.setTextColor(BLACK); display.setCursor(9, 18); display.println("SHOOT SCORE"); display.setTextSize(3); if(shootScore < 10) display.setCursor(35, 27); else if(shootScore > 9 && shootScore < 100) display.setCursor(25, 27); else if(shootScore > 99 && shootScore < 1000) display.setCursor(17, 27); else if(shootScore > 999 && shootScore < 10000) display.setCursor(9, 27); display.println(shootScore); } else if(flagMenu == 2) { display.setTextColor(BLACK); display.setCursor(5, 21); display.println("EASY"); display.setCursor(5, 30); display.println("MEDIUM"); display.fillRoundRect(0, 38, 33, 9, 3, BLACK); display.setTextColor(WHITE); display.setCursor(5, 39); display.println("HARD"); } else if(flagMenu == 21) { display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(18, 0); display.println("E-TARGET"); display.fillRoundRect(0, 8, 83, 9, 3, BLACK); display.setTextColor(WHITE); display.setCursor(15, 9); display.println("HARD MODE"); display.setTextColor(BLACK); display.setCursor(0, 18); display.print("SHOOT TIME:"); if(shootTime < 10) display.print("00"); else if(shootTime < 100) display.print("0"); display.print(shootTime); // Выводим на дисплей все 5 параметров SHOOT INTERVAL display.setCursor(0, 29); display.print("SHOOT INTERVAL"); display.setCursor(0, 38); for(uint8_t i = 0; i < 5; i++) { if(shootInterval[i] < 10) display.print("0"); display.print(shootInterval[i]); display.print(" "); } // Рисуем курсор под тем параметром, который в данный момент необходимо изменить switch(hardModeCursor) { case 0: display.drawLine(65, 26, 84, 26, BLACK); break; case 1: display.drawLine(0, 46, 10, 46, BLACK); break; case 2: display.drawLine(18, 46, 28, 46, BLACK); break; case 3: display.drawLine(36, 46, 46, 46, BLACK); break; case 4: display.drawLine(54, 46, 64, 46, BLACK); break; case 5: display.drawLine(72, 46, 82, 46, BLACK); break; } } else if(flagMenu == 210) { display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(18, 0); display.println("E-TARGET"); display.fillRoundRect(0, 8, 83, 9, 3, BLACK); display.setTextColor(WHITE); display.setCursor(15, 9); display.println("HARD MODE"); display.setTextColor(BLACK); display.drawLine(42, 18, 42, 48, BLACK); display.drawLine(41, 18, 41, 48, BLACK); display.setCursor(12, 18); display.println("TRY"); display.setCursor(56, 18); display.println("HIT"); display.drawLine(0, 26, 84, 26, BLACK); display.setTextSize(2); display.setCursor(3, 31); if(TRY < 10) display.print("00"); else if((TRY > 9) && (TRY < 100)) display.print("0"); display.print(TRY); display.setCursor(47, 31); if(shootScore < 10) display.print("00"); else if((shootScore > 9) && (shootScore < 100)) display.print("0"); display.println(shootScore); } flagDraw = false; display.display(); } } /* ОСНОВНОЙ ЦИКЛ ПРОГРАММЫ */ void loop() { while(1) { // Если на ИК-приёмник поступил сигнал if (irrecv.decode(&results)) { /* Если на пульте ДУ нажата кнопка "ВНИЗ" */ if(results.value == DOWN) { // Навигация по "ГЛАВНОМУ МЕНЮ" if(menuCursor < 3) { menuCursor++; if(menuCursor > 2) menuCursor = 0; flagDraw = true; } // Уменьшение параметра RANDOM TIME в режиме MEDIUM if(menuCursor == 11) { randomTime--; if(randomTime < 3) randomTime = 99; flagDraw = true; } // Уменьшение одного из параметров в режиме HARD if(menuCursor == 21) { if(hardModeCursor == 0) { // Уменьшаем параметр SHOOT TIME shootTime--; if(shootTime < 1) shootTime = 999; } else if(hardModeCursor > 0) { // Уменьшаем один из параметров SHOOT INTERVAL shootInterval[hardModeCursor - 1]--; if(shootInterval[hardModeCursor-1] < 0) shootInterval[hardModeCursor - 1] = 99; } flagDraw = true; } } /* Если на пульте ДУ нажата кнопка "ВВЕРХ" */ else if(results.value == UP) { // Навигация по "ГЛАВНОМУ МЕНЮ" if(menuCursor < 3) { menuCursor--; if(menuCursor < 0) menuCursor = 2; flagDraw = true; } // Увеличение параметра RANDOM TIME в режиме MEDIUM if(menuCursor == 11) { randomTime++; if(randomTime > 99) randomTime = 3; flagDraw = true; } // Увеличение одного из параметров в режиме HARD if(menuCursor == 21) { if(hardModeCursor == 0) { // Увеличиваем параметр SHOOT TIME shootTime++; if(shootTime > 999) shootTime = 0; } else if(hardModeCursor > 0) { // Увеличиваем один из параметров SHOOT INTERVAL shootInterval[hardModeCursor - 1]++; if(shootInterval[hardModeCursor-1] > 99) shootInterval[hardModeCursor - 1] = 0; } flagDraw = true; } } /* Если на пульте ДУ нажата кнопка "ВПРАВО" */ else if(results.value == RIGHT) { // Перемещаем курсор к следующему параметру в режиме HARD if(menuCursor == 21) { hardModeCursor++; if(hardModeCursor > 5) hardModeCursor = 0; flagDraw = true; } } /* Если на пульте ДУ нажата кнопка "ВЛЕВО" */ else if(results.value == LEFT) { // Перемещаем курсор к предыдущему параметру в режиме HARD if(menuCursor == 21) { hardModeCursor--; if(hardModeCursor < 0) hardModeCursor = 5; flagDraw = true; } } /* Если на пульте ДУ нажата кнопка "ОК" */ else if(results.value == OK) { /* Выход из режима EASY, MEDIUM или HARD*/ if(menuCursor >= 100) { menuCursor = -1; flagDraw = true; globalState = 0; shootMode = 0; shootScore = 0; shootFlag = false; } /* Нажимаем на пульте ОК. Бузер издает сигнал. Включается красный светодиод (нет попадания) */ if(menuCursor == 10) { menuCursor = 100; flagDraw = true; digitalWrite(pinGreenLed, LOW); digitalWrite(pinRedLed, HIGH); beep(); shootMode = EASY; globalState = 3; shootFlag = true; } /* Стреляем в режиме MEDIUM */ if(menuCursor == 11) { menuCursor = 110; flagDraw = true; digitalWrite(pinGreenLed, LOW); digitalWrite(pinRedLed, LOW); beep(); shootMode = MEDIUM; globalState = 5; shootFlag = true; } /* Стреляем в режиме HARD */ if(menuCursor == 21) { menuCursor = 210; flagDraw = true; digitalWrite(pinGreenLed, LOW); digitalWrite(pinRedLed, LOW); beep(); shootMode = HARD; globalState = 7; shootTimer = millis(); shootFlag = true; } // Вход в режим EASY if(menuCursor == 0) { menuCursor = 10; shootScore = 0; flagDraw = true; } // Вход в режим MEDIUM if(menuCursor == 1) { menuCursor = 11; shootScore = 0; flagDraw = true; } // Вход в режим HARD if(menuCursor==2){menuCursor=21;TRY=0;shootScore=0;shootIntervalCursor=0;flagDraw=true;} } irrecv.resume(); } if(globalState == 0) { ledBlinkTimer = millis(); digitalWrite(pinGreenLed, HIGH); digitalWrite(pinRedLed, LOW); globalState = 1; } else if(globalState == 1) { if((millis() - ledBlinkTimer) > 500) { ledBlinkTimer = millis(); digitalWrite(pinGreenLed, LOW); digitalWrite(pinRedLed, HIGH); globalState = 2; } } else if(globalState == 2) { if((millis() - ledBlinkTimer) > 500) globalState = 0; } else if(globalState == 4) { flagDraw = true; showMenu(menuCursor); digitalWrite(pinGreenLed, HIGH); digitalWrite(pinRedLed, LOW); beep(); beep(); digitalWrite(pinGreenLed, LOW); digitalWrite(pinRedLed, HIGH); if(menuCursor == 100) globalState = 3; else if(menuCursor == 110) globalState = 5; else if(menuCursor == 210) { if(shootIntervalCursor < 4) shootIntervalCursor++; globalState = 7; } //flagDraw = true; shootFlag = true; } else if(globalState == 5) { randomSeed(analogRead(0)); mm_randomTime = random(3000, (randomTime * 1000)); Serial.print("randomTime="); Serial.println(mm_randomTime); mm_randomTimer = millis(); digitalWrite(pinRedLed, HIGH); globalState = 6; shootFlag = true; } else if(globalState == 6) { // Если в течение выделенного таймслота нет попадания if((millis() - mm_randomTimer) > mm_randomTime) { if(shootScore > 0) shootScore--; shootFlag = false; beep_1(); digitalWrite(pinRedLed, LOW); delay(200); digitalWrite(pinRedLed, HIGH); delay(200); digitalWrite(pinRedLed, LOW); delay(200); digitalWrite(pinRedLed, HIGH); delay(200); digitalWrite(pinRedLed, LOW); delay(200); flagDraw = true; globalState = 5; } } else if(globalState == 7) { Serial.print("Shoot time:"); Serial.println(shootTime * 1000); hm_Timer = millis(); hm_Time = shootInterval[shootIntervalCursor] * 1000; Serial.print("shootInterval="); Serial.println(hm_Time); digitalWrite(pinRedLed, HIGH); globalState = 8; shootFlag = true; TRY++; flagDraw = true; } else if (globalState == 8) { // Если общее время стрельбы ещё не вышло if((millis() - shootTimer) < (shootTime * 1000)) { // Если в течение выделенного таймслота нет попадания if((millis() - hm_Timer) > hm_Time) { if(shootScore > 0) shootScore--; beep_1(); digitalWrite(pinRedLed, LOW); delay(200); digitalWrite(pinRedLed, HIGH); delay(200); digitalWrite(pinRedLed, LOW); delay(200); digitalWrite(pinRedLed, HIGH); delay(200); digitalWrite(pinRedLed, LOW); delay(200); flagDraw = true; globalState = 7; if(shootIntervalCursor > 0) shootIntervalCursor--; } } else { // Если прошло время, отведённое на стрельбу digitalWrite(pinRedLed, LOW); digitalWrite(pinRedLed, LOW); shootFlag = false; flagDraw = true; globalState = 100; Serial.println("HARD MODE-TIME OUT"); } } showMenu(menuCursor); if(menuCursor == -1) { menuCursor = 0; flagDraw = true; } } } /* Функция-обработчик прерывания */ void shoot() { if(shootMode) { if(shootFlag) { shootFlag = false; globalState = 4; shootScore++; } } }

    Если кто был внимателен при прочтении скетча, тот наверняка заменил, что я отказался от кнопки «EXIT», так как посчитал её лишней для данного проекта и выход в верхнее меню осуществляется повторным нажатием кнопки «OK». Ну и наконец, ниже представлены несколько фото работающей мишени, которая доставила массу удовольствия при стрельбе и заставила поработать мозг при её создании.

    easy.jpg

    Режим «EASY»


    medium.jpg

    Режим «MEDIUM»


    hard.jpg

    Режим «HARD»

    Похожие статьи

    Обзор высокотемпературной сушилки Sunlu FilaDryer E2
    3D печать
    18 сентября 2025
    Обзор высокотемпературной сушилки Sunlu FilaDryer E2
    Датчик цвета TCS230
    Датчики
    04 декабря 2024
    Датчик цвета TCS230
    Установка Octoprint на 3D-принтер. Пошаговая инструкция
    3D принтеры
    01 июля 2024
    Установка Octoprint на 3D-принтер. Пошаговая инструкция
    Назад к списку
    • Все публикации 273
      • 3D печать 62
      • 3D принтеры 57
      • 3D сканеры 1
      • Arduino механика 6
      • Arduino платы 8
      • Датчики 27
      • Дисплеи 6
      • Кейсы 1
      • Компоненты 13
      • Мировые новости 35
      • Модули 38
      • Проекты 7
      • Сопутствующие 2
      • ЧПУ 10
    Подпишитесь на рассылку наших новостей и акций
    Подписаться
    Подписаться
    на новости и акции
    Связаться с нами
    +71000000011
    +7 100 000-00-11 Консультация
    +7 100 000-00-22 Отдел продаж
    +7 100 000-00-33 Бухгалтерия
    E-mail
    info@site.com
    Адрес
    Москва, ул. Пушкинская, д.12
    Режим работы
    Пн - Вс: 10.00 - 19.00
    info@site.com
    Москва, ул. Пушкинская, д.12
    Каталог товаров
    3D принтеры
    3D-сканеры
    Материалы для 3D печати
    Комплектующие 3D принтера
    Arduino и робототехника
    Комплектующие ЧПУ станка
    Инструменты
    Запчасти для 3D принтеров по брендам
    Компания
    О компании
    Акции
    Блог
    Методы оплаты
    Методы доставки
    Гарантия
    Отзывы
    Контакты
    Личный кабинет
    Избранное
    Сравнение товаров
    Мои заказы
    Авторизация
    Регистрация
    Восстановление пароля
    Информация
    Политика конфиденциальности
    Политика использования файлов cookie
    Договор публичной оферты
    © 2026 Site
    Каталог товаров
    Компания
    Личный кабинет
    Информация
    Главная Каталог 0 Корзина 0 Избранные Кабинет 0 Сравнение Бренды Контакты