Как сделать самому Луноход
Если в детстве у тебя не было велосипеда, а теперь у тебя Бентли,
то всё равно в детстве у тебя велосипеда не было.
Так уж получилось, что в моём детстве не было Лунохода. А тут ещё и ребёнок родился. В общем, я подумал, и решил сделать игрушку нам обоим.
Создавать точную копию не хотелось, да и не умею я печатать корпуса дома, поэтому решил ограничиться воссозданием похожей функциональности. Кроме того, мне показалось негуманным вводить «программу» движения по памяти и не понимать, что именно получилось ввести, поэтому добавил дисплей.
Версия 1
Под рукой было недорогое шасси с Ebay и Arduino Uno.
Для управления моторчиками я взял PWM Servo Shield и на макетной плате спаял L293D + PCF8574:
Для считывания с клавиатуры взял PCF8574 и горсть диодов:
Саму клавиатуру сделал печатной платой:
Дабы клавиатура не разваливалась в руках, закрепил сверху накладку. Её пришлось заказать у «фрезеровщиков» :)
Для отображения программы используется обычный дисплей 20 на 4 символа. Да, тоже через PCF8574;)
Для питания сначала использовал 4 батарейки, но они слишком быстро садились, и я заменил их на пару аккумуляторов 18650:
Для зарядки использовал модули TP4056, которые присоединил через реле к аккумуляторам, правда, не очень успешно.
Быстрее всего получилось написать прошивку. К сожалению, оказалось, что библиотека I2C LCD имеет лицензию GPL, и код отправился в корзину. Примерно тогда же я понял, что Arduino Uno не самый удачный вариант, и что горсть PCF8574 очень неудобно паять.
И я решил начать сначала.
Версия 2
Учёл предыдущий опыт, который подсказывал, что есть несколько проблем:
- Шасси с Ebay сделано из оргстекла и очень (!) хрупкое (я перетянул винт крепления редукторов и крепление просто сломалось).
- На шасси много крепёжных отверстий, но ни одного подходящего.
- Вместе с шасси идут редукторы 1:48, но они слишком шустрые.
- И вообще шасси маловато.
- У Arduino Uno мало «ног».
- Нет звукового модуля (а он нужен для команды «огонь»).
- Про Li-ion в интернете пишут страшилки, давать ребёнку потенциально опасное устройство не хочется.
В результате купил:
Кроме того:
Achtung! Warning! Attention! Данные ссылки приведены исключительно для иллюстрации и упрощения дальнейшего поиска деталек. Я не могу гарантировать, что продавец внезапно не поменяет лот на какой-то другой, не изменит цену, количество и т.п.
Железо
Клавиатуру я перенёс на печатную плату (пожалуй, это единственный сложный для повторения элемент). Накладку на клавиатуру мне отфрезеровали на заказ.
Оставался вопрос: из чего же сделать шасси? Пластика подходящего не было, металл тяжело обрабатывать… А если взять фанеру? «Но это же не эстетично!», подумал было я. Но когда через полчаса я получил нормальное шасси, то изменил мнение. Шасси было не очень презентабельно и отправилось в корзину, но скорость обработки так понравилась, что я решил и дальше использовать фанеру.
Правда, второй лист я начал пилить только после того, как нарисовал примерный план:
Для крепления моторов отрезал кусок алюминиевого уголка и высверлил:
Платы закрепил на шестигранных стойках и соединил между собой шлейфами.
(здесь же можно заметить стабилизатор на 5В и немного контактов питания).
Проводов питания оказалось многовато, поэтому я сделал из stripboard плату питания (подробности здесь). Подозреваю, что можно взять обычный sensor shield, у которого выводов питания с избытком.
Так как расширителей ввода-вывода больше не было, клавиатуру пришлось переделать (исходники). Я перенёс на неё диоды и резисторы подтяжки:
В качестве датчика оборотов использовал щелевую оптопару и шестерню (раскрасил её перманентным маркером):
В качестве третьего колеса использовал шарик:
Изначально там была опора в виде колёсика на коромысле, которая шла вместе с шасси. Однако при изменении направления движения колёсико начинало разворачиваться в самый неожиданный момент и тележку бросало в сторону.
Схема соединений
Лучше всего посмотреть файлы consts.h и lcd.ino, они содержат самую актуальную информацию. Соединения, как они есть сейчас, выглядят так:
Картинка кликабельна.
Прошивка
Прошивка, по сути своей, представляет обыкновенную программу, написанную в Arduino IDE. Режимов работы два: редактирование и выполнение. В процессе редактирования с клавиатуры принимается команда + количество повторений. Всё это упаковывается в 16-битное значение и складывается в массив в RAM. При выполнении программы из массива выгребаются значения и выполняются. Выполнение одного шага (в очень упрощённой форме) выглядит так:
если (уже работаем)
проверить счётчик пройденного пути
если (счётчик >= требуемая дистанция),
подождать немного
перейти к следующей команде
иначе
инкремент счётчика
иначе
выключить двигатели
взять очередную команду
включить двигатели
требуемая дистанция = константа*число повторений из команды
Пройденный путь определяется по количеству импульсов с оптопары, которая проверяется в прерывании таймера.
Единственное исключение — проигрывание звука. Если встречается команда «выстрел», то запускается простейший цикл for
, который выгребает значения из wav-файла (он прошит в той же flash-памяти, что и программа) и выдаёт их на ЦАП R-2R. Когда значения заканчиваются, происходит возврат к обычному процессу выполнения программы.
К сожалению реальный мир несколько отличается от программной модели, на которую рассчитана прошивка, поэтому я добавил некоторое количество задержек, которые позволяют учесть инерцию шасси.
Я сознательно поставил MIT-лицензию. В моём понимании прошивку с такой лицензией можно свободно использовать как угодно, без необходимости публиковать дальнейшие изменения (не хочу никого ни к чему принуждать).
Руководство по эксплуатации ;)
Клавиатура слегка отличается от «классического» Лунохода:
- Слева расположен блок команд (зелёные — куда ехать, красная — пауза, снизу — Out, огонь, повтор).
- В середине — цифры с количеством повторений.
- Справа 8 клавиш управления (чёрная — удалить последнюю команду, красная — удалить всё, зелёная — запуск, жёлтая — запуск последней команды, синие — тест, серые — запасные).
Ещё раз табличкой:
На картинке | Перевод | Смысл |
Fwd | Ехать вперёд | |
Bwd | Ехать назад | |
Left | Повернуть налево | |
Right | Повернуть направо | |
Pause | Замереть | |
Out | Не реализовано, оставлено на будущее | Сделал как в Луноходе |
Fire | Огонь | Издаёт звук «пиу!» |
Loop | Цикл | Повторить несколько предыдущих команд один раз |
0–9 | Число шагов | Максимум 20 |
Bsp | Удалить последнюю команду | |
Del | Удалить всю программу | Требуется подтверждение кнопкой Go! |
T1, T2 | Тест | Запустить тестовую программу |
Check | Выполнить последний шаг | |
Go! | Выполнить все шаги |
Программа вводится поочерёдным нажатием «Команда» и «Цифра». Потом жмём зелёный «Запуск» и смотрим на результат. Удаление происходит по нажатию красной кнопки, но не сразу: надо подтвердить своё решение нажатием зелёной кнопки «Запуск». При выключении питания программа удаляется.
Команда «Повтор» содержит один параметр: сколько шагов нужно повторить [один раз]. Пример: Fwd1, Pause1, Bwd1, Loop3; в результате команды Fwd1, Pause1, Bwd1 будут выполнены два раза. Первый раз потому, что они есть в программе, второй — потому что так указано в команде «Цикл».
На всякий случай контролируется заряд аккумулятора. Если он слишком мал, то выводится предупреждение и игрушка не едет.
GUI
Держать в голове всю программу тяжко, поэтому я прикрутил простейший индикатор, на котором дублируется вводимая информация.
После запуска отображается приглашение:
При вводе команды в левом верхнем углу отображается значок команды и количество повторений:
Если введено больше одной команды, снизу будет список (по сути, программа), а сверху всё так же будет отображаться вводимая команда:
Почему получилось именно так
Игрушка создавалась из того, что было под руками или легко достать. Отдельно хочется сказать про Arduino. Она выбрана по нескольким причинам:
- У неё подходящее количество выводов, а их надо много (43):
- 6 для управления моторами;
- 8+4 для клавиатуры;
- 11 для LCD;
- 3 для ЦАП;
- 8 для УЗ-датчиков;
- 2 для датчиков оборотов;
- 1 для замера напряжения на аккумуляторе.
- Я знаком с этой платформой.
- Она прошивается в один клик.
- От микроконтроллера не требуется каких-то гигантских скоростей или объёмов памяти.
- И особой экономичности тоже не требуется, т.к. 90% тока потребляют моторы.
Что можно улучшить
Шасси. При резком старте колёса «шлифуют» и игрушка сбивается с курса. Можно попробовать сделать шестиколёсное шасси, или вообще гусеничное (на Aliexpress есть, но я пока не пробовал).
GUI. Сейчас на индикатор выводится только минимальный объём информации, и делается это самым простым способом.
Код. Пулитцера я точно не получу.
Звук. Есть дешевые и очень мелкие mp3-плееры. Можно смело выкинуть ЦАП R-2R и заменить его на готовый плеер.
Резервные кнопки. Можно сделать запись готовой программы в EEPROM, чтобы она не терялась при выключении питания. Реализация может быть как в магнитолах: при длинном нажатии программу сохраняем, при коротком — запускаем.
Кнопка Out. На данный момент не реализована. Можно прикрутить что-то типа реле/сервы к одному из выводов Arduino.
Благодарности
- Ребёнку, который мотивировал меня всё это время.
- Жене, которая терпеливо ждала, пока я наиграюсь, и помогала с Corel Draw!
- Сергею Дудникову, который отрисовал накладку на клавиатуру.
- Андрею Шишкову, который эту самую накладку фрезеровал.
- Антону, который сделал мне отличный mp3 со звуком «пиу!».
- hudbrog, за идею реализовать ПИД-регулятор!
- Чатику самодельщиков, которые меня морально поддерживали и вынужденно смотрели на промежуточные итоги работы ;)
Неудачные дубли
Мне нравятся фильмы с Джеки Чаном, потому что в конце есть нарезка неудачных дублей. У меня без них тоже не обошлось. Больше всего меня удивил тот факт, кто круглое сверло с двумя канавками даёт треугольное отверстие;)