Электронный прицел на OSD-генераторе MAX7456.

Электронный прицел

Описывается Ардуино-проект электронного прицела для высокоточного сверлильного станка. Устройство значительно облегчает точное попадание сверла в метку на детали. Данная разработка может быть использована и в других приложениях, требующих наложения на видеосигнал прицельного маркера.

Примерно год тому назад Игорь из Москвы заказал мне разработку программы для системы управления сверлильным станком. Станок он собрал сам из комплектующих, купленных на Али Экспресс.

 

Я не буду объяснять, как устроена механика станка. Боюсь опозориться при употреблении терминов. Устройство станка можно понять по фотографиям.

Электронный прицел

Электронный прицел

Электронный прицел

Электронный прицел

Игорь – человек, который привык все делать хорошо. На мой взгляд, даже слишком хорошо. Он поставил задачу реализовать в программе все, что можно придумать и, что позволяет сделать электромеханика. Я уже все функции не помню.

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

  • скорости опускания, подъема, вхождения в деталь сверла;
  • скорость вращения сверла;
  • глубина сверловки;
  • положение сверла над деталью.
  • Все параметры задаются для разных материалов и выбираются группами через название материала.
  • На дисплее отображаются параметры, режим, подсказки и т.п.

Вот фильм о работе станка.

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

 

В механике ему тоже что-то в первом варианте не понравилось. Он переделал станок. На креплении направляющих закрепил видеокамеру.

Электронный прицел

Осталось сделать электронику, которая будет на видеосигнал камеры накладывать прицельное перекрестие.

Принцип работы планировался следующий. На детали зенкуется метка. Затем кнопками прицела перекрестие наводится на эту метку. Теперь, если толщина детали не изменится, то сверло всегда будет попадать в место, указанное прицельным перекрестием.

Такой проект и был реализован с использованием OSD-генератора MAX7456.

MAX7456 – это микросхема стоимостью 100 рублей, которая позволяет накладывать на видеосигнал текстовую и псевдографическую информацию. Я подробно описывал ее в уроках Ардуино (урок 66, 67, 68). Буду рассказывать дальше исходя из того, что вы хотя бы просмотрели эти уроки.

Игорь разработал и изготовил печатную плату для OSD-модуля MAX7456. Схема модуля стандартная, приведена в уроке 66.

OSD-модуль

Такие модули есть и готовые.

OSD-модуль

К модулю я добавил плату Arduino Nano (можно использовать Arduino PRO Mini) и 5 кнопок управления маркером. Разработка получилась вполне бюджетной.

Схема соединения электронных компонентов устройства выглядит так.

Схема соединения

Вот мой макет.

Макет электронного прицела

Работать с электронным прицелом очень просто.

Видеосигнал с камеры подается на вход модуля, к его выходу подключается монитор.

Устройство в сборе

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

Прицельное перекрестие

Прицельное перекрестие

Прицельное перекрестие

Маркер можно двигать кнопками ВВЕРХ, ВНИЗ, ВПРАВО, ВЛЕВО. При кратковременном нажатии на кнопку прицельная метка меняет свое положение на минимальную единицу. При удержании - перемещается. Нажатием на кнопку ИНВЕРСИЯ можно инвертировать изображение маркера. На темных деталях удобнее работать со светлой меткой и наоборот.

 

В правом верхнем углу экрана выводятся условные координаты маркера относительно центра экрана. Надпись mypractic.ru в правом нижнем углу можно написать свою, можно убрать.

Конечно, при выключении питания последнее положение маркера прицела сохраняется.

Скетч проекта можно загрузить по ссылке:

  Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта!  

Используются библиотеки:

  • max7456.h

  Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта!  

  • Button.h

  Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта!  

Еще необходим пакет для загрузки знакогенератора MAX7456.

  Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта!  

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

Обязательно необходимо установить систему отображения монитора NTSC или PAL. Это производится в строчке функции setup().

osd.videoStandartSelect(1); // выбор системы 0 - NTSC, 1 - PAL

Я создал маркер прицеливания в виде простого креста. Игорь изменил его на метку более сложной формы.

