Если в детстве у тебя не было велосипеда, а теперь у тебя Бентли,
то всё равно в детстве у тебя велосипеда не было.
Так уж получилось, что в моём детстве не было Лунохода. А тут ещё и ребёнок родился. В общем, я подумал, и решил сделать игрушку нам обоим.
Создавать точную копию не хотелось, да и не умею я печатать корпуса дома, поэтому решил ограничиться воссозданием похожей функциональности. Кроме того, мне показалось негуманным вводить «программу» движения по памяти и не понимать, что именно получилось ввести, поэтому добавил дисплей.
![](https://habrastorage.org/r/w780q1/webt/ih/pq/ns/ihpqnsayvywyqgoltv4mwchnqbc.jpeg)
Под рукой было недорогое шасси с Ebay и Arduino Uno.
![](https://habrastorage.org/r/w780q1/webt/oa/ks/bs/oaksbszaetv0pmdq3mjl4iouhlc.jpeg)
Для управления моторчиками я взял PWM Servo Shield и на макетной плате спаял L293D + PCF8574:
![](https://habrastorage.org/r/w780q1/webt/zn/_k/pk/zn_kpktlf5vzumkw2lypgzcn-w8.jpeg)
Для считывания с клавиатуры взял PCF8574 и горсть диодов:
![](https://habrastorage.org/r/w780q1/webt/vl/3m/ce/vl3mcexy-af8o2qftryu1ycbatc.jpeg)
Саму клавиатуру сделал печатной платой:
![](https://habrastorage.org/r/w780q1/webt/t9/pq/a_/t9pqa_mbs80phb7fvym68cfr7vg.jpeg)
Дабы клавиатура не разваливалась в руках, закрепил сверху накладку. Её пришлось заказать у «фрезеровщиков» :)
![](https://habrastorage.org/r/w780q1/webt/aa/ew/al/aaewalxzkgyoaza8hbbtczi9qzi.jpeg)
Для отображения программы используется обычный дисплей 20 на 4 символа. Да, тоже через PCF8574 ;)
Для питания сначала использовал 4 батарейки, но они слишком быстро садились, и я заменил их на пару аккумуляторов 18650:
![](https://habrastorage.org/r/w780q1/webt/no/z3/nj/noz3njtz2sggvjjhwsml3awkige.jpeg)
Для зарядки использовал модули TP4056, которые присоединил через реле к аккумуляторам, правда, не очень успешно.
Быстрее всего получилось написать прошивку. К сожалению, оказалось, что библиотека I2C LCD имеет лицензию GPL, и код отправился в корзину. Примерно тогда же я понял, что Arduino Uno не самый удачный вариант, и что горсть PCF8574 очень неудобно паять.
И я решил начать сначала.
![](https://habrastorage.org/r/w780q1/webt/n-/r7/-b/n-r7-beqhk6ahhkgimg8jnblkaa.jpeg)
Учёл предыдущий опыт, который подсказывал, что есть несколько проблем:
В результате купил:
Кроме того:
Achtung! Warning! Attention! Данные ссылки приведены исключительно для иллюстрации и упрощения дальнейшего поиска деталек. Я не могу гарантировать, что продавец внезапно не поменяет лот на какой-то другой, не изменит цену, количество и т.п.
Клавиатуру я перенёс на печатную плату (пожалуй, это единственный сложный для повторения элемент). Накладку на клавиатуру мне отфрезеровали на заказ.
Оставался вопрос: из чего же сделать шасси? Пластика подходящего не было, металл тяжело обрабатывать… А если взять фанеру? «Но это же не эстетично!», подумал было я. Но когда через полчаса я получил нормальное шасси, то изменил мнение. Шасси было не очень презентабельно и отправилось в корзину, но скорость обработки так понравилась, что я решил и дальше использовать фанеру.
Правда, второй лист я начал пилить только после того, как нарисовал примерный план:
![](https://habrastorage.org/r/w780q1/webt/i2/04/jf/i204jfektudoeouou1eictzhlou.jpeg)
Для крепления моторов отрезал кусок алюминиевого уголка и высверлил:
![](https://habrastorage.org/r/w780q1/webt/yc/9l/mf/yc9lmfuxmzuwyzk-0f6va4kltme.jpeg)
Платы закрепил на шестигранных стойках и соединил между собой шлейфами.
![](https://habrastorage.org/r/w780q1/webt/8z/cy/lr/8zcylrr4a2ze3batxdor64eo8sg.jpeg)
(здесь же можно заметить стабилизатор на 5В и немного контактов питания).
Проводов питания оказалось многовато, поэтому я сделал из stripboard плату питания (подробности здесь). Подозреваю, что можно взять обычный sensor shield, у которого выводов питания с избытком.
![](https://habrastorage.org/r/w780q1/webt/ck/ub/x2/ckubx2ow7a7ruepvhp_9ximpbxs.jpeg)
Так как расширителей ввода-вывода больше не было, клавиатуру пришлось переделать (исходники). Я перенёс на неё диоды и резисторы подтяжки:
![](https://habrastorage.org/r/w1560/webt/_g/ok/bl/_gokblns0ghrh8bpioognk5qqsy.png)
![](https://habrastorage.org/r/w1560/webt/x7/bq/4e/x7bq4erwndaruwajukdzx-zmjok.png)
В качестве датчика оборотов использовал щелевую оптопару и шестерню (раскрасил её перманентным маркером):
![](https://habrastorage.org/r/w780q1/webt/oy/j4/bi/oyj4bisufg1waa_n2-g2lmkvg7e.jpeg)
В качестве третьего колеса использовал шарик:
![](https://habrastorage.org/r/w780q1/webt/v8/do/dz/v8dodzdbt2t_ypmcxvt7tbtayfm.jpeg)
Изначально там была опора в виде колёсика на коромысле, которая шла вместе с шасси. Однако при изменении направления движения колёсико начинало разворачиваться в самый неожиданный момент и тележку бросало в сторону.
Лучше всего посмотреть файлы consts.h и lcd.ino, они содержат самую актуальную информацию. Соединения, как они есть сейчас, выглядят так:
![](https://habrastorage.org/r/w1560/webt/9-/x5/fn/9-x5fn6xo7a0stgsm2kz8spipwg.png)
Картинка кликабельна.
Прошивка, по сути своей, представляет обыкновенную программу, написанную в Arduino IDE. Режимов работы два: редактирование и выполнение. В процессе редактирования с клавиатуры принимается команда + количество повторений. Всё это упаковывается в 16-битное значение и складывается в массив в RAM. При выполнении программы из массива выгребаются значения и выполняются. Выполнение одного шага (в очень упрощённой форме) выглядит так:
Пройденный путь определяется по количеству импульсов с оптопары, которая проверяется в прерывании таймера.
Единственное исключение — проигрывание звука. Если встречается команда «выстрел», то запускается простейший цикл
К сожалению реальный мир несколько отличается от программной модели, на которую рассчитана прошивка, поэтому я добавил некоторое количество задержек, которые позволяют учесть инерцию шасси.
Я сознательно поставил MIT-лицензию. В моём понимании прошивку с такой лицензией можно свободно использовать как угодно, без необходимости публиковать дальнейшие изменения (не хочу никого ни к чему принуждать).
Клавиатура слегка отличается от «классического» Лунохода:
![](https://habrastorage.org/r/w780q1/webt/4u/j5/vn/4uj5vnruc0uqqatdl4vdhyzmo5q.jpeg)
Ещё раз табличкой:
Программа вводится поочерёдным нажатием «Команда» и «Цифра». Потом жмём зелёный «Запуск» и смотрим на результат. Удаление происходит по нажатию красной кнопки, но не сразу: надо подтвердить своё решение нажатием зелёной кнопки «Запуск». При выключении питания программа удаляется.
Команда «Повтор» содержит один параметр: сколько шагов нужно повторить [один раз]. Пример: Fwd1, Pause1, Bwd1, Loop3; в результате команды Fwd1, Pause1, Bwd1 будут выполнены два раза. Первый раз потому, что они есть в программе, второй — потому что так указано в команде «Цикл».
На всякий случай контролируется заряд аккумулятора. Если он слишком мал, то выводится предупреждение и игрушка не едет.
Держать в голове всю программу тяжко, поэтому я прикрутил простейший индикатор, на котором дублируется вводимая информация.
После запуска отображается приглашение:
![](https://habrastorage.org/r/w780q1/webt/s9/fa/vm/s9favm1fnid9wcecjjr5ftreucs.jpeg)
При вводе команды в левом верхнем углу отображается значок команды и количество повторений:
![](https://habrastorage.org/r/w780q1/webt/ap/49/uo/ap49uo6kiynrphfa_3dq6x4t1pu.jpeg)
Если введено больше одной команды, снизу будет список (по сути, программа), а сверху всё так же будет отображаться вводимая команда:
![](https://habrastorage.org/r/w780q1/webt/ar/ee/qx/areeqxmd-29tpcrlpdr912ynqrq.jpeg)
Игрушка создавалась из того, что было под руками или легко достать. Отдельно хочется сказать про Arduino. Она выбрана по нескольким причинам:
Шасси. При резком старте колёса «шлифуют» и игрушка сбивается с курса. Можно попробовать сделать шестиколёсное шасси, или вообще гусеничное (на Aliexpress есть, но я пока не пробовал).
GUI. Сейчас на индикатор выводится только минимальный объём информации, и делается это самым простым способом.
Код. Пулитцера я точно не получу.
Звук. Есть дешевые и очень мелкие mp3-плееры. Можно смело выкинуть ЦАП R-2R и заменить его на готовый плеер.
Резервные кнопки. Можно сделать запись готовой программы в EEPROM, чтобы она не терялась при выключении питания. Реализация может быть как в магнитолах: при длинном нажатии программу сохраняем, при коротком — запускаем.
Кнопка Out. На данный момент не реализована. Можно прикрутить что-то типа реле/сервы к одному из выводов Arduino.
Мне нравятся фильмы с Джеки Чаном, потому что в конце есть нарезка неудачных дублей. У меня без них тоже не обошлось. Больше всего меня удивил тот факт, кто круглое сверло с двумя канавками даёт треугольное отверстие ;)
то всё равно в детстве у тебя велосипеда не было.
Так уж получилось, что в моём детстве не было Лунохода. А тут ещё и ребёнок родился. В общем, я подумал, и решил сделать игрушку нам обоим.
Создавать точную копию не хотелось, да и не умею я печатать корпуса дома, поэтому решил ограничиться воссозданием похожей функциональности. Кроме того, мне показалось негуманным вводить «программу» движения по памяти и не понимать, что именно получилось ввести, поэтому добавил дисплей.
Версия 1
![](https://habrastorage.org/webt/ih/pq/ns/ihpqnsayvywyqgoltv4mwchnqbc.jpeg)
Под рукой было недорогое шасси с Ebay и Arduino Uno.
![](https://habrastorage.org/webt/oa/ks/bs/oaksbszaetv0pmdq3mjl4iouhlc.jpeg)
Для управления моторчиками я взял PWM Servo Shield и на макетной плате спаял L293D + PCF8574:
![](https://habrastorage.org/webt/zn/_k/pk/zn_kpktlf5vzumkw2lypgzcn-w8.jpeg)
Для считывания с клавиатуры взял PCF8574 и горсть диодов:
![](https://habrastorage.org/webt/vl/3m/ce/vl3mcexy-af8o2qftryu1ycbatc.jpeg)
Саму клавиатуру сделал печатной платой:
![](https://habrastorage.org/webt/t9/pq/a_/t9pqa_mbs80phb7fvym68cfr7vg.jpeg)
Дабы клавиатура не разваливалась в руках, закрепил сверху накладку. Её пришлось заказать у «фрезеровщиков» :)
![](https://habrastorage.org/webt/aa/ew/al/aaewalxzkgyoaza8hbbtczi9qzi.jpeg)
Для отображения программы используется обычный дисплей 20 на 4 символа. Да, тоже через PCF8574 ;)
Для питания сначала использовал 4 батарейки, но они слишком быстро садились, и я заменил их на пару аккумуляторов 18650:
![](https://habrastorage.org/webt/no/z3/nj/noz3njtz2sggvjjhwsml3awkige.jpeg)
Для зарядки использовал модули TP4056, которые присоединил через реле к аккумуляторам, правда, не очень успешно.
Быстрее всего получилось написать прошивку. К сожалению, оказалось, что библиотека I2C LCD имеет лицензию GPL, и код отправился в корзину. Примерно тогда же я понял, что Arduino Uno не самый удачный вариант, и что горсть PCF8574 очень неудобно паять.
И я решил начать сначала.
Версия 2
![](https://habrastorage.org/webt/n-/r7/-b/n-r7-beqhk6ahhkgimg8jnblkaa.jpeg)
Учёл предыдущий опыт, который подсказывал, что есть несколько проблем:
- Шасси с Ebay сделано из оргстекла и очень (!) хрупкое (я перетянул винт крепления редукторов и крепление просто сломалось).
- На шасси много крепёжных отверстий, но ни одного подходящего.
- Вместе с шасси идут редукторы 1:48, но они слишком шустрые.
- И вообще шасси маловато.
- У Arduino Uno мало «ног».
- Нет звукового модуля (а он нужен для команды «огонь»).
- Про Li-ion в интернете пишут страшилки, давать ребёнку потенциально опасное устройство не хочется.
В результате купил:
- Редукторы 1:120.
- Моторы с двумя валами (в надежде установить потом ПИД-регулятор).
- Модуль L293.
- Arduino Mega.
- Много цветных шлейфов!
- Свинцово-кислотный аккумулятор на 6В (он не так быстро садится, отдаёт больший ток, и он тяжелый — колёса меньше «шлифуют»).
- УЗ-датчики в качестве датчиков препятствий.
- Третье колесо в виде шарика.
- Тактовые кнопки.
- Толкатель кнопки.
- Щелевой датчик.
Кроме того:
- Дисплей LCD 2004 (5В) остался от версии 1.
- Спаял ЦАП R-2R на монтажной плате (вот здесь есть схема в KiCAD и 3D-модель).
Achtung! Warning! Attention! Данные ссылки приведены исключительно для иллюстрации и упрощения дальнейшего поиска деталек. Я не могу гарантировать, что продавец внезапно не поменяет лот на какой-то другой, не изменит цену, количество и т.п.
Железо
Клавиатуру я перенёс на печатную плату (пожалуй, это единственный сложный для повторения элемент). Накладку на клавиатуру мне отфрезеровали на заказ.
Оставался вопрос: из чего же сделать шасси? Пластика подходящего не было, металл тяжело обрабатывать… А если взять фанеру? «Но это же не эстетично!», подумал было я. Но когда через полчаса я получил нормальное шасси, то изменил мнение. Шасси было не очень презентабельно и отправилось в корзину, но скорость обработки так понравилась, что я решил и дальше использовать фанеру.
Правда, второй лист я начал пилить только после того, как нарисовал примерный план:
![](https://habrastorage.org/webt/i2/04/jf/i204jfektudoeouou1eictzhlou.jpeg)
Для крепления моторов отрезал кусок алюминиевого уголка и высверлил:
![](https://habrastorage.org/webt/yc/9l/mf/yc9lmfuxmzuwyzk-0f6va4kltme.jpeg)
Платы закрепил на шестигранных стойках и соединил между собой шлейфами.
![](https://habrastorage.org/webt/8z/cy/lr/8zcylrr4a2ze3batxdor64eo8sg.jpeg)
(здесь же можно заметить стабилизатор на 5В и немного контактов питания).
Проводов питания оказалось многовато, поэтому я сделал из stripboard плату питания (подробности здесь). Подозреваю, что можно взять обычный sensor shield, у которого выводов питания с избытком.
![](https://habrastorage.org/webt/ck/ub/x2/ckubx2ow7a7ruepvhp_9ximpbxs.jpeg)
Так как расширителей ввода-вывода больше не было, клавиатуру пришлось переделать (исходники). Я перенёс на неё диоды и резисторы подтяжки:
![](https://habrastorage.org/webt/_g/ok/bl/_gokblns0ghrh8bpioognk5qqsy.png)
![](https://habrastorage.org/webt/x7/bq/4e/x7bq4erwndaruwajukdzx-zmjok.png)
В качестве датчика оборотов использовал щелевую оптопару и шестерню (раскрасил её перманентным маркером):
![](https://habrastorage.org/webt/oy/j4/bi/oyj4bisufg1waa_n2-g2lmkvg7e.jpeg)
В качестве третьего колеса использовал шарик:
![](https://habrastorage.org/webt/v8/do/dz/v8dodzdbt2t_ypmcxvt7tbtayfm.jpeg)
Изначально там была опора в виде колёсика на коромысле, которая шла вместе с шасси. Однако при изменении направления движения колёсико начинало разворачиваться в самый неожиданный момент и тележку бросало в сторону.
Схема соединений
Лучше всего посмотреть файлы consts.h и lcd.ino, они содержат самую актуальную информацию. Соединения, как они есть сейчас, выглядят так:
![](https://habrastorage.org/webt/9-/x5/fn/9-x5fn6xo7a0stgsm2kz8spipwg.png)
Картинка кликабельна.
Прошивка
Прошивка, по сути своей, представляет обыкновенную программу, написанную в Arduino IDE. Режимов работы два: редактирование и выполнение. В процессе редактирования с клавиатуры принимается команда + количество повторений. Всё это упаковывается в 16-битное значение и складывается в массив в RAM. При выполнении программы из массива выгребаются значения и выполняются. Выполнение одного шага (в очень упрощённой форме) выглядит так:
если (уже работаем)
проверить счётчик пройденного пути
если (счётчик >= требуемая дистанция),
подождать немного
перейти к следующей команде
иначе
инкремент счётчика
иначе
выключить двигатели
взять очередную команду
включить двигатели
требуемая дистанция = константа*число повторений из команды
Пройденный путь определяется по количеству импульсов с оптопары, которая проверяется в прерывании таймера.
Единственное исключение — проигрывание звука. Если встречается команда «выстрел», то запускается простейший цикл
for
, который выгребает значения из wav-файла (он прошит в той же flash-памяти, что и программа) и выдаёт их на ЦАП R-2R. Когда значения заканчиваются, происходит возврат к обычному процессу выполнения программы.К сожалению реальный мир несколько отличается от программной модели, на которую рассчитана прошивка, поэтому я добавил некоторое количество задержек, которые позволяют учесть инерцию шасси.
Я сознательно поставил MIT-лицензию. В моём понимании прошивку с такой лицензией можно свободно использовать как угодно, без необходимости публиковать дальнейшие изменения (не хочу никого ни к чему принуждать).
Руководство по эксплуатации ;)
Клавиатура слегка отличается от «классического» Лунохода:
![](https://habrastorage.org/webt/4u/j5/vn/4uj5vnruc0uqqatdl4vdhyzmo5q.jpeg)
- Слева расположен блок команд (зелёные — куда ехать, красная — пауза, снизу — 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
Держать в голове всю программу тяжко, поэтому я прикрутил простейший индикатор, на котором дублируется вводимая информация.
После запуска отображается приглашение:
![](https://habrastorage.org/webt/s9/fa/vm/s9favm1fnid9wcecjjr5ftreucs.jpeg)
При вводе команды в левом верхнем углу отображается значок команды и количество повторений:
![](https://habrastorage.org/webt/ap/49/uo/ap49uo6kiynrphfa_3dq6x4t1pu.jpeg)
Если введено больше одной команды, снизу будет список (по сути, программа), а сверху всё так же будет отображаться вводимая команда:
![](https://habrastorage.org/webt/ar/ee/qx/areeqxmd-29tpcrlpdr912ynqrq.jpeg)
Почему получилось именно так
Игрушка создавалась из того, что было под руками или легко достать. Отдельно хочется сказать про Arduino. Она выбрана по нескольким причинам:
- У неё подходящее количество выводов, а их надо много (43):
- 6 для управления моторами;
- 8+4 для клавиатуры;
- 11 для LCD;
- 3 для ЦАП;
- 8 для УЗ-датчиков;
- 2 для датчиков оборотов;
- 1 для замера напряжения на аккумуляторе.
- Я знаком с этой платформой.
- Она прошивается в один клик.
- От микроконтроллера не требуется каких-то гигантских скоростей или объёмов памяти.
- И особой экономичности тоже не требуется, т.к. 90 % тока потребляют моторы.
Что можно улучшить
Шасси. При резком старте колёса «шлифуют» и игрушка сбивается с курса. Можно попробовать сделать шестиколёсное шасси, или вообще гусеничное (на Aliexpress есть, но я пока не пробовал).
GUI. Сейчас на индикатор выводится только минимальный объём информации, и делается это самым простым способом.
Код. Пулитцера я точно не получу.
Звук. Есть дешевые и очень мелкие mp3-плееры. Можно смело выкинуть ЦАП R-2R и заменить его на готовый плеер.
Резервные кнопки. Можно сделать запись готовой программы в EEPROM, чтобы она не терялась при выключении питания. Реализация может быть как в магнитолах: при длинном нажатии программу сохраняем, при коротком — запускаем.
Кнопка Out. На данный момент не реализована. Можно прикрутить что-то типа реле/сервы к одному из выводов Arduino.
Благодарности
- Ребёнку, который мотивировал меня всё это время.
- Жене, которая терпеливо ждала, пока я наиграюсь, и помогала с Corel Draw!
- Сергею Дудникову, который отрисовал накладку на клавиатуру.
- Андрею Шишкову, который эту самую накладку фрезеровал.
- Антону, который сделал мне отличный mp3 со звуком «пиу!».
- hudbrog, за идею реализовать ПИД-регулятор!
- Чатику самодельщиков, которые меня морально поддерживали и вынужденно смотрели на промежуточные итоги работы ;)
Неудачные дубли
Мне нравятся фильмы с Джеки Чаном, потому что в конце есть нарезка неудачных дублей. У меня без них тоже не обошлось. Больше всего меня удивил тот факт, кто круглое сверло с двумя канавками даёт треугольное отверстие ;)