Хотеть!
200 у.е. но не у нас.
200 у.е. но не у нас.
Привет!
Я новичок в этом деле, нужна Ваша помощь. Также новичок на Пикабу и не знаю, длинный мой пост или нет, по сему заранее перед вами извиняюсь.
Собираюсь сделать настенный терминал управления умным домом с home assistant. В наличии есть:
1) Cама плата Raspberry pi 3 b
2) Сенсорный дисплей, диагональ 10.1, разрешение 1024х600
3) Картридер
4) Sd карточка на 32gb и соответственно переходник
За неимением оригинального блока питания для одноплатника использую бп - внешний аккумулятор Moonfish на 20Вт.
Опираюсь по этому гайду:
Касаемо проблемы:
С помощью imager устанавливаю на карту памяти Raspberry Pi OS Lite 64-BIT. Далее колхозно для теста собираю плату с дисплеем, подключая свистки беспроводных мыши и клавиатуры, вместе с питанием от бп. Одноплатник привычно запускается до рабочего стола. Захожу уже на Пк в командную строку и по гайдам идет этам подключения по ssh. Необходимо достучаться через host name или по ip. С именем хоста по не понятной мне причине результат отрицательный, по ip предлагает ввести пароль.
Тут как раз я и задаюсь вопросом "Где же зарыта собака?". При вводе пароля (символы не отображаются, судя по инфе из интернетов, ради безопасности) консоль выдает отказ в доступе.
Возвращаясь к этапу "установка ОС на сд карту". При установке всплывает окно с переходом в настройки, где можно прописать имя хоста с паролем, ssid и пароль для него, так же проставить галочку у ssh. Все это заполнил, галочку поставил.
При вводе пароля в командной строке Пк мне отказывают в доступе. Ищу ответ на форумах, но внятного решения так и не нашел. Как быть? Заранее спасибо всем за комменты и конструктивную критику.
Да-да, идея не уникальна, но тег моё, т.к я сам разработал, спаял и запрограммировал эту штуку
В этом видео показан процесс установки операционных систем Ubuntu, Android на одноплатный компьютер Orange Pi PC.
В этом видео показан процесс установки операционных систем Ubuntu, Android на одноплатный компьютер Orange Pi PC.
Ссылка на образы операционных систем
логин и пароль на OS ubuntu: user: root , password: orangepi
Ссылка на группу где Вы можете задать вопросы об Orange Pi PC, а также технические вопросы
Ссылки на программы, которые используются в этом видео
Все программы, Вы используете на свой страх и риск
К огромному сожалению, старые смартфоны всё чаще и чаще находят своё пристанище в мусорном баке. К прошлым, надежным «друзьям» действует исключительно потребительское отношение — чуть устарел и сразу выкинули, словно это ненужный мусор. И ведь люди даже не хотят попытаться придумать какое-либо применение гаджетам прошлых лет! Отчасти, это вина корпораций — Google намеренно тормозит и добивает довольно шустрые девайсы. Отчасти — вина программистов, которые преследуют исключительно бизнес-задачи и не думают об оптимизации приложений совсем. В один день я почувствовал себя Тайлером Дёрденом от мира IT и решил бросить вызов проприетарщине: написать свою прошивку для уже существующего смартфона с нуля. А дабы задачка была ещё интереснее, я выбрал очень распространенную и дешевую модель из 2012 года — Fly IQ245 (цена на барахолках — 200-300 рублей). Кроме того, у этого телефона есть сразу несколько внешних шин, к которым можно подключить компьютер или микроконтроллер, что даёт возможность использовать его в качестве ультрадешевого одноплатника для DIY-проектов. Получилось ли у меня реализовать свои хотелки? Читайте в статье!
Честно сказать, идея попытаться реализовать свою прошивку мне пришла ещё давно. Однако, дабы не завлекать опытного читателя кликбейтом, я сразу поясню, в чём заключается «прошивка с нуля»:
Мы всё ещё используем Linux: в качестве ядра мы продолжаем использовать образ Linux, предоставленный нам производителем. Написание прошивки полностью с нуля заняло бы очень много времени (особенно без схемы на устройство). Однако, мы вообще не загружаем Android никаким образом.
Мы не используем библиотеки AOSP: наша прошивка без необходимости не использует никаких библиотек уже имеющегося образа Android. Вся работа с железом происходит с помощью низкоуровневого API Linux. Это значит, что отрисовка графики, звук, управление ресурсами и питанием ложится полностью на нас.
Прошивка может запускать только нативные программы: да, это тоже камень в сторону Android. Изначально, наша прошивка умеет запускать только нативные программы, написанные на C. Причём она экспортирует собственное C API — дабы приложения могли использовать всю мощь нашего смартфона в виде простого и понятного набора методов.
Проектов по выкидыванию Android из, собственно, Android-смартфонов как минимум несколько: UBPorts — бывший Ubuntu Touch, FireFox OS и его наследник Kai OS и конечно же, postmarketOS. Отчасти можно сюда отнести и Sailfish OS — но там образы имеются в основном на смартфоны от Sony. Все эти проекты объединяет сложность портирования и невозможность их завести на устройствах без исходного кода ядра. Даже если у вас есть исходный код ядра, но, например, устройство использует ядро 2.6 — навряд-ли вы сможете завести современный дистрибутив на нём.
Другой вопрос в том, что можно использовать полу-baremetal подход, когда от Linux берется практически минимальный функционал. Всё, что мы имеем — busybox, libc и низкоуровневый доступ к железу, благодаря API самого ядра. Как под это всё программировать — я рассказывал впрошлойстатье. Этот же подход мы будем использовать и сейчас — как иллюстрация реального применения подобного способа.
Итак, что наша прошивка должна уметь:
Отрисовывать произвольную графику: графическая подсистема нашей прошивки должна работать с фиксированным форматом пикселя, уметь загружать прозрачные и непрозрачные изображения, отрисовывать картинки с альфа-блендингом и т. п.
Уметь звонить и работать с модемом: общение с модемом происходит посредством AT-команд — общепринятого в индустрии стандарта. Однако в случае нашего устройства, есть м-а-а-а-ленький нюанс, о котором я расскажу позже.
Иметь механизм приложений: мы ведь не будем хардкодить все «экраны» в прошивке в виде кучи стейтов, верно? Для этого у нас должен быть простой и понятный механизм слинкованных с прошивкой приложений.
Обрабатывать ввод: обработка тачскрина и жестов — это задача подсистемы ввода.
Реализовывать анимированный UI: здесь всё очевидно, наша прошивка должна иметь готовые элементы пользовательского интерфейса для будущих приложений: кнопки, текстовые поля и т. д. О деталях реализации этой подсистемы, я расскажу ниже (а реализовал я её очень необычно для такой системы).
Начинаем мы с хардварной части. Именно здесь я покажу вам, как использовать внешние шины вашего устройства.
В качестве смартфона для нашего проекта, я выбрал популярную бюджетную модель из 2012 года — Fly IQ245 Wizard. Это простенький китайский смартфон, который работал на базе популярного в прошлом 2G-чипсета: MediaTek MT6573, да и стоил около 2х тысяч рублей новым. Однако вот в чём суть: мне удалось заставить работать «медиатековский» модем и даже позвонить с него на свой основной телефон, но… только ввод и вывод данных из звукового тракта модема происходит через звуковую подсистему Android — к которой доступа у нас нет!
Именно поэтому, мы идём на очень хитрый и занимательный костыль: мы распаяем внешний модем сами! В качестве радиомодуля у нас выступит модуль SIM800 от компании SIMCOM. И даже он очень близок к нашему смартфону в аппаратном плане: ведь в основе этого модуля лежит популярнейший чипсет из кнопочников тех лет: MediaTek MT6261D. Преимущество SIM800 в его цене — он стоит пару сотен рублей, так что по карману выбор модема не влияет.
На весу паять крайне неудобно. В финальном варианте перепаяю нормально.
Но как его подключать? SIM800 общается с другими устройствами посредством протокола UART — универсальный асинхронный приемо-передатчик. И вот тут мы включаем смекалочку. Разбираем устройство и видим то, что я пытаюсь долгое время донести до моих читателей — аж два канала UART: один практически посередине, второй справа. Нам нужны пятачки TXD4 и RXD4:
Обычно на этот канал UART летят логи ядра, которые можно без проблем отключить минорной правкой U-Boot в HEX-редакторе. Впрочем, модем никак не реагирует на «мусор» из консоли и просто отвечает ошибками — хватит лишь очистить буфер сообщений для того, чтобы все работало нормально. Подпаиваемся к UART'у с помощью преобразователя — у меня оным выступает ESP32 с выпаянным чипом.
Увидели логи? Замечательно, пора попытаться что-то отправить на ПК и с ПК. UART работают без тактовых сигналов и зависит исключительно от старт/стоп битов и бодрейта, который на устройствах MediaTek равен 921600. TXD4 и RXD4 обнаруживаются в системе на консоли/dev/ttyMT3. Пробуем что-то отправить: всё работает!
Вот теперь-то можно подключить наш внешний модем и попытаться пообщаться с ним, отправив тестовую командуAT. Модем отвечаетOK! На этот раз я работаю с смартфоном из режимаFactory mode— практически тоже самое, что и режим recovery, но позволяющий, например, получить доступ к камере устройства. Простая и понятная схема, поясняющая что и куда подключать:
На этом модификация аппаратной частипоказакончена. Пора переходить к реализации софта! Я решил разделить материал на каждый модуль, который я реализовывал — дабы вам был понятен процесс разработки и отладки прошивки!
На этот раз я решил загружать смартфон из режима рекавери. Однако никто не мешает в будущем просто прошить раздел recovery вместо boot и получить прямую загрузку прямо в нашу прошивку. Время такой загрузки будет заниматься ~3-4 секунды с холодного старта. Очень даже ничего.
Я взял уже готовый образ TWRP для своего смартфона и пропатчил его, дабы сам рекавери не мешал своим интерфейсом. Для этого я распаковал образ recovery.img с помощью MtkImgTools и убрал в init.rc запуск службы /sbin/recovery. После этого, я залил прошивку обратно на устройство и получил подобную свободу действий — консоль через USB и чистый холст в виде смартфона! Старые смартфоны на чипсетах MediaTek шьются через USB только после замыкания тест-поинта — на моем аппарате его местонахождение очевидно. Замыкаем контакты между собой, подключаем смартфон без АКБ к ПК и ждем прошивки:
Теперь можно деплоить программы! Важный нюанс: в отличии от Makefile из прошлой статьи, для Android 2.3 параметр -fPIE нужно убрать — иначе динамический линкер (/sbin/linker) будет вылетать в segmentation fault.
В комментариях под прошлой статьёй меня похвалили за то, что я делюсь достаточно профильными знаниями касательно эффективной отрисовки 2D-графики. Собственно, к реализации графической подсистемы я подошёл ответственно и постарался реализовать достаточно шустрый рендерер, к которому затем можно подключить другие модули.
Как я уже говорил ранее, графическая подсистема должна уметь загружать картинки, выводить некоторые примитивы, выводить картинки с прозрачностью и без, загружать и отрисовывать заранее подготовленные шрифты, а также управлять отрисовкой бэкбуфера на экран.
В случае с этим устройством (и большинством старых устройств), формат пикселя оказался RGB565 — т. е. 5 бит красный, 6 бит синий, 5 бит зеленый. Конвертация форматов пикселей всегда была занозой в заднице для программных рендереров, поскольку занимает дополнительное время, которое обратно зависимо от размера дисплея. Изначально я решил выделить буфер в том же формате, что и фреймбуфер, но затем решил сделать классический и самый портативный формат — RGB888 (24х-битный цвет), а при копировании кадра на экран, на лету делать преобразования цвета:
Очень важный нюанс, который я не упомянул в предыдущей статье: на устройствах прошлых лет для обновления фреймбуфера необходимо послать структуру var_screeninfo, где хотя бы что-то изменено, иначе никаких изменений мы не увидим. Этот же костыль используется в родном recovery для отрисовки, а судя по исходникам драйвера fb, «правильный» способ обновить экран — послать драйверу ioctl (который я пока что не пробовал).
После того, как я смог управлять дисплеем, я решил загрузить и отобразить какую-нибудь картинку. Пусть это будут обои для нашей прошивки:
Загрузчик TGA сильно не поменялся: я таскаю его в неизменном виде из проекта в проект. Он поддерживает любые форматы пикселя, кроме палитровых, но я его искусственн ограничиваю на RGB888 и RGBA8888 — для поддержки обычных картинок и картинок с альфа-каналом. После этого, я написал не очень шустрые, но достаточно универсальные методы для отрисовки картинок. Для больших участков кода, я буду использовать pastebin, поскольку на Пикабу до сих пор не добавили ни подсветки синтаксиса, не нормальный перенос форматирования табов :(
PutPixel желательно заинлайнить в будущем. В целом, сама отрисовка работает достаточно быстро, но поскольку рендеринг выполняется на ЦПУ — рано или поздно мы упремся в количество картинок на экране. Есть некоторые оптимизации: например, непрозрачные картинки можно просто коприовать сканлайнами прямо в задний буфер.
Сразу же реализовываем методы для рисования шрифтов: они у нас будут совсем простенькими — только моноширинные (все символы имеют одинаковую ширину) и растровыми (для каждого размера придется «запекать» несколько шрифтов). Для этого я написал маленькую программку, которая рисует виндовые шрифты прямо в наш самопальный формат:
Формат примитивнейший:
1 байт говорит нам о размере шрифта и далее идут 255 изображений символов. Да, это не очень эффективно т.к попадают пустые символы из ASCII-таблицы, но в будущем это можно поправить.
Прозрачность в символах обеспечивает фоновый цвет Magena — ярко-розовый. Я не стал делать дополнительный альфа-канал, т. к. иначе будут серьезные лаги при выводе большого количества текста.
Теперь у нас есть отображение картинок и текста! Что с этим можно сделать?
Пока что здесь не хватает обработки «хардварных» кнопок — домой, меню, назад и т. п. Однако в будущем это всё можно реализовать!
Не забыл я и про анимации. Ну кому с такими ресурсами нужен неанимированный топорный интерфейс? Пусть лучше будет анимированный, пусть и примитивный!
Аниматор напоминает оный из ранних версий Android: он имеет фиксированный набор свойств, которые умеет интерполировать в промежутках определенного времени. Если простыми словами: то он оперирует линейными отрезками времени a и b, в промежутке которых мы имеем значение «прогресса» — которое даёт нам результат от 0.0f (начало анимации) до 1.0f (конец анимации). Пока время тикает до необходимого интервала (duration), аниматор интерполирует заранее назначенные ему поля до нужных значений.
Именно так и получается плавность! Похожим образом реализованы анимационные системы во многих играх и мобильных ОС, только там они гораздо более комплексны: есть сериализация/десериализация из файлов, поддержка кейфреймов (несколько последовательных состояний на одном промежутке времени), поддержка кастомных свойств и т. п.
Как я уже говорил раннее, работа с модемом происходит посредством AT-команд. Лучше всего обрабатывать ввод-вывод модема из отдельного потока, поскольку он может отвечать довольно медленно и тормозить UI-поток основной программы, вызывая лаги. В SIM800 уже реализован весь GSM-стек, в том числе декодирование и вывод звука через встроенный усилитель с фильтром — остается только подключить динамики и микрофон от нашего телефона. Пока что я подсобрал аудиотракт на том, что было под рукой — микрофон от нерабочего смартфона и динамик от планшета, но для проверки этого хватает:
Важный нюанс: по умолчанию, tty-устройства в Linux работают по терминальному принципу — т. е. дробят транзакции по символу окончания строки (\n), имеют ограниченный буфер и т. д. Для нормальной работы в условиях модема — когда фактически длина ответа неизвестна, а в сам ответ могут «вклиниваться» Unsolicited-команды (своеобразные флаги о состоянии от модема, которые могут прийти в произвольное время — т. е. при входящем звонке, модем начнёт флудить RING в терминал), необходимо иметь возможность точно прочитать весь буфер до конца и парсить данные «по месту». Для этого используется raw-режим терминала:
tcgetattr(modemFd, &tio);
tio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
tio.c_oflag &= ~(OPOST);
tio.c_cflag |= (CS8);
tio.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
tcsetattr(modemFd, TCSAFLUSH, &tio);
После чего можно запросить состояние модема:
И продолжить работу дальше. После этого, можно переходить к реализации самой прослойки между модемом и вашей программой:
Пытаемся позвонить с помощью метода Dial и видим, что всё работает! Это очень круто! А теперь, конечно же, самое время переходить к реализации того, чего вы ждали — пользовательского интерфейса!
К выбору концепции для интерфейса, я поступил максимально просто — «слизал» дизайн первых версий iOS. Как по мне, это одни из самых красивых версий iOS вообще — все эти приятные градиенты и переливания. Конечно, я не так крут, как инженеры Apple, да и мощного UI-фреймворка у меня пока что нет, поэтому я приступил к реализации с «минимальным» функционалом.
Начал я с разделения главного экрана на модули и продумывания архитектуры основного «лаунчера». У нас есть статусбар, который рисуется поверх всех приложений, полка с приложениями — AppDrawer и сами экраны приложений, унаследованные от суперкласса CScreen.
На данный момент, отрисовка достаточно примитивная: сначала рисуются фоновые обои, затем, если нет никаких активных экранов — AppDrawer и в самом конце рисуется статусбар и всевозможные оверлеи.
Практически сразу я решил обкатать анимационную «систему» и добавить первые анимашки — выезжающий статусбар и анимация а-ля айфон:
animator = new CAnimator();
animator->SetTranslation(0, -imFiller->Height, 0, 0);
animator->Run();
Выглядит симпатичненько. Если я смогу поднять хардварный GLES, то это получится сделать в разы плавнее и шустрее — не хуже айфонов тех лет! Реализация самого статусбара примитивненькая, но вполне рабочая:
gLauncher->Graphics->DrawImage(imFiller, animator->X, animator->Y);
gLauncher->Graphics->DrawImage(imBattery[(int)gLauncher->PowerManager->GetBatteryLevel()], imFiller->Width - imBattery[0]->Width - 5, animator->Y + 5);
char timeFmt[64];
time_t _time = time(0);
tm* _localTime = localtime(&_time);
strftime((char*)&timeFmt,
sizeof(timeFmt), "%R", _localTime);
gLauncher->Graphics->DrawString(gLauncher->Font, (char*)&timeFmt, 0, 0);
Кроме этого, я сразу же реализовал предварительный механизм приложений в системе — пока что они слинкованы статически с основным лаунчером. Для этого есть структура CAppDesc, которая содержит минимально-необходимую информацию для показа информации о приложении и фабрику для создания его основного экрана.
Обратите внимание на удобство примененного подхода Immediate GUI. Нам понадобился новый элемент интерфейса, который описывает кнопку номеронабирателя? Мы просто реализовываем ещё один метод, который берет за основу стандартную кнопку и дорисовывает к ней текст. Всё крайне просто и понятно, хотя на данный момент слишком захардкожено. :)
Пришло время совершить первый звонок с нашей по настоящему кастомной прошивки. Набираем номерок и…
Да, всё работает и мы без проблем можем дозвониться :)
Конечно же, это далеко не весь функционал, необходимый любому современному смартфону. Здесь много чего еще нужно реализовать хотя бы для соответствия уровню бюджетных кнопочных телефонов: телефонную книгу, поддержку СМС/ММС, мультимедийный функционал с играми. Однако начало уже положено и самая необходимая часть модулей реализована. Этот проект очень занимательный для меня и я горд, что смог не на словах, а на деле показать вам, моим читателям, возможности моддинга совершенно NoName-устройств, без каких либо опознавательных знаков…
Моя задача заключается в том, чтобы показать вам возможности использования старых телефонов не только в потребительских, но и в гиковских DIY-сферах. Судите сами: огромный классный дисплей, емкостной тачскрин, готовый звук, камера — и всё это за каких-то пару сотен рублей. Главное показать людям, как всю эту мощь использовать в своих целях и делать совершенно новые устройства из существующих, а не выбрасывать их на помойку!
Сейчас смартфоны, подобные Fly из этого поста стоят копейки, а портировать на них прошивку можно без каких-либо трудностей. Я очень надеюсь, что после этого поста читатели попытаются сделать что-то своё из старых смартфонов, благо свои наработки я выкладываю на GitHub!
Дурная голова рукам покоя не даёт… история началась несколько месяцев назад: я увидел на Пикабу забавное видео игры в комнате с пиксельным светодиодным полом и решил сделать подобное для своих детей. За эти месяцы я получил массу удовольствия от процесса разработки и даже заразился идеей масштабирования проекта, но обо всём по порядку! Внимание, ниже будет много фото!
Идея в целом не уникальна, но я не нашёл в продаже каких-то готовых решений. В том же Китае продаются платформы без обратной связи и без игровых возможностей, у них это называется светодиодный танцевальный пол. Но это всё не то, что я хотел, а значит надо делать самому. Всегда любил работать со светодиодами, это приносит огромное эстетическое удовольствие, и в целом я скучал по работе с электроникой, так что решил сдуть пыль с паяльной станции и прикупить ещё некоторое оборудование.
Пользуясь случаем, позвольте кратко представиться, так текст будет менее обезличенным.
В жизни меня зовут Анатолием, в прошлом я более 5 лет проработал на крупном заводе инженером-схемотехником-программистом (нужное подчеркнуть), так что присутствует какой-никакой реальный опыт и понимание процесса массового производства электроники, надеюсь ещё пригодится. Последние 5 лет работаю фуллстек разработчиком. Так и решил совместить эти две области в одном проекте.
Меня весьма вдохновляет прорабатывать полный производственный цикл изделия: от разработки схемотехники и написания низкоуровневого ПО на микроконтроллеры до продумывания конструктива и поиска редких метизов для сборки (это когда ты немного ошибся в 3D модели крепления датчика, а их уже напечатано более 320 штук *facepalm*).
На Пикабу публикуюсь впервые, раньше немного писал на Хабре (аля Как я в армии в экселе сетевого Бомбермена писал или Как банкоматы взрывоопасным газом накачивал). Будем знакомы!
Вот примерный концепт того, каким я видел проект:
Игровая комната:
пиксельный RGB-светодиодный интерактивный игровой пол с адекватным временем реакции на нажатие;
настенные кнопки для разнообразия игрового процесса;
табло с информацией по игре (название игры, общее время, время этапа, очки, жизни и т.п.);
колонки со звуковым сопровождением игры (озвучивать ошибки/победы/поражения, называть цели этапов, цвета и прочее).
Игровой контроллер:
приёмопередатчик для шины данных;
Ethernet / Wi-Fi канал для связи с внешним миром;
аудио выход для звукового сопровождения;
видео выход для табло.
Админ интерфейс:
отображение текущего состояния платформы и информации по игре;
запуск/остановка игр;
индивидуальная настройка пикселей (назначение адресов, коэффициентов, калибровка, дефектовка и т.д.);
конструктор игр;
всякого рода журналирование (игры, логи контроллера, ошибки и пр.).
Основная цель: на старте заложить техническую возможность масштабирования платформы до размеров средней комнаты ~20-30 м2. На этом этапе лбами сталкиваются проблемы частоты обновления платформы и надёжности связи. По своей сути это взаимовытесняющие вещи: хочешь надёжно — пожертвуй скоростью, хочешь быстро — будь готов к потерям данных. Я не хотел тупо гнать сигнал через адресную ленту на базе WS2812B, это путь в никуда.
* Скриншот из видео Activate Games
По итогу всех изысканий, в качестве интерфейса связи к пикселям, мной была выбрана шина CAN, я считаю она идеально ложится на вышеизложенную концепцию:
количество устройств в одной подсети может достигать до 120 шт. При группировке по 4 пикселя это обеспечит мне теоретический предел в 476 пикселей или примерно 34 м2, чего более чем достаточно на начальном этапе. Далее можно расширять путём введения дополнительных подсетей или увеличения количества пикселей в группах;
скорость передачи данных до 500 Кбит/с на 100 метров кабеля, чего как раз должно хватить, чтобы окольцевать 34 м2 площади. В эту скорость для тех же 476 пикселей, в зависимости от выбора протокола цветопередачи, можно будет уложить от 20 до 80 кадров в секунду;
возможность выстраивания приоритета сообщений в сети и разруливание коллизий через аппаратный механизм арбитража, что хорошо ложится на концепцию быстрого реагирования на нажатия. Короче говоря, сообщения о нажатии отправляются в шину вне очереди;
достаточно устойчивая связь вследствие использования дифференциального сигнала;
широкое распространение и дешевизна микросхем, что немаловажно.
Пессимистично делим все теоретические пределы на 4 и всё равно остаёмся в рамках разумного, жить будет. Поехали дальше!
Пиксель представляет собой классическую рамку с боковым расположением светодиодов, накрытую оргстеклом. Рамку выгрызали на ЧПУ фрезере из чёрной ламинированной фанеры толщиной 21 мм. Оргстекло мне тоже раскроили на ЧПУ при заказе, так доставка ТК обошлась в копейки, нежели доставлять лист 2х3 метра.
Первая сложность возникает при выборе типа датчика нажатия. Рассматривал несколько вариантов:
концевой переключатель;
тензодатчики (как в напольных весах).
Мне сразу не понравилась идея использовать механический переключатель, т.к. для этого потребуется обеспечить подпружиненный свободный ход оргстекла и при этом избежать залипаний. В эту же категорию идут и датчики из двух пластин, работающих на замыкание, как в танцевальных аппаратах.
То ли дело работа с аналоговыми тензодатчиками, когда свободный ход практически отсутствует (вспомните ваши напольные весы). К тому же есть пара идей, как применить аналоговый сигнал в играх…
Так и поступил: было решено собирать ~85 напольных весов собственной разработки с проводным каналом связи и RGB подсветкой. Крепления для датчиков рисовал сам и заказывал печать на 3D принтере. Было напечатано около 340 таких креплений. Конструкцией доволен, получилось весьма надёжно и доступно для массового производства, в т.ч. и для литья. Нижняя часть пикселя выглядит колхозно, но это прототип, да простят меня эстеты.
Как я упомянул ранее, я сгруппировал пиксели по 4 шт, а значит нужно два вида плат: групповая плата с модулем связи и контроллером и 4 маленьких платы просто с внешним АЦП для датчиков. По итогу я собрал 21 большую и 84 маленьких платы (на фото маленьких — это только половина от общего количества).
Основная идея была сделать пиксель максимально тупым. Он должен принимать/отображать цвет и отправлять нажатие. На словах это просто, а на деле, т.к. работа идёт с аналоговыми датчиками, нужен был периодический опрос с цифровыми фильтрами, всякими коэффициентами к ним, калибровками нуля и чувствительности и т.д., чтобы, в случае чего, можно было с бэкенда подкрутить параметры прямо на ходу, в т.ч. вывести пиксель из игры, если он начал неадекватно себя вести или залип.
Сначала у меня была идея делать собственный 3х канальный USB-CAN преобразователь и управлять платформой с обычного компьютера. Я даже успел развести и заказать платы, но потом передумал и в качестве контроллера выбрал обычную Raspberry Pi 4. В ней есть всё необходимое: Wi-Fi, аудио/hdmi выходы, а также к ней продаются готовые модули CAN шины. Сложной математики там нет, так что процессор справляется легко, я даже вывел метрики в админку на всякий случай.
Управляющее ПО писал сам полностью с нуля: фронтенд — Vue.js, бэкенд — Golang, база данных — SQLite. Из того, что реализовано на данный момент:
отображение текущего состояния платформы (подсветка нажатий и текущего веса в кг);
игровое табло (время, очки, жизни);
просмотр информации по каждому пикселю в отдельности и отправка индивидуальных команд;
отправка широковещательных команд;
вывод метрик контроллера (загрузка/температура CPU, потребление памяти, основные метрики бэкенда);
простой конструктор кадров для игр;
несколько игровых механик: пол — это лава (нужно собрать все синие, не наступая на красные), море волнуется/пиксель дуэль (соревновательные режимы по сбору своего цвета, побеждает самый ловкий), безопасный цвет (робот озвучивает цвет, нужно успеть его найти и занять), классики (пропрыгать случайный паттерн), несколько демо режимов;
старт/стоп/пауза игр с возможностью конфигурации непосредственно в момент старта игры (например, для детей я отключал контроль жизней и увеличивал время этапа);
имитация игр мышкой прямо через админку для непосредственного тестирования игры после конструктора (ну или вмешивания прямо в процесс игры… хе-хе, я так помогал своей дочке побеждать пару раз, чтоб не расстраивалась).
Сборка такого количества плат и пикселей в одиночку у меня заняла больше месяца: сверлить, прикручивать, приклеивать, паять, отлаживать и перепаивать сгоревшее. К расстановке компонентов на платы я привлекал даже дочь… как говорится, любишь играть, люби и платы собирать!
Какие ошибки допустил в процессе разработки:
Ошибка 1: Россыпь плат, а не панель
Я торопился и заказал платы не панелями, а россыпью… это было немного больно и приходилось наносить пасту на платы поштучно. Я купил трафаретный принтер для нанесения пасты и мини стол для оплавления припоя, это в десятки раз ускорило процесс. Трафаретный принтер — самоделка одного замечательного человека с ютуба, кому будет интересно, могу дать контакт в комментариях.
Ошибка 2: Оргстекло
Найти оргстекло или поликарбонат подходящей толщины оказалось проблемой. В наличии из импортного ничего нет, толстое вообще не в почёте, а если заказывать, то нужен объём + большие сроки. Взял лист оргстекла от какого-то российского производителя, а оно оказалось недостаточно молочным (см. фото), очень сильно просвечивал источник света, пришлось каждый квадратик вручную дополнительно матовать шлиф машинкой… то ещё удовольствие.
Ошибка 3: Танталовые конденсаторы
Танталовые конденсаторы сами по себе достаточно капризная штука, а заказывать их с Китая было вдвойне ошибкой… брака было около 40%: они просто взрывались при напряжении в половину от номинала. Я проверял их непосредственно перед пайкой, но даже это не помогло… несколько штук вышло из строя прямо в день мероприятия, проработав перед этим около месяца дома. В следующий раз поставлю бочонки, благо высота позволяет, они не так горят.
Ошибка 4: Таблица на фронтенде
Я ненастоящий фронтендер и умею клепать только админки для внутреннего использования. Как мне кажется, было ошибкой использовать на фронтенде простую таблицу. Хоть обновление ячеек и сделано реактивно на тегах, но рендер всего поля разом немного подтормаживает. Скорее всего нужно будет переходить на графику, проконсультируюсь чуть позже с опытными коллегами.
Ошибка 5: Экономия на протоколе передачи
Цветовые эффекты немного скудные, недостаточная цветопередача, т.к. сэкономил на протоколе. Рассчитать всё в теории — легко, но опыт подсказывал, что теоретические пределы скорости не практике недостижимы, боялся не получить требуемую частоту обновления, поэтому заранее ужимал протокол, хотя при таком размере поля можно было особо не беспокоиться.
Ошибка 6: Размытая граница пикселя и неравномерность засветки
Мне не нравятся размытые контура пикселей, хочется сделать их более чёткими, это будет смотреться гораздо круче. Качество засветки тоже можно улучшить, используя более глубокую рамку и правильное оргстекло.
Ошибка 7: Дешёвая светодиодная лента
Было куплено около 90 метров "высококлассной" китайской светодиодной ленты… которая оказалась явно б/у, имела разное свечение и много раз перегорала. Но тут вынужденная экономия на прототипе.
Идеи на будущее:
Расширение группы до 9 шт. — это будет явное удешевление, повышение надёжности связи за счёт уменьшения устройств на шине и расширение теоретического предела площади игровой зоны;
Соты! Очень хочу гексагональное игровое поле, это должно выглядеть весьма круто!
Настенные кнопки;
Быстрые соединения. Из-за использования в прототипе винтовых клеммников, сборка платформы перед детским праздником у меня заняла около 2.5 часов, что очень много. Буду прорабатывать быстрые соединения;
Ну и конечно, разные-разные механики игр! В голове масса идей: всякого рода змейки, пакман, эстафеты, арканоид, захват территорий, повтор рисунка, те же танцы и твистер…
При выборе кодового имени проекта было несколько разных вариантов. Больше всего мне симпатизирует название «Pixel Quest» ввиду широкого распространения в народе понятия «квест-комната». Сразу занял под это дело домен и, как это водится, завёл отдельный ТГ канал @pixel_quest для публикации прогресса разработки и дальнейших обсуждений с заинтересовавшимися читателями. Заходите в гости, буду держать в курсе событий.
На Пикабу пишу ради новых знакомств, поиска поддержки и идей для дальнейшего развития проекта. Я технарь, а не предприниматель, и, если честно, плохо представляю, как правильно превратить это в бизнес. Я не умею в эти ваши «найди инвестиции / собери команду / захвати мир» (но это пока что), не умею писать бизнес-планы, хочу просто делать интересный продукт и радовать людей. Буду рад любым советам! Личный телеграм для связи: @AnatoliyB
В ближайший планах найти подходящее помещение у себя в городе (Смоленске) для построения первой комнаты с увеличенной игровой зоной и полноценного тестирования. Хочу развивать идею как по направлению целых игровых квест-комнат, так и небольших игровых платформ 4-6 м2 для установки в детских комнатах или сдачи в аренду на детские праздники.
Итого:
Потрачено: ~300 тыс. руб.
Заработано: 0 руб.
Удовольствие от процесса разработки и праздника для детей: бесценно!
Спасибо всем, кто дочитал! Пишите свои мысли и идеи игр в комментариях!
Привет!
Несколько месяцев назад я публиковал пост, о своем роботе.
Сейчас я хотел бы поделиться обновлением: недавно я написал клиентское приложение (на питоне) для Steam Deck (игровая консоль).
Теперь роботом можно управлять через WiFi, видеть логи и стрим с камеры.
Исходные коды клиентского и серверного приложений доступны в моем github https://github.com/stanislau-arkhipenka/arr
Привет, уважаемые пользователи Пикабу! Здравствуйте, любители таких тем как DIY ( 'do it yourself' - сделай сам), IoT ('Internet of things' - интернет вещей) и так далее.
Пару лет назад я обзавелся новым хобби, точнее, воскресил старое - микроэлектроника и
радиотехника. Что и как из этого получилось я опишу далее, а пока вот фото для затравки.
Сейчас, конечно, с паяльником сидеть гораздо приятней и проще чем 20+ лет назад. Все радиодетали в доступности, интернет просто кишит различной информацией, необходимой для того, чтобы начать что-то изучать на эту тему. Кроме того, стали доступны всякие вещи для создания конструкций, корпусов. Я уже молчу об огромном количестве готовых наборов для начинающих, которые могут заинтересовать этой увлекательной и полезной темой подрастающее поколение. Интерес к робототехнике также подогревается и тем, что она тесно связана с программированием, что как никогда актуально. Начинать обучение программированию, когда имеешь дело не с абстрактными данными а с чем-то, что можно пощупать, запустить или отправить в плавание - на мой взгляд хорошая идея. Это была минутка агитации и если вам стало интересно, какие вещи, например, можно сделать в наше время домашних условиях своими руками, пожалуйста, продолжайте чтение.
Прежде чем продолжить, хочу сказать, что не считаю, что тема легкая и что это для всех, ведь каждый человек уникальный со своими особенностями. Ведь нужно обладать определенными качествами и образованием, чтобы делать определенные вещи. Но есть один важный момент: никогда не поздно чему-то учиться, и при правильном подходе, если какая-то тема стала вам интересна можно чего-то в ней добиться. Не каждый станет музыкантом, но если музыка нравится, можно для начала хотя бы научиться в ней разбираться.
В марте 2021 года я начал проявлять интерес к Arduino. До этого я всегда считал это чем-то недостижимо сложным, чем-то на грани физического и цифрового миров. Я программист и имею небольшие навыки в радиотехнике, чтобы, собрать, например усилитель ШИМ-сигнала, или подружить 3.3v логику с пятивольтовой, или сделать гирлянду на елку, или свет для своих перцев, которые выращиваю дома. То есть имею базовые представления о работе полупроводников и имею навыки обращения с паяльником. Радиотехнику я забросил давно, но еще раз скажу, что за 20 с лишним лет многое изменилось, стало значительно легче и доступней, поэтому вернуться в этот удивительный мир транзисторов, резисторов, конденсаторов, микросхем и катушек мне было не сложно. Arduino, как я писал, мне казалось сложным, поэтому для начала мне пришлось купить стартовый набор, как например вот этот:
И.... сделать конечно, же "мигалку". Моему восторгу от наблюдения за мигающим светодиодом не было предела и меня затянуло, ведь до этого частоту мигания на К155ЛА3 в юности я мог регулировать только конденсатором и резистором, а теперь я мог сделать это программно, и это казалось нереально крутым. Часть того, что из этого вышла, я и опишу далее.
Чтобы не потерять интерес к новой теме мне надо было поставить перед собой цель. Что-то, что я мог бы использовать с пользой или для игры. Что-то, что сочетало бы в себе сразу несколько технологий и подходов. Вероятно я где-то увидел, какие прикольные танки делает народ и тоже решил сделать нечто подобное. В интернете много статей и роликов на тему создания подобных вещей. Кто-то использует Arduino, кто-то другие платформы вроде Raspberry Pi (и подобных Orange/Banana/Rock). Кто-то использует и то и другое и можно без хлеба. Все зависит от цели. Моя изначальная цель была создание танка, которым можно было бы управлять по BLE с айфона или андроида, используя свое приложение. Под управлением я понимал движение вперед, назад, в стороны и разворот. Для гусеничного хода это регулируется скоростью и направлением вращения моторов, расположенным по сторонам. В этот момент я наконец-то узнал что такое ШИМ и как его применять. И для меня вдруг стало понятно, почему почти вся эта техника с приводами на заводах так пищит :). Кроме того, требовалось как-то взаимодействовать по Bluetooth, но тут особой проблемы не было, поскольку по работе я работал с iBeacon и имел какие-то представления о том, что и как делать. Танк должен был быть автономным, ведь глупо было бы в наше время управлять чем-то по воздуху, если это что-то ограничено длиной провода до источника питания :). Поэтому также пришлось изучить и правила работы со сборками Li-Ion батарей.
Итоговая сборка первой версии танка, над которой я работал пару недель состояла из:
- Три Li-Ion аккумулятора, собранные в батарею 3S с платой BMS для защиты и балансировки заряда.
- Один драйвер мотора на L298N
- Одна Arduino UNO из стартового набора
- Bluetooth модуль HM-10 (поскольку он был для меня доступен и умел в BLE, что для меня было критичным)
- Шасси танка с AliExpress. Там 2 мотора, гусеничные полотна, шестерни и крепеж для соединения конструкции. Классная вещь!
- Индикатор уровня заряда Li-Ion 3S батареи.
К сожалению, чтобы найти фотки той версии танка надо перерыть сотни гигабайт неупорядоченных картинок, но зато у меня сохранилось видео, где я сконцентрировал все свои умопомрачительные навыки в видеомонтаже (осторожно, ирония).
Управлял я этим делом пользуясь акселерометром, держа телефон как геймпад в руке и наклоняя его в сторону, куда танку надо было повернуть. Было прикольно. Пришлось решить несколько интересных задач, вроде принудительного останова механизма при потере сигнала, продумать легкий протокол данных для отправки команд и как-то попытаться синхронизовать поток этих самих данных в условиях отправки нескольких десятков команд в секунду (я стремился к максимальной отзывчивости).
Программа (или скетч, как говорят ардуинщики) потребовала воскресить навыки написания на C/C++, и я даже собрал некое подобие библиотеки для того, чтобы быть ближе к плюсам. Назвал ее эту штуку BoardKit, положил к себе в Bitbucket и никому не показывал, потому что чувствовал, что ходу этой теме не будет. Итоговая программа в .ino файле выглядела примерно вот так (заранее прошу прощения за выкладывание кода в скринах из VS Code, но там нет ничего, что было бы неудержимо хотелось скопировать :) )
Ах, да, изначально я отрицал такие IDE как VS Code и писал в Xcode, а компилил и заливал через Arduino IDE, что добавило мне определенных сложностей, но помогло хотя бы работать в более-менее нормальном (а главное привычном) IDE, но на таких извращениях мы не будем заострять слишком много внимания.
MasterScheme тут - это модель платы. Она должна была описывать составляющие ее компоненты и логику взаимодействия между ними. Ашник соответствующего класса выглядел примерно вот так:
При чем тут Habanero? Я люблю острые перцы и решил, что интересные модули буду называть именем сорта перцев. Просто ради прикола и какого-то порядка в именовании. Саму логику (*.cpp) я прикладывать не буду, потому что пост и так обещает быть довольно большим, но если тема станет интересна аудитории, то я запилю отдельный пост, приложив исходники на гитхабе не обещая что они соберутся, так как я больше их не использую, и потому что изврат с Xcode, помните? :) Хотя что-то подсмотреть в них наверное можно.
Так или иначе, мой танк поехал. Правда ездил он наверное пару дней, потому что окрыленный своим успехом я начал исследовать другие, связанные с робототехникой моменты, такие как серво-приводы, датчики приближения, датчики расстояния и многое другое. Я аугментировал танк пока было время, даже как-то приделывал к нему управляемую руку - хваталку и в конце концов переложил его на Arduino Mega, чтобы можно было независимо использовать ШИМ для моторов и сервоприводов. Обвесил ультразвуковыми датчиками расстояния и попытался научить его объезжать препятствия, но потом в итоге, вдоволь наигравшись поставил его на полку до лучших времен. Вот такой он был на тот момент.
Где-то год я в свободное время активно занимался Raspberry/Orange/Rock PI, Full-Stack разработкой собственной системы умного дома в квартире в симбиозе с HomeKit и управлением полива и мониторингом погоды на дачном участке с видео-наблюдением. Сейчас у меня довольно внушительная система, которую я постараюсь описать отдельным постом, если это будет кому-то интересно. Если коротко, то это бекенд на основном хосте под Docker на Raspberry Pi, который по MQTT управляет переферийными устройствами на ESP32-WROOM (например включение света в спальне), пишет в MongoDB, расположенную на RockPI 4 статистику по температуре и влажности в комнатах и на улице, а также по количеству людей в комнате. Распознает людей система на том же хосте Raspberry Pi при помощи Intel Neural Stick 2 и OpenVINO. Почти всем этим делом можно управлять с веба под тем же докером. Веб доступен в локальной сети. Бек на Express, фронт на React. И все это дело скрепляется несчетным количеством bash-скриптов. Тема, в общем-то тоже очень интересная, хотелось бы, чтобы читателям стало интересно и про это почитать :)
Вернемся к главной теме: роботанку. C завершением дачного сезона я решил его воскресить, но уже с учетом технологий, которые я освоил за тот год, пока он пылился на полке.
Во первых, я окончательно ушел от Arduino, и от Esp8266, коих за год имел неосторожность накупить на алике за дешево по акциям приличное количество. ESP32 значительно лучше и современней. Прошивки для ESP32 я делаю на основе Mongoose OS - великолепная вещь, которая позволяет во первых, писать на MJS, что мне было приятней, чем C или MicroPython, а также уже имеет в себе интерфейсы для работы с множеством IoT штук на более-менее высоком уровне, чтобы не тратить время на то, что я назвал BoardKit'ом :). Также я решил встроить танк в свой умный дом, пожертвовав тем самым отзывчивостью. А именно управлять им, как я управляю светом в какой-либо комнате: какой-то клиент шлет HTTP запрос с неким параметром на бекенд, он по MQTT отправляет сообщение с обновленным конфигом в брокер (кстати, Mosquitto наызвается), тот рассылает по устройствам, которые подписаны на нужный топик, устройство получает обновленный конфиг и переходит в новый стейт. Опять же, если будет интерес, я обязательно опишу более детально и пошарю исходники. Схема довольно громоздкая, но универсальная, стабильная и расширяемая. Также у меня давно скучала одна плата ESP32-CAM и я решил всунуть в танк и ее, чтобы видеть куда тот едет (используя подсветку, если темно), управляя без необходимости его видеть. Плюс надо было уйти от необходимости установки мобильного приложения в сторону возможности управления с веба, тем более опыт создания WEB-приложений накопился довольно значительный. А еще надо было поработать над аварийной остановкой механизма в случае упора в препятствие или переворота. Ну и еще я хотел видеть уровень заряда батареи в вольтах а не в полосочках, как было раньше. Также я пробрел дешевый лазерный модуль и решил его тоже использовать для 'пиу-пиу бластера' для котиков. Вот двое из трех:
По мере создания переферийных устройств для умного дома я насобачился делать всякие коробочки из вспененного ПВХ на любой вкус и цвет. У меня есть 2 листа: черный и белый, толщиной 3 мм. Клею я их клеем Cosmofen SL-660. Записывайте лайфхак: клей белый и чтобы склеивать черный лист ПВХ так, чтобы не было белых полос на месте склейки я добавляю порошок для лазерного принтера прямо в клей, который выдавливаю порционно в шприц, а уже из шприца выдавливаю когда мне нужно. Эти нехитрые манипуляции позволяют создавать коробочки почти любой сложности на приличном уровне. Вот например я делал 'умный' диммер на 2 канала в довольно простом, но аккуратном корпусе:
Поэтому, вдохновившись Cybertruck'ом от Tesla (шутка, конечно) я запили в итоге это.
Моторами, вспышкой для камеры, лазером и сбором данных с ИК-датчиков препятствий и коммуникацией с остальной частью умного дома занимается прошивка для ESP32-WROOM DevKitC. Вот такая:
Потоковый сервер с камеры - на ESP32-CAM. Вот такая:
Исходник прошивки для нее прям один-в-один с примеров, которые предлагает Arduino IDE для AI Thinker. Единственное что я сделал - это исправил качество видео по умолчанию и добавил дополнительные попытки подключения к вайфаю, если тот не может подключиться в течение некоторого времени. Я не уверен, что это работает, потому что подебажить не хватило времени, но вроде хуже не стало :D
Остальная начинка, это все те же 3 Li-Ion батареи, BMS, L298N, датчик тока INA219, парочка полевиков для мощного светодиода вспышки и включения ESP-CAM и 3 ИК-датчика препятствий: спереди, сзади и снизу, чтобы остановить моторы при перевороте или подъеме.
Часть WEB-страницы для управления танком в итоге выглядит вот так:
В центре - кнопка останова. Стрелочки - думаю понятно. Каждое нажатие на стрелочку добавляет или отнимает X% мощности на нужной гусенице. В верхнем левом углу - включение лазерной указки, в верхнем правом - переключение между обычным и 'спортивным' режимом
По сути, спортивный режим - это просто бОльшие значения X на которые мы изменяем мощность двигателей при каждом нажатии на кнопку управления. Предназначен для езды в зале, где места много и не требуется точность прохождения 'узких' участков. Если нужна точность, тогда включаем обычный режим и на самой низкой мощности черепашьим ходом ювелирно заворачиваем куда надо.
Конечно, над внешним видом еще можно поработать. Убрать сопли клея со стыков, сгладить углы. Вид сзади.
На ИК датчики надеть колпачки - экраны (если кто знает как они называются, скажите, пожалуйста 🙏 ), что должно исключить ряд моментов, когда датчик не срабатывает когда нужно.
Короче, нет предела совершенству, но в таком виде его уже не стыдно показать обществу :)
Бесспорным и сильным недостатком этого девайса является его жесткая привязка к моей домашней сети. Но при желании можно и от этого избавиться. Пока меня это не беспокоит. Серийное производство я налаживать не собираюсь и делаю чисто для себя в качестве хобби и самообучения в свободное от работы время.
Прошу прощения за большое количество текста, ошибки и мизерную часть технической информации, но, повторюсь - если будет заинтересованность, я обязательно опишу на более детальном уровне ту или иную часть системы, о которой вел речь. Кроме того, если будут какие-то вопросы в комментариях, то я по мере сил и знаний постараюсь ответить. А напоследок еще немного видео с моментами управления танком.
Дорогие друзья, для чего я сделал этот пост? Тема кажется мне интересной и я уверен, что многим тоже зайдет. Кроме того, у меня накопился некоторый опыт в вопросах DiY, IoT и при необходимости если будут какие-то вопросы, я могу попробовать ответить, или подсказать… Поскольку знаю, каково это искать решение какой-то дурацкой проблемы на форумах 10-ти летней давности на условном китайском языке. Кроме того, лично мне очень понравилась та связка технологий, которую я использую в своём умном доме, возможно она поможет кому-нибудь решить какие-то технические вопросы. Ну и конечно же, послушать дельные советы ребят, которым есть что сказать и направить на путь истинный.
Спасибо за внимание, будьте здоровы!