В любом случае маркер должен быть загружен в MAX7456. Как это делается подробно описано в уроке 68. Пакет для загрузки MAX7456_Font_Loader со знакогенератором, в котором маркер задан в виде креста, можно загрузить по ссылке выше.

Маркер состоит из 6 знакомест (3 x 2 ). Каждое знакоместо 12 x 18 пикселей. Значит, маркер имеет разрешение 36 x 36 пикселей. Вам надо в пакете MAX7456_Font_Loader отредактировать 6 знакомест с адресами (кодами символов) 0xc3 – 0xc8. Эти адреса заданы в массиве программы.

byte mark[6] = {0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8};  // метка

Все работает замечательно. Очень удобно сверлить самые точные отверстия. Думаю такой электронный прицел можно использовать и на обычных сверлильных станках.

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

 

Сейчас над этим работаем. По сути, я разрабатываю последовательный OSD-терминал. Т.е. устройство, которое накладывает на видеосигнал текст и псевдографику, передаваемую по последовательному порту. А текст будет передаваться от, разработанной на предыдущем этапе, системы управления сверлильным станком.

 

Доработанный вариант устройства.

По просьбе Игоря я доработал устройство. Другого Игоря. Почему-то электронным прицелом интересуются люди именно с таким именем.

Он попросил добавить возможность выбора типа маркера.

Вот новый скетч:

  Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта!  

Коды символов для маркеров задаются в массиве:

const byte marks[60] = {

0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65,
0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8
};

У меня массив на 10 маркеров.

Надо задать количество маркеров:

#define MARKS_NUM 3 // число маркеров

И еще добавлена кнопка выбора маркера:

Button btMark(7, 25);  // кнопка выбор маркера

Я подключило ее к 7 выводу.

Последний проект не проверен, могут быть ошибки.

-1

Автор публикации

не в сети 17 часов

Эдуард

184
Комментарии: 1633Публикации: 161Регистрация: 13-12-2015

