Робот-бармен своими руками — когда лень на корпоративе наливать коктейли вручную

Началось всё в начале декабря, когда меня пригласили на корпоратив в компанию, откуда уволился месяцем ранее. И так как в компании работают очень инициативные и неординарные люди, то и корпоратив придумали с достаточным количеством активностей и интересностей.

Среди обязательного условия было: наличие бара с коктейлями и барменом, который бы мог угощать гостей коктейлями.

Робот-бармен своими руками — когда лень на корпоративе наливать коктейли вручную

Как ожидалось, желающих примерить на себе обязанность бармена не нашлось, и я взял на себя все это. Этой же ночью созрел ленивый план «Как бы за меня кто-то наливал коктейли», так как я человек из колхоза, и в моем понимании корпоратив — это когда ты употребляешь сам и на следующий день бывает стыдно :D

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

Робот-бармен своими руками — когда лень на корпоративе наливать коктейли вручную

Но была проблема — у меня совсем нет опыта в разработке устройств на Arduino... Да и C/C++ я знаю только поверхностно, что-то стабильно работающее в короткий срок не смогу разработать.

Так как я неплохо знаю ECMAScript (JavaScript), решил погуглить на эту тему. Нашёл быстро то, что позволило бы мне быстро разработать эту разливайку — Espruino! Ещё немного погуглив, нашёл плату IskraJS, которая реализована в форм-факторе Arduino и совместима с ее шилдами. То что нужно!

Робот-бармен своими руками — когда лень на корпоративе наливать коктейли вручную

Так как в голове уже были наброски устройства, я приступил к формированию заказа. Я предполагал, что мне для всего этого необходимо:

В одном магазине всего этого не нашлось, поэтому пришлось дробить заказ между двумя магазинами. К слову, в «Амперку» мне пришлось ездить ещё два раза, чтобы поменять бракованные устройства. Неприятно, конечно, но ребята всё без проблем заменили либо вернули деньги и отправили в «ЧипДип».

Часть заказа​
Часть заказа​

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

​Собрал «на коленке»
​Собрал «на коленке»

Замечательно! Пытаемся установить среду разработки, подключиться к Iskra JS и подёргать клапанами и насосом. Но! Ноутбук не видит устройство… Сначала думаем, что мертвый USB-кабель, пытаемся подключить ещё через два провода, которые остались от Android-телефонов. Не работает…

Следующая мысль: USB-хаб, который в power bank чем-то не устраивает какую-то из сторон (Macbook, Iskra JS). Не проблема! Идём в ближайший re: Store, прихватив с собой контроллер, провода, ноутбук. Покупаем переходник, там же пробуем все это на глазах удивленных покупателей — не видит… Возвращаем его обратно!

Совсем уже ошалев от происходящего, ведь зная, что Iskra JS точно рабочая, поднимаемся на четвёртый этаж ТЦ и покупаем самый бюджетный ноутбук на Windows. Добираемся до дома, подключаем, и о счастье — окна спиликали и сказали, что найдено устройство, но оно не верно работает. Достаём бубен и танцуем вокруг с попытками накатить другой драйвер. Но каменный цветок так и не выходит.

Открываем пиво, и в этот момент приходит гениальная мысль: «А возможно, все три моих USB-кабеля мертвые, ведь я не уверен в них, так как не пользуюсь ими?!». Доходим до ближайшего магазина с ширпотребом и покупаем USB-провод. Бежим домой через пивной магазин, чтобы пополнить запасы. Подключаем Iskra JS к Macbook и — о чудо! — всё работает! Так как пиво уже открыто и в холодильнике есть ещё, забываем про зря купленный ноутбук :D

Пишем несколько десятков строк кода, чтобы контроллер принимал команды по Bluetooth и отправлял туда же логи, чтобы проверить работу насоса, клапанов и, самое главное, счётчика жидкости, так как основное, что необходимо, — правильно дозировать жидкости!

Проверяем всё это, и выясняется два неприятных факта:

  • Датчик жидкости считает больше, чем на самом деле через него прошло.
  • Bluetooth-соединение отваливается после включения насоса.

Делаю предположение, что датчик жидкости считает неверно из-за того, что насос создаёт слишком большое давление, на которое не рассчитан датчик. А синезуб отваливается из-за помех, которые исходят от насоса в момент включения.

Решение первой проблемы — включить в схему драйвер мотора, чтобы можно было контролировать производительность насоса.

Решение второй — отказаться от Bluetooth в пользу Wi-Fi и управлять устройством через Telegram-бота. Преимущество налицо! Не нужно писать программу для телефона, а всё необходимое Telegram уже предоставляет.

Едем в магазин и покупаем ещё два шилда:

Возвращаемся, подключаем Wi-Fi — не работает! Танцы с бубном — не работает! Едем в магазин, возвращаем деньги, покупаем в другом месте — работает!

