Это вторая часть серии, посвящённой сборке инструментов на основе датчика Холла. Если первую часть вы не читали, то лучше будет начать с неё: Электронный циркуль Тима. В этом проекте я буду использовать уже не один, а два датчика 49E, каждый с парой магнитов, по тому же принципу, что и при сборке циркуля.
Для реализации потребуется 3D-принтер, так как точность сборки является ключевым фактором.
Как и прежде, я буду использовать Arduino Nano с ЖК-дисплеем, отображающим координаты, но для получения практических результатов потребуется приложение, которое будет отрисовывать графику. И такое приложение я написал.
Тем, кто решит реализовать этот проект, понадобится базовое понимание платформы Arduino и некоторое знание G-Code.
▍ Материалы
- два линейных датчика Холла 49E;
- четыре неодимовых магнита, ширина и длина 5мм, высота 2мм (направление Север/Юг ориентировано по оси высоты);
- инструмент для определения полюсов магнитов. Я использовал приложение на телефоне;
- Arduino Nano;
- жк-дисплей 1602 с интерфейсом I2C и модуль PCF8575 для его подключения;
- кабель, будет прокладываться вдоль ножек пантографа. Я взял шлейф из старого принтера;
- набор разъёмов DuPont и гребёнки;
- нажимная кнопка 6х6х5мм для монтажа через отверстия;
- два стержня диаметром 8мм и длиной 171мм. Я использовал бамбуковые.
- кучка саморезов М1.7х6мм;
- стержень диаметром 3мм и длиной 300мм. Этот пойдёт на изготовление штифта для обводки. Можно взять стальной, латунный, алюминиевый или из любого аналогичного материала;
- лист ДВП 3мм. Я использовал имевшийся под рукой размером 285х380мм – меньше уже не пойдёт. Также подойдёт картон;
- клей, в моём случае УФ-смола;
- ну и уже упомянутый 3D-принтер для печати деталей пантографа.
Фото материалов
Ниже даны ссылки на STL-файлы. Имейте в виду, что Electics_Mount_No_Fillest.stl не соответствует моему стандарту, т.к. на Instructables максимальный размер загружаемого файла ограничен 25МБ.
- Base Pivot.stl
- Arm_Magnet_End.stl
- Arm Stops.stl
- First_Arm_Pivot.stl
- Sylus_Holder.stl
- Sylus_Cap.stl
- Cable_Clips_L_Type_Long.stl
- Cable_Clips_L_Type_Short.stl
- Cable_Clip_Simple.stl
- First_Arm_Support.stl
- Depth_Check.stl
- Second_Arm_Height_Check.stl
- M2_Washer_x_1_x_5.stl
- Electics_Mount_No_Fillest.stl
▍ Шаг 1: пантограф
Я назвал этот инструмент электронным пантографом, но считаю, что сначала лучше пояснить, о каком именно инструменте идёт речь (ведь пантографы бывают и на поездах).
Если простыми словами, то это устройство для копирования линий на плоской поверхности с помощью параллельных направляющих (плечей), поворачивающихся в устанавливаемых точках. Путём смещения этих точек можно регулировать масштаб копируемых линий.
Поскольку я собираю электронный пантограф, мне потребуется всего два стержня, положения которых будут регистрироваться электронно. Затем зарегистрированные позиции можно будет использовать для электронной отрисовки скопированных линий в любом масштабе.
▍ Шаг 2: направление магнитов
Северный полюс должен указывать в направлении стержня, вставленного в держатель магнита (Arm Magnet End). Как и при сборке циркуля, здесь для определения полюсов я использовал приложение на телефоне.
Магниты устанавливаются первым делом, потом уже собирается вся конструкция. Перед этим нужно будет убедиться, что они плотно входят в паз – там есть наплыв, который может потребовать зачистки после печати.
На этот раз ввиду столь близкого расположения магнитов я сделал их держатели раздвижными, чтобы упростить сборку. После установки держателей на поворотные элементы (Base Pivot, First Arm Pivot) их свободные концы стягиваются винтом.
Возможно, придётся повращать детали относительно друг друга, чтобы добиться достаточно плотной посадки.
▍ Шаг 3: упоры
Упоры (Arm Stops) нужно одеть на поворотные сегменты. Оба упора плечей одинаковые, каждый фиксируется с помощью двух винтов. Их верхняя часть имеет изогнутую форму, и её нужно правильно сориентировать, так что обратите внимание, в какую сторону упоры повёрнуты на чертеже.
▍ Шаг 4: стержни
В качестве стержней я использовал бамбуковые палочки диаметром 8мм, хотя для этой цели сойдут и другие аналогичные детали диаметром не менее 6мм – вам нужно будет просверлить их, чтобы зафиксировать с помощью саморезов M1.7x6мм.
Длина стержней должна быть ровно 171мм. Их необходимо плотно вставить в держатели магнитов и зафиксировать с помощью двух винтов. Направляющие отверстия диаметром 1.2мм под винты я просверлил в стержнях уже после их установки в держатели.
▍ Шаг 5: доска
Дополнительные фото
На чертежах показана разметка доски. Общий размер моей может показаться несколько странным, но под рукой у меня оказалась только такая. Здесь же отмечена рабочая область.
Отверстия для крепления треугольной опоры разметить не так просто. Я советую отложить это до момента, когда вы уже зафиксируете верхнюю часть опоры первого плеча (First Arm Support), и просверлить их по месту. Все отверстия должны иметь диаметр 1.2мм под винты M1.7x6мм. При этом общий размер доски не обязательно должен быть такой же. Главное, чтобы все отверстия и рабочая область соотносились друг с другом пропорционально.
Для большей наглядности я нарисовал на доске рабочую область. Калибровочный крестик потребуется позже, но отметить его лучше сейчас.
Ниже я также привёл ссылку на DXF-файл доски.
▍ Шаг 6: установка первого плеча
Закрепите первое плечо (First Arm) к доске с помощью четырёх винтов.
▍ Шаг 7: установка опоры первого плеча
Закрепите опору первого плеча к доске, прикрутив её верхнюю часть четырьмя винтами.
Если до этого у вас возникли сложности с разметкой трёх отверстий для нижней части, можете просверлить их сейчас, когда деталь зафиксирована.
Вкрутите оставшиеся три винта.
▍ Шаг 8: присоединение второго плеча к первому
Второе плечо должно плотно сесть на стержень первого, после чего его нужно зафиксировать двумя винтами. Направляющие отверстия под них я просверлил уже после установки второго плеча.
Для контроля его уровня в плоскости я дополнительно напечатал небольшой высотомер.
При установке второго плеча удобнее всего расположить его под 90° относительно первого.
▍ Шаг 9: штифт для обводки
Штифт я изготовил из круглого металлического стержня. Здесь неважно, какой материал использовать, можете брать любой. Его диаметр должен быть 3мм, а общая длина 30мм.
Верхняя часть штифта плоская, её размер особой роли не играет. Небольшой выпил в форме «I» — нужен, чтобы можно было вкрутить винт, который не даст штифту выпасть, но при этом позволит перемещаться вверх-вниз. Это вертикальное движение ему необходимо для активации переключателя.
▍ Шаг 10: держатель штифта
Вставьте штифт в держатель (Stylus Holder) плоской стороной вперёд и зафиксируйте с помощью винта. Туго не затягивайте, винт должен выступать ровно настолько, чтобы не позволять штифту выпасть.
Установите переключатель в верхнюю часть держателя и зафиксируйте его с помощью крышечки (Stylus Cap). Крышечку прикрутите винтом.
▍ Шаг 11: крепление держателя штифта ко второму плечу
Держатель нужно плотно насадить на стержень плеча и зафиксировать двумя винтами. Направляющие отверстия под них я просверлил уже после его установки.
Прежде чем прикручивать держатель, убедитесь в его вертикальном положении.
▍ Шаг 12: схема
Дополнительные фото
Схему я делал в программе Fritzing. В качестве кабелей я взял шлейфы (FFC). По-моему, с ними смотрится круто. К тому же — у меня осталось много таких от старых разобранных принтеров и планшетных сканеров.
Сам кабель я зафиксировал с помощью клипс, которые тоже напечатал. В своих проектах я ещё использую 3-х и 4-жильные плоские servo-кабели. Если речь идёт только о передаче данных, то беру 32SWG.
Немного поясню про кнопку в схеме.
Я использую плату Arduino Nano, у которой есть ряды контактов питания, земли и данных. В коде я устанавливаю прерывания для кнопки (Button), подключённой к выводам A3 и A0, контакты A1 и A2 оставляю на будущее.
Как правило, я использую схему антидребезга, чтобы не реализовывать его обработку в коде, который только всё замедлит. Поэтому для работы с подобными платами я собрал небольшой адаптер, а именно RC-цепь.
Ниже ссылки на файлы Fritzing и их PDF-версии.
- Tims Electrical Pantograph.fzz
- Tims Electrical Pantograph_schem.pdf
- Tims Electrical Pantograph_bb.pdf
▍ Шаг 13: установка датчиков
Дополнительные фото
Чтобы обеспечить правильное положение датчиков при установке, я напечатал небольшой глубиномер (Depth Checker).
У этого глубиномера есть специальная зазубрина, которая позволяет проконтролировать погружение датчика, устанавливаемого в поворотную основу (Base Pivot). А при установке второго датчика, уже в поворотный сегмент первого плеча (First Arm Pivot), глубиномер погружается в отверстие полностью, доставая до верхнего края этого датчика.
Отверстия в поворотных деталях сделаны так, чтобы направление датчиков было очевидным. Сами же датчики я фиксирую небольшим количеством клея, который наношу в месте выхода их контактов.
▍ Шаг 14: прокладка шлейфа
Если вы, как и я, используете шлейф, не пытайтесь паять его концевые выводы – лучше их отрезать и распустить провода с помощью ножниц.
Дополнительные фото
Далее для очистки изоляции можно просто подержать концы проводов рядом с жалом паяльника.
Здесь поможет много флюса. Шлейфы не такие нежные, как может показаться. Мой, к сожалению, оказался коротковат и до платы не доставал, поэтому я нарастил его обычным кабелем, объединив при этом провода питания и земли.
▍ Шаг 15: крепление Arduino
Для крепления Arduino и дисплея я напечатал небольшой кронштейн.
Я использую плату расширения Nano Uno, так что кронштейн изготовил под неё. По опыту знаю, что иногда платы могут немного отличаться, но при наличии отверстий Uno должны подходить.
Uno в кронштейн впишется, но если вы решите использовать именно её, то код нужно будет скорректировать, так как у этой модели нет выводов A6 и A7.
Все использованные винты имеют размер M1.7x6мм. На случай если вам понадобятся шайбы, я сделал их макет в STL.
▍ Шаг 16: код
Если вы уже работали с Arduino Nano, то наверняка знакомы с ресурсом Arduino.cc и не раз обращались за помощью к содержащимся там материалам.
Для тех же, кто впервые использует устройство с архитектурой Arduino, рекомендую сначала почитать этот раздел: Arduino IDE 2 Tutorials. В нём вы можете скачать Arduino IDE и ознакомиться с руководствами от самих разработчиков этой платформы. Там же есть инструкция по загрузке программы на устройство.
Ниже я приложил ссылку на скачивание скетча Tims_Electronic_Pantograph.ino, который нужно будет поместить в каталог с тем же названием, но без .ino.
▍ Шаг 17: калибровка [режим DEBUG]
Дополнительные фото
Калибруется пантограф в несколько шагов.
Сначала загружаем код на микроконтроллер в режиме DEBUG. Для этого нужно раскомментировать строку 29
#define DEBUG
.#define DEBUG // Активирует отладку с помощью последовательного вывода. (закомментируйте для отключения DEBUG).
На этом же этапе нужно установить значения
ANGLE_BIOS_01
и ANGLE_BIOS_02
на 0
.#define ANGLE_BIOS_01 1.4107 // Коррекция угла в точке калибровки после коррекции Nano.
#define ANGLE_BIOS_02 1.5719 // Коррекция угла в точке калибровки после коррекции Nano.
Проверьте правильность кода и загрузите его на Nano. Запустите Serial Monitor в Arduino IDE. Показания датчиков должны отправляться на Serial Monitor. Также в верхнем правом углу дисплея должна отображаться надпись DEBUG.
▍ Шаг 18: калибровка [первый прогон]
Дополнительные фото
При снятии показаний перемещайте плечи полностью до крайних точек. Если значения окажутся обратными, то есть вместо малых большие, значит, вы перепутали направление магнитов.
Малое значение датчика 1 при величине угла 45°.
Переместите первое плечо вправо до упора и введите полученное значение в строку
#define CAL_HALL_45D_01
(замените 232).#define CAL_HALL_45D_01 232 // Малое значение датчика 1 при величине угла 45°. Переместить первое плечо вправо до упора.
Большое значение датчика 1 при величине угла 135°.
Переместите первое плечо вниз-влево до упора и введите зарегистрированное значение в строку #define CAL_HALL_135D_01 (замените 835)
#define CAL_HALL_135D_01 835 // Большое значение датчика 1 при величине угла 135С. Переместить первое плечо влево-вниз до упора.
Малое значение датчика 1 при величине угла 45°.
Отведите второе плечо до упора вправо и введите зарегистрированное значение в строку
#define CAL_HALL_45D_02
(замените 258).#define CAL_HALL_45D_02 258 // Малое значение датчика 2 при величине угла 45°. Отвести второе плечо до упора вправо.
▍ Большое значение датчика 2 при величине угла 135°.
Сдвиньте второе плечо к первому влево до упора и введите полученное значение в строку
#define CAL_HALL_135D_02
(замените 825).#define CAL_HALL_135D_02 825 // Большое значение датчика 2 при величине угла 135°. Сдвинуть второе плечо до упора к первому.
Важно
После изменения значений, прежде чем переходить к следующем шагу, загрузите код на микроконтроллер ещё раз.
▍ Шаг 19: Калибровка [второй прогон]
Дополнительное фото
Теперь можно использовать значения, которые Nano вычисляет для положений 0° и 180°.
Малое значение для Sensor 1 Calculated при величине угла 0°.
Введите в строку
#define CAL_HALL_0D_01
значение, показанное в графе Sensor 1 Calculated 0 value: 113.36. У вас будет другая величина (замените 107).#define CAL_HALL_0D_01 107 // Значение, вычисленное Nano.
Большое значение Sensor 1 Calculated при величине угла 180°.
Введите в строку
#define CAL_HALL_180D_0
1 значение, показанное в графе Sensor 1 Calculated 180 value: 957.64. У вас будет своя величина (замените 690).#define CAL_HALL_180D_01 690 // Значение, вычисленное Nano.
Малое значение Sensor 2 Calculated при величине угла 0°.
Введите в строку
#define CAL_HALL_0D_01
значение, показанное в графе Sensor 2 Calculated 0 value: 140.57. У вас будет другая величина (замените 140).#define CAL_HALL_0D_02 140 // Значение, вычисленное Nano.
Большое значение Sensor 2 Calculated при величине угла 180°.
Введите в строку
#define CAL_HALL_180D_01
значение, показанное в графе Sensor 2 Calculated 180 value: 942.43. У вас будет другая величина (замените 942).#define CAL_HALL_180D_02 942 // Значение, вычисленное Nano.
Важно
После изменения значений, прежде чем переходить далее, заново загрузите код на микроконтроллер.
▍ Шаг 20: калибровка [третий этап]
Дополнительное фото
Для этого штифт необходимо расположить над калибровочным крестиком, отмеченным на доске. В таком положении плечи должны оказаться под углом 90°.
Вычисленные значения углов
В Serial Monitor оба
Angle Values
: Hall_Angle_01
и Hall_Angle_02
должны равняться 90
. Если это не так, значит ANGLE_BIOS_01
и ANGLE_BIOS_02
необходимо изменить на значение, прибавление которого приведёт к получению 90. Для этого достаточно просто вычесть из 90 значение, указанное в Serial Monitor. Если получается отрицательная величина, значит — в коде пишется отрицательное значение.Например:
- Serial Monitor показывает 90.245.
- 90 — 90.245 = -0.245
#define ANGLE_BIOS_01 -0.245 // Коррекция угла в точке калибровки после коррекции Nano.
То же самое проделываем для
Angle 2
. Теперь всё должно быть в порядке.▍ Шаг 21: калибровка [завершение]
После завершения калибровки необходимо перевести Arduino в рабочий режим, так как теперь нам нужно отправлять информацию о состоянии штифта через последовательный кабель. Если использовать для отправки данных обычный текст, то получится слишком долго, поэтому мы будем отправлять их в виде байтов.
Закомментируйте в коде
DEBUG
.//#define DEBUG // Активирует отладку с помощью последовательного вывода (закомментируйте для отключения DEBUG).
Загрузите код на Arduino.
Надпись DEBUG в верхнем правом углу дисплея должна исчезнуть, а Serial Monitor будет получать информацию, похожую на мусор.
▍ Шаг 22: почему последовательный порт отправляет мусор
Этот раздел для тех, кто ещё мало знаком с последовательной передачей данных.
Когда вы отправляете что-то через последовательный порт, данные уходят в виде байтов. Байт хранит 8-битное беззнаковое число от 0 до 255. При этом важно то, как вы эти числа интерпретируете.
Если в процессе написания кода вы присвоите число как
char
, то оно будет рассматриваться в качестве символа ASCII. Если же присвоить его как byte
, то оно будет расцениваться как число.Символами ASCII являются буквы, числа, символы, фигуры и функции, представленные кодом, который мы используем при вводе в компьютер.
Если заглянуть в таблицу стандарта ASCII (Американский стандартный код для обмена информацией), то мы увидим, что все символы имеют свои коды. Эта таблица доходит только до 127, последующие числа находятся в так называемом расширенном наборе символов, который может варьироваться в зависимости от страны/языка.
В Arduino используются только стандартные 127 символов. Так что, если мы хотим передать X=50, Y=120, Pen=Up, то отправляем:
Serial.prinln("X=50, Y=120, Pen=Up");
В действительности этот код, производя сопоставление с таблицей ASCII, отправляет следующую комбинацию чисел:
120, 61, 53, 48, 44, 33, 89, 61, 49, 50, 48, 44, 32, 80, 101, 110, 61, 85, 112, 13, 10
.В компьютерном понимании это много байтов (21), на отправку которых уходит немало времени. По этой же причине написание в коде Arduino текста для вывода требует много памяти. Если же воспользоваться простыми правилами, то можно сократить наше сообщение до 9 байт.
Правило 1:
Если нам известно, что мы отправляем, то известно и то, что мы получаем. Звучит неплохо :)
Что здесь нужно помнить:
- отправлять можно только байты, каждый из которых хранит 8-битное беззнаковое число от 0 до 255;
- нельзя отправлять отрицательные числа и числа больше 255;
- нельзя использовать дроби и десятичные величины.
Что нам нужно отправлять:
- сообщение о том, опущен или поднят штифт для обводки. Это просто – достаточно одного бита, 0 или 1.
- положение в направлении X. Размер нашей рабочей области в направлении X равен 240, значит, тут проблем нет;
- положение в направлении Y. Размер нашей рабочей области в этом направлении равен 190, тоже всё нормально;
Получается всего 3 байта, но я говорил о 9, почему же?
Просто я хочу, чтобы значение в направлениях X и Y имело три десятичных знака, и нам нужен способ превратить такое число в целое. Для этого достаточно умножить его на 1000.
Стоп, но тогда у нас получится уже больше 255. Значит, мы используем для X и Y по 3 байта, которые дадут нам 24-битное беззнаковое число, охватывающее диапазон от 0 до 16777215.
Таким образом, мы пришли к 7 байтам. Но нам также потребуется отправлять сообщение о завершении текущего блока информации. Если бы мы использовали стандартный набор от 0 до 127, то можно было бы обойтись одним байтом, символом из расширенного набора ASCII. Но у нас не тот случай — отправляемые нами байты могут быть представлены любым значением от 0 до 255.
Поэтому мы используем 2 байта, которые будут идти один за другим. Порядок такой: сначала возврат каретки (CR), затем перевод строки (LF), то есть
13
и 10
. Значит, если появляется 13
в сопровождении 10
, мы понимаем, что это конец текущего фрагмента данных.При этом существует ничтожный шанс, что комбинация
13
и 10
возникнет посреди данных, поэтому при получении мы дополнительно делаем подсчёт, начиная с последней комбинации 13
и 10
.Вот у нас и получилось 9 байт. Если однажды мы соберёмся масштабировать пантограф, то можно дойти вплоть до размера 16776 с тремя десятичными знаками.
Как я говорил, первый байт используется для обозначения верхнего или нижнего положения штифта с помощью всего одного бита, так что в нём можно задействовать ещё 7 бит.
Вторым битом мы сообщаем об отрицательном значении X, а третьим об отрицательном Y.
Кому будет интересно разобраться в деталях – я оставил в коде все соответствующие комментарии.
В итоге, если реверсировать получаемый через Serial Port мусор, мы увидим необходимую нам информацию.
Именно это и происходит в написанном мной приложении.
▍ Шаг 23: Программное обеспечение
Я создал специальное приложение для визуального представления данных, регистрируемых моим пантографом. Установочные файлы размещены на Google Drive.
Не пытайтесь запустить установку из архива. Сначала распакуйте его по желаемому пути и выполните setup.exe оттуда. Программу я создавал с использованием техники It’s About Trust, так что перед скачиванием и установкой рекомендую с ней ознакомиться.
▍ Шаг 24: пробное копирование
- установите и запустите программу Tim’s Electronic Pantograph;
- подключите пантограф к USB-порту компьютера;
- в программе выберите USB Port, к которому подключили устройство, установите Baud Rate на 115200 и кликните подключиться.
Всё должно заработать.
Положите на рабочую область любую картинку, которую хотите скопировать, и зафиксируйте её.
Для переключения режимов «Pen Up» и «Pen Down» нажимайте на штифт. Лучше всего установить программу в “Auto mode”.
Максимальный масштаб переноса изображения 3 к 1.
Параметр «Line Length» определяет, как часто отрисовывается линия.
Окно “Data” будет выводить G-Code, который можно использовать на плоттере для воспроизведения изображения с экрана.
После нажатия на штифт для перехода в режим «Pen Down» начинайте обводить изображение – на экране должно отображаться то, что вы обводите.
▍ Шаг 25: G-Code
Имейте в виду, если вы будете копировать при большем масштабе, то плоттер также будет печатать увеличенное изображение. G-Code записывает только команды
G00
(перейти к) и G01
(печать). Если вам нужна какая-то особая команда «Pen Up» или «Pen Down», потребуется их реализовать самостоятельно. То же касается ваших команд инициализации.