В мире существует невероятное количество говорящих игрушек для детей и это только усугубляет впечатление, что взрослым быть скучно. Наша команда решила исправить эту ситуацию.
Начало истории
Всё началось с того, что в пытливый ум одного моего друга и коллеги netsnail пришла светлая мысль: а почему бы не только детей, но и взрослых не повеселить тематическими шутками? Благо доступное и хорошо зарекомендовавшее себя железо сейчас уже ни разу не редкость, да и умеет оно не только лампочками мигать, но и песни петь.
В связи с этим он позвонил мне и предложил повторить эпический подвиг убедиться так ли хорошо ESP8266 музыку в MP3 формате играет по сети и не разрывает ли хомячка на куски хватает ли реально производительности, что я и сделал по быстрому в новогодние праздники 2016 года:
На видео ESP8266 играет интернет радио, выводя звук с помощью хака «5-битный PWM через I2S».
Однако проигрывание MP3 радио из интернет кушало почти весь ресурс ESP8266 и звучало «так себе», в то время как воображение уже рисовало нам нечто большее, чем просто MP3 радио колонку. С этими творческими порывами мы и пошли к нашей команде и любимому шефу Владимиру.
После небольшого мозгового штурма начала вырисовываться более детальная картина и даже логическая цепочка того, что мы не только хотим, но и можем сделать:
- MP3 заменить на что-то менее требовательное к ресурсам и более свободное, остановились на Speex, который flexxnn довольно удачно и быстро портировал на ESP8266.
- Записи шуток брать с сервера в облаке и складывать локально на SD карту, т.к. интернет не везде есть, да и на ESP8266 если постоянно включенным держать — никакой батарейки не напасёшься.
- Привязать «шутки юмора» к каким-то событиям, а не просто по random говорить. Генератором событий был выбран смартфон, так как он почти у всех уже есть. Ну а собственно события можно легко получать из Apple Notification Center Service (ANCS), который уже есть на iPod, iPhone и iPad.
- Использовать для связи со смартфоном Bluetooth Low Energy (BLE), потому что заряжать игрушку чаще раза в неделю мало кому покажется забавным.
- Чтобы игрушка не бесила пользователя частыми шутками на все приходящие события решили использовать логику на скриптовом языке. Остановились на Pawn language.
- Так как вкусы на шутки у всех разные, а слушать одну и ту же шутку это уже грустно — было решено дать пользователю возможность голосовать за шутки путём «погладить» и «побить» (акселерометр), чтобы на контент-сервере в следующий раз сформировать ему более релевантный плейлист.
Выбор железа
Изначально хотелось сделать очень простой, но полностью рабочий прототип на плате «всё в одном», поэтому решили попробовать на LinkIt ONE от MediaTek. И netsnail это почти сходу удалось. Был и коннект с телефоном и с SD карточки MP3 отлично проигрывались.
Казалось бы — вот оно счастье и готовая уже платформа! Но потом мы столкнулись с суровой реальностью ограничениями их закрытого SDK и эйфория прошла.
Мы поняли, что готовой платформы на одной плате, удовлетворяющей всем нашим пожеланиям, не было в природе, а значит нам предстояло создать её с нуля.
Итак, нам предстояло выбрать (февраль 2016) наиболее подходящий BLE чип, который необходимо было связать с ESP8266. В качестве связи между ESP8266 и BLE чипом (мы тогда не знали ещё какой это будет чип) решили использовать стандартный TWI (I2C).
А вот с BLE выбор был тогда не особо велик:
- TI CC2541 — сразу как-то не приглянулся из-за архитектуры 8051, да и 8 Кб RAM выглядели малообещающими лёгкую жизнь, учитывая количество BLE сервисов и характеристик, которые требовались нам в игрушке.
- BCM20732 — выглядел очень многообещающе, но на поверку SDK оказался очень сырой, а железо BLE «брелка» Broadcom WICED Smart настолько глючным, что я ничего тут особо писать не буду, чтобы не ругаться. Дайте знать, если сейчас ситуация улучшилась.
- nRF52832 — первый чип, который сразу порадовал. Но тогда не было компактного BLE модуля — rekod начал прототипировать на отладочной плате, SDK очень понравился, содержал много разных рабочих примеров. Пример BLE ANCS запустился сходу и мы тут же увидели уведомления с iPhone в логах с UART. Кстати на этой отладочной плате есть настоящий программатор и отладчик SEGGER J-Link, что сильно облегчило нам жизнь в дальнейшем.
- nRF51822 — на тот момент существовали готовые модули, а программировали их через SEGGER от nRF52832. Что больше всего меня удивило — код со старшей модели nRF52832 отлично переносится на младшую nRF51822 и обратно!
В итоге первое железо выглядело как паук тарантул примерно так:
Ловить глюки из-за отваливающихся dupont кабелей, особенно на модуле nRF51822, где pin'ы чуть меньше размером, было очень грустно.
BLE сервисы на nRF51822 и iOS приложение
Тем не менее я и affair уже на этом железе-пауке начали реализовывать BLE сервисы и характеристики на nRF51822, поделив всё примерно пополам:
- Apple Notification Center Service (ANCS) — для получения уведомлений о событиях со смартфона.
- Apple Current Time Service (CTS) — при подключении игрушка берёт время с телефона.
- HandShake Service (HSS) — этот сервис, кстати, делает игрушку «неугонямой» в отличие от обычных гарнитур и подобных гаджетов. Дело в том, что в облаке есть СlientID и пользователь не просто делает pair телефона и игрушки по Bluetooth, но и дополнительную привязку, которую не так то легко сбросить. Описание этого процесса требует отдельной статьи, поэтому ограничусь кратким упоминанием.
- Battery As Service (BAS) — передача состояния батарейки в приложение на смартфон.
- Content Service (CONTS) — этим можно посмотреть список проигранных ранее шуток, с текстом (текст берётся с сервера в облаке).
- Settings Service (SETTS) — этим можно настроить фильтры неприемлемого контента шуток, время когда игрушка должна молчать (ночью, например) и т.д.
MaximKit в это же время делал приложение под iOS.
На картинке справа виден главный экран приложения.
Тут flexxnn не выдержал наших страданий из-за отваливающихся проводков и сделал дома методом лазерного утюга первый нормальный прототип:
На фото не видно, но слот для microSD карты там уже есть. На маленькой квадратной платке внизу — ALC5627, звук был уже гораздо лучше, чем 5-битный PWM через I2S.
Для управления питанием выбрали AXP209. Позволяет и заряжать и использовать аккумулятор одновременно, а также следить за его состоянием. Чип очень распространённый, но имеет много специфики как в программировании, так и в требуемых внешних компонентах, т.н. «обвязке».
Магия на ESP8266
Параллельно с этим flexxnn портировал на ESP8266 Speex, FatFs, сделал bootloader для ESP8266 и nRF51822, чтобы можно было не шить обновлённые прошивки по проводам, а делать это помещая файлы прошивок на microSD карту.
Лично мне кажется ему помогали инопланетяне, так как сделал он это всё примерно за месяц. Но он не сознаётся в контактах с инопланетным разумом.
А затем и второй более нормальный прототип:
Но более нормальный прототип уже не лез в мягкую игрушку. А если бы и влез, то при резком движении на потенциального пользователя из игрушки полез бы «чужой», что конечно было неприемлемо для MVP.
Поэтому решено было заказать плату профессионалам и вот что получилось в итоге:
В кота такая конструкция уже отлично помещается, правда выглядит это как-то негуманно:
В то же время подтвердились опасения, что события с телефона могут приходить довольно часто и в итоге пользователь получил бы раздражение вместо веселья. Требовалась гибкая логика для фильтрации, которую можно легко менять в любой момент без перепрошивки. В связи с этим я, изучив матчасть и поняв, что для ESP8266 быстрых и компактных скриптов нет (Lua и microPython — интерпретаторы), решил портировать Pawn language, который быстро (всего лишь в 18 раз медленнее нативного) исполняет компактный байткод.
Кстати исходники на Pawn очень похожи на C, поэтому скрипты модифицировать одно удовольствие — их достаточно всего лишь скомпилировать в AMX байткод и скопировать на SD карту.
Обман гаджетов. Прикидываемся iOS на Android
И тут «внезапно» мы все вспомнили, что Android телефонов в мире не так уж и мало, а даже больше, чем телефонов с iOS.
В итоге мне пришлось в темпе проверить сможем ли мы обмануть гаджеты и прикинуться iOS на Android, чтобы они увидели сервис ANCS, неотличимый от Apple.
В итоге всё удалось и уже через неделю гаджеты (и наш кот не исключение) искренне верили, что у меня iPhone с ANCS сервисом, подключаясь к моему Nexus 5 и даже к старому Samsung Galaxy с Android 4.4.
Go Cloud
Так как никто не любит слушать шутку по несколько раз (факт), а также существуют предпочтения и культурные ограничения, решено было каждому пользователю формировать уникальный playlist. Для этого affair вплотную занялся сервером в облаке.
Но как решить кому что понравится? Правильно — пусть решит сам пользователь! Для этого я сделал базовый gesture detection на акселерометре LIS3DH от STMicroelectronics. Понравилась шутка — наклонил кота, как будто «да», не понравилась шутка — наклонил вбок, как будто «нет». А ещё добавил «незабудку» для телефона — если связь по BLE пропадает, а акселерометр фиксирует движение, значит кота куда-то несут, а телефон забыли.
После того как пользователь «полайкал» и обозначил тем самым свои предпочтения — информация уходит на сервер, где идёт сравнение «геномов» playlist'ов и пользователю формируются новые наборы шуток. Но это уже тема для отдельной статьи.
Итоги
В итоге из развлечения получилась отличная платформа, которая умеет:
- связываться с телефоном по BLE и получать уведомления о событиях;
- связываться по WiFi и скачивать контент и обновления прошивок;
- сохранять и читать файлы в FAT32 на microSD;
- играть шутки, упакованные speex кодеком;
- определять предпочтения пользователя с помощью акселерометра (gesture detection);
- формировать playlists под каждого пользователя на основе его предпочтений в юморе;
Что примечательно, «оч.умелые ручки» вполне могут подключиться к соответствующим pin'ам (даже отверстия под разъёмы на плате оставлены) и «поумнеть кота» так, как им заблагорассудится. Это и делает платформу всё-в-одном привлекательной для гиков.
С этой платформой мы и вышли на kickstarter, назвав готовую игрушку KiQ. В первый же день собрали 40%, а сейчас уже 57%. Но это уже совсем другая история.
Спасибо всем тем, кто дочитал до этой строчки. Жду от вас интересных вопросов.
Автор: rekod