И тут же понимаем, что рассадник зла и террористов Telegram заблокирован в РФ, а в библиотеке, которую планировал использовать для быстрого поднятия бота, нет возможности указать адрес прокси.

Ну ничего не поделать — форкаем библиотеку, дописываем возможность использовать домен, отличный от api.telegram.org. Поднимаем на DigitalOcean самую дешёвую VPS и настраиваем там на nginx реверс-прокси для api.telegram.org. Пробуем на тестовой команде — всё ок, бот работает! Наконец-то! Можно приступить непосредственно к программированию того, что будет готовить наши крутые коктейли!

Посоветовавшись с СЕО компании, решаем, что нужно готовить три коктейля: негрони, джин-тоник, кампари шприц. Чтобы в случае отсутствия спроса на коктейли можно было догнаться отдельно оставшимися ингредиентами!

Итого: для приготовления этих коктейлей нам необходимо: джин, кампари, красный вермут, тоник, шампанское.

В прошивку углубляться не буду, ведь там всё довольно просто. В одном объекте храним информацию о том, какой клапан за какой ингредиент отвечает. В другом — рецепт коктейлей.

const bottles = { 'gin': 4, 'vermouth rosson': 3, 'campari': 2, 'tonic': 1, 'prosecco': 0 }; const cocktails = { 'negroni': [ { name: 'vermouth rosson', volume: 30 }, { name: 'campari', volume: 30 }, { name: 'gin', volume: 30 } ], 'gin_tonik': [ { name: 'gin', volume: 50 }, { name: 'tonic', volume: 150 } ], 'campari_spritz': [ { name: 'campari', volume: 60 }, { name: 'prosecco', volume: 60 }, { name: 'tonic', volume: 100 } ], 'gin': [ { name: 'gin', volume: 50 }, ], 'tonic': [ { name: 'tonic', volume: 100 }, ], 'prosecco': [ { name: 'prosecco', volume: 100 }, ] };

И не забываем добавить отдельно «топпинги» для привередливых гостей :)

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

Робот-бармен своими руками — когда лень на корпоративе наливать коктейли вручную

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

Но после того как натренировались на кошках, время взвалить на себя тяжёлое бремя тестировщика-дегустатора! Идём до «Ашана», покупаем те же самые ингредиенты, что планируются на мероприятии. Заодно покупаем будущий корпус для устройства — пластиковый пищевой контейнер!

Прототип устройства готов! Приступаем к тестам!

Я думаю, не стоит говорить, что на следующий день я был в совсем не работоспособном состоянии :D

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

Две вспомогательных функции по промывке системы после использования устройства и прокачке системы в самом начале тоже были написаны уже в бессознательном состоянии :D И даже не пришлось рефакторить!

За день до корпоратива устройство приобрело вид настоящего MVP из го… и палок. Пришлось очередной раз сгонять в магазин за чем-то, что было похоже на ножки, — этим оказались деревянные шампуры.

Робот-бармен своими руками — когда лень на корпоративе наливать коктейли вручную

В этом пластиковом контейнере компактно расположилась вся механическая часть.

​

А всю электронику решил облагородить и расположить снаружи, чтобы придать более интересный вид устройству.

Робот-бармен своими руками — когда лень на корпоративе наливать коктейли вручную

Настал день корпоратива. Так как сейчас единственный возможный вариант настроить подключение к Wi-Fi — это прописать в прошивку SSID и пароль. Пришлось принести с собой ноутбук и залить обновленный код, и бот сразу же написал мне «Ready!».

Презентация устройства и демонстрация его работы прошли успешно! Устройство работало без ошибок и глюков весь долгий вечер.

Не могу сказать, что путь, пройденный во время разработки устройства проще, чем вручную разливать коктейли. Но ведь и смысл в другом — получить моральное удовлетворение и удивить гостей :) Надеюсь, это получилось!

Следующие устройства, которые планирую начать с нового года: полностью автоматическая пивоварня и кофе-машина, умеющая HomeKit и управляемая с помощью Siri.

63
40 комментариев

Когда на Хабре стало так душно, что люди пошли на vc)))

19
Ответить

пришёл сюда написать тот же самый комментарий)

4
Ответить

"Но ведь и смысл в другом - получить моральное удовлетворение и удивить гостей"


Можно идти по пути Лукаса. 

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

Всё, робот почти готов. Осталось залить 300 мл свежей прошивки.

9
Ответить

А если заливать сразу в себя 300мл свежей прошивки, то совсем ничего не придется делать 😂

4
Ответить

И добавить функцию "random" :-) 

4
Ответить

Есть такая недокументированная функция 😂 но в таком случае нужно минимум бутылок 10. Иначе не будет нужного разнообразия

1
Ответить

Охуенно! 

4
Ответить