[Из песочницы] Кот-анекдот KiQ или как мы говорящую игрушку для взрослых сделали
В мире существует невероятное количество говорящих игрушек для детей и это только усугубляет впечатление, что взрослым быть скучно. Наша команда решила исправить эту ситуацию.
Начало истории
Всё началось с того, что в пытливый ум одного моего друга и коллеги 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%. Но это уже совсем другая история.
Спасибо всем тем, кто дочитал до этой строчки. Жду от вас интересных вопросов.
Источник

Airbus A220 первым из пассажирских самолётов получит систему навигации, не зависящую от GPS
Все 33 Raptor включились на 15 секунд: SpaceX провела успешные огневые испытания ускорителя Super Heavy B22
Boeing недосчитывается до $6,5 млн ежедневно: выпуск грузовых 777F почти два месяца простаивает
«Выбор очевиден»: Airbus намерен нарастить выпуск A350 — мировой авиации требуется больше широкофюзеляжных лайнеров
Samsung Galaxy S27 Ultra оснастят батареей на 5700 мА·ч, 60-ваттной зарядкой, 200-мегапиксельной камерой и защитой по стандарту IP68
Nvidia планирует ввести подписку на $2000 в год за каждую видеокарту для работы с нейросетями
Раскрыты характеристики Samsung Galaxy S27 Pro: аккумулятор на 5200 мАч, 2К-экран, камера 200 Мп и защита IP68
Теперь смотреть сериалы и листать TikTok можно на собственном рукаве: учёные вшили в ткань экран