63 комментария на «Электронный прицел на OSD-генераторе MAX7456.»

  1. Доброго дня и здоровья Эдуард !!! Молодец, все очень здорово. Но есть единственное что бы я например исправил, так это управление не 5 кнопок а 3, кнопка меню в котором выбираешь пункты меню верх низ и запомнить состояние а другими правишь. Как тебе такое ?

    0
    • Здравствуйте!
      Для сверлильного станка операцию установки маркера надо производить часто и оперативно. Поэтому я посчитал, что с четырьмя кнопками будет удобнее.

      0
      • А мне надо, потому что есть мах на котором 20 видов перекрестий и я ни как не могу их вытащить. Как с этим быть даже не знаю!? С Уважением дед Игорь

        0
          • Дело в том, что даже те что даны в этом проекте не пойму как выводятся на экран, далек я от этого и не понимаю как можно нарисовать еще и как их потом менять, вот так Эдуард !

            0
  2. Вот то что написано тобой «Маркер состоит из 6 знакомест (3 x 2 ). Каждое знакоместо 12 x 18 пикселей. Значит, маркер имеет разрешение 36 x 36 пикселей» для меня темный лес !

    0
    • Нарисуйте на листочке 6 прямоугольников, 2 ряда по три прямоугольника. Это знакоместа. Они отображаются на экране так, как нарисованы, без зазоров. Каждое знакоместо это таблица 12 на 18. Ячейка таблицы это пиксель. Получается таблица 36 на 36. В ней и надо рисовать маркер. Прочитайте внимательно первую часть урока 68. Там подробно рассказано, как редактировать знакогенератор. Нужные вам знакоместа имеют адреса c3 — c8. Их и надо отредактировать и загрузить.

      0
      • Надо конечно вникать, чем и буду заниматься, просто писать одно и всего не опишешь, а вот общение совсем другое где и я могу что то более подробно изучить со слов учителя.

        0
    • Там и должно быть пустое место. Крест смещен влево. Невозможно при четном числе пикселей нарисовать посередине.

      0
        • Добрый день!Мне очень интересна это программа.Но довольно староват заниматься этим.У меня вопрос,помощь от Вас скорее.Очень хочу себе ночной электронный прицел,а то волки в наглую в деревню заходят,собак воруют и мало того и люди ходят и дети по вечерам. Подсказали что можно с Ардуино создать электронную сетку на прицел,в мониторчике и попробовать сделать поправки.Здесь для сверлильного станка и подумал ведь можно и на ружье.Купить прицел нет таких возможностей это очень дорого с моей пенсией.Если Вы можете сделать в этих электронных плат то помогите.Сможете мне настроить на этих компонентах я оплачу если вышлите мне эти готовые и настроенные платы.Соеденить это у меня есть телемастер.Спасибо и извините если что.

          0
  3. Еще одно спрошу, в знакогенераторе все выделено по краям символов черными квадратиками, а перекрестие нет ?

    0
  4. Приветствую Эдуард !!! Здоровья и благополучия ! Разобрался немного, если добавить еще парочку разновидностей перекрестия, что нужно изменить или добавить чтоб можно было их менять ?

    0
  5. Добрый день. Очень полезная разработка. Намерен повторить.
    Весьма распространенная плата MinimOSD (ATmega328 и MAX7456)
    Например http://rufavor.ru/goods-4468.html
    Такая подойдет и надо ли править скетч?

    0
  6. Здравствуйте Эдуард. Повторил ваш проект на плате micro minimosd, разобрался как работать с маркерами.
    Прошу Вас помочь добавить в вашу прошивку electronic_sight_1_5 управление по ИК каналу. В вашем проекте используются прерывания, а я еще тот «программист»…..:(
    Сам же в данный момент мучаю библиотеку IRremote.h

    0
    • И еще вопрос. Как добавить вывод динамической информации? Допустим время работы с момента включения.

      0
      • Здравствуйте!
        Я собираюсь выложить проект OSD-терминала. Может он вам поможет.
        Это устройство, которое выводит на OSD-экран данные, поступающие с последовательного порта. Я использовал его в сверлильном станке. Там на экран выводится все, что угодно — и текстовая информация, и рамки, и маркер для прицеливания. Может удобнее по ИК-каналу передавать данные, которые будут выводиться на экран.

        0
        • Небольшое уточнение.Под ИК я подразумевал управление стандартным пультом например от ТВ приставки. Не всегда удобно тянуться до кнопок.

          0
          • Все, вопрос решил…. был какой то конфликт связанный с библиотекой MsTimer2.h. Процессор входил в бесконечный цикл. Удалил все что связанно с кнопками, получилось ШИКАРНО. Может кому то пригодиться.

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

          0
  7. Эдуард подскажите, возможно ли сделать OSD генератор для VGA сигналов? Будете ли Вы в дальнейшем работать в этом направлении? Может у вас есть ссылка на какое то решение?

    0
  8. Здравствуйте! Давно ищу подобное решение для отображения прицельной сетки в приборе тепловизионном. Можно ли у вас приобрести готовый прибор? Если не трудно, напишите мне,пожалуйста, на почту: hoope01@mail.ru

    0
  9. Здравствуйте Эдуард. Очень кстати! Можно сдружить мой заброшенный проект с Вашей разработкой. Принцип сверлильного станка почти тот же, только я в своём проекте целился вебкой от ноутбука. Вебка была закреплена под поднятым сверлом на БМГ HDD прямо над предполагаемым отверстием. При сверлении вебка отъезжала приводом БМГ, сверлилось отверстие, вебка возвращалась в исходное положение для нового прицеливания.
    https://www.radiokot.ru/lab/hardwork/138/
    Можно ли мне в обсуждении моего станка ( https://www.radiokot.ru/forum/viewtopic.php?t=147425 ) добавить ссылку на Ваш проект?

    0
  10. Приветствую тебя Эдуард !!!! Здоровья !!! Много времени прошло с тех пор как ты мне помог по этому проекту, за что тебе очень благодарен !!! Но вот опять возник вопрос, перекрестие которое я рисую на экранчике моего мониторчика очень маленькое, можно ли программно увеличить символы которые выводятся на экран ??? Зарание благодарю тебя !!! Здоровья, благополучия, с Уважением дед Игорь !!!

    0
    • Здравствуйте!
      Спасибо за пожелания. Вам тоже всего самого лучшего.
      Сомнительно, что это легко получится сделать. В программе двигается по экрану массив из 6 символов.
      byte mark[6] = {0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8}; // метка
      Попробовать его увеличить и изменить блок перерисовки.
      // стереть предыдущую метку
      if( (prevCharPositionX != charPositionX) || (prevCharPositionY != charPositionY) ) {
      osd.printMax7456Char(‘ ‘, prevCharPositionX, prevCharPositionY);
      osd.printMax7456Char(‘ ‘, prevCharPositionX +1, prevCharPositionY);
      osd.printMax7456Char(‘ ‘, prevCharPositionX +2, prevCharPositionY);
      osd.printMax7456Char(‘ ‘, prevCharPositionX, prevCharPositionY +1);
      osd.printMax7456Char(‘ ‘, prevCharPositionX +1, prevCharPositionY +1);
      osd.printMax7456Char(‘ ‘, prevCharPositionX +2, prevCharPositionY +1);
      }

      prevCharPositionX= charPositionX;
      prevCharPositionY= charPositionY;

      // вывести новую метку
      osd.setDisplayOffsets(offsetX, offsetY);

      osd.printMax7456Char(* (mark+0), charPositionX, charPositionY,0,inv);
      osd.printMax7456Char(* (mark+1), charPositionX +1, charPositionY,0,inv);
      osd.printMax7456Char(* (mark+2), charPositionX +2, charPositionY,0,inv);
      osd.printMax7456Char(* (mark+3), charPositionX, charPositionY +1,0,inv);
      osd.printMax7456Char(* (mark+4), charPositionX +1, charPositionY +1,0,inv);
      osd.printMax7456Char(* (mark+5), charPositionX +2, charPositionY +1,0,inv);

      0
      • Привет Эдуард !!! Здоровья !!! Даже приятно что откликнулся, все что ты написал я уже сделал, дошел своим серым веществом и все получилось, я сделал на 12 символов массив и на 3 маркера, ну я тебе скажу для меня это довольно трудно было поставить каждый символ куда надо, но вот что интересно, смотрим скетч:
        unsigned char marks[36] = {
        0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
        0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
        0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0 и

        // стереть предыдущую метку
        if( (prevCharPositionX != charPositionX) || (prevCharPositionY != charPositionY) ) {
        osd.printMax7456Char(‘ ‘, prevCharPositionX, prevCharPositionY); // 1
        osd.printMax7456Char(‘ ‘, prevCharPositionX +1, prevCharPositionY); // 2
        osd.printMax7456Char(‘ ‘, prevCharPositionX +2, prevCharPositionY); // 3
        osd.printMax7456Char(‘ ‘, prevCharPositionX, prevCharPositionY +1); // 4
        osd.printMax7456Char(‘ ‘, prevCharPositionX +1, prevCharPositionY +1); // 5
        osd.printMax7456Char(‘ ‘, prevCharPositionX +2, prevCharPositionY +1); // 6
        osd.printMax7456Char(‘ ‘, prevCharPositionX -1, prevCharPositionY); // 7
        osd.printMax7456Char(‘ ‘, prevCharPositionX +1, prevCharPositionY -1); // 8
        osd.printMax7456Char(‘ ‘, prevCharPositionX +3, prevCharPositionY); //9
        osd.printMax7456Char(‘ ‘, prevCharPositionX -1, prevCharPositionY +1); // 10
        osd.printMax7456Char(‘ ‘, prevCharPositionX +1, prevCharPositionY +2); // 11
        osd.printMax7456Char(‘ ‘, prevCharPositionX +3, prevCharPositionY +1); // 12
        }

        prevCharPositionX= charPositionX;
        prevCharPositionY= charPositionY;

        // вывести новую метку
        osd.setDisplayOffsets(offsetX, offsetY);

        osd.printMax7456Char(* (mark+0), charPositionX, charPositionY,0,inv); // 1
        osd.printMax7456Char(* (mark+1), charPositionX +1, charPositionY,0,inv); // 2
        osd.printMax7456Char(* (mark+2), charPositionX +2, charPositionY,0,inv); // 3
        osd.printMax7456Char(* (mark+3), charPositionX, charPositionY +1,0,inv); // 4
        osd.printMax7456Char(* (mark+4), charPositionX +1, charPositionY +1,0,inv); // 5
        osd.printMax7456Char(* (mark+5), charPositionX +2, charPositionY +1,0,inv); // 6
        osd.printMax7456Char(* (mark+6), charPositionX -1, charPositionY,0,inv); // 7
        osd.printMax7456Char(* (mark+7), charPositionX +1, charPositionY -1,0,inv); // 8
        osd.printMax7456Char(* (mark+8), charPositionX +3, charPositionY,0,inv); // 9
        osd.printMax7456Char(* (mark+9), charPositionX -1, charPositionY +1,0,inv); // 10
        osd.printMax7456Char(* (mark+10), charPositionX +1, charPositionY +2,0,inv); // 11
        osd.printMax7456Char(* (mark+11), charPositionX +3, charPositionY +1,0,inv); // 12

        В начале указываю сколько знаков «3» первый знак нарисовал и он выводится правильно, 2 й знак не рисовал совсем, а когда переключаюсь кнопкой на 2 й и 3 й знак он мне показывает фрагменты из 1 го, почему, так и не разобрался. Давай и подумаем почему так происходит, 2 й и 3 й должно быть пустое поле, а он кидает из первого не все конечно, так обрывки. С Уважением дед Игорь !!! Здоровья и благополучия !!!

        0
        • Привет!У вас неправильно стираются и перерисовываются маркеры. Надо это делать по столбцам. Если у вас матрица 4×3, то
          X,Y X,Y+1 X,Y+2 X,Y+3
          X+1,Y X+1,Y+1 X+1,Y+2 X+1,Y+3 и т.д.

          1
          • Привет Эдуард !!! Не понял, что значит по столбцам ? Я расписываю 1 строчку, 2 ю и третью, а как по столбцам не понял ?? С Уважением дед Игорь !!!

            0
          • И первую строку из 12 символов программа выводит правильно на экран
            1. 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
            2. 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
            3. 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab,

            0
          • Я посмотрел, у меня вроде так и получается как я описываю и как ты мне говоришь, может что то и не до понимаю, проясни пожалуйста мою старую головушку !!!

            0
          • Я уже сам подзабыл. Конечно, по строкам. Все равно, откуда — 1?
            osd.printMax7456Char(* (mark+6), charPositionX -1, charPositionY,0,inv); // 7

            0
  11. Все, причина найдена, markToScreen(marks + marksNum * 12, currX, currY); в место 12 было 6, вот и вся причина не правильного вывода. С Уважением дед Игорь !!! Здоровья и долголетия !!!

    0
      • Да уж !!! Нет так все хорошо но при перемещении перекрестия вылазят еще какие то черточки и пропадают только при выключении и последующем включении прибора, что это за ерунда не понятно.

        0
  12. Все, и эту проблему нашел, Эдуард ! Благодарю тебя за внимание, Здоровья, Успехов и всего наилучшего, до свидания, я не прощаюсь !!! С Уважением дед Игорь !!!

    0
  13. Привет Эдуард !!! Хотел спросить, в программе есть обращение на вывод информации порядкового номера маркера, а на экран номер маркера не выводится, просмотрел весь скетч и ничего не нашел, посмотри пожалуйста !!! С Уважением Игорь!

    0
    • Здравствуйте!
      Делать это надо в блоке
      if( onScreen == true ) {
      // вывод информации на экран
      . . . . .
      // вывод координат
      . . . . . .
      // вывод номера маркера
      osd.print(marksNum, 20, 10); // координаты X, Y
      }

      Если с текстом перед маркером, то
      sprintf(str,»текст перед маркером %d», marksNum);
      osd.print(str,20, 10); // координаты X, Y

      0

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить" Вы даёте свое согласие на обработку введенной персональной информации в соответствии с Федеральным Законом №152-ФЗ от 27.07.2006 "О персональных данных".