Доска для инструментов
Бюджетный вариант навести порядок в гараже. После ремонта пола остались обрезки osb 12 мм, скрутил между собой и повесил на стену в нише. Идея не новая, но вдруг кого наведёт на мысль. Сейчас конечно продаётся куча специализированных перфопанелей и различного крепежа к ним. Но как вариант, из того, что валялось просто так, сойдёт.
Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом?
Я, как и многие мои читатели, очень люблю игры. Уже довольно обширное число моих статей было посвящено ремонту и моддингу самых разных игровых консолей — как китайских «нонеймов», так и брендовых PSP и PS Vita! Однако, меня тянет к железу не только желание отремонтировать и поставить в строй «устаревшие» девайсы, но и мания делать и созидать что-то своё! А ещё я очень люблю программировать игры и графику сам. Недавно я загорелся идеей разработать с нуля свой портативный «тетрис»: от схемы и разводки платы, до написания прошивки и игр под нее. Что получается, когда программист, который поставил электронику практически во главе своей жизни, пытается сделать свое устройство? Читайте в статье!
❯ Как я к этому вообще пришел?
Проекты разработки самодельных игровых приставок стали очень популярны к нашему времени. Если раньше embedded-разработка была достаточно дорогой и доступной лишь для избранных, то сейчас на рынке можно найти все что хочешь — и мощные микроконтроллеры с кучей периферии за 300 рублей, и готовые дисплейные модули по 250 рублей, и макетные платы с удобными dupont коннекторами за весьма скромные деньги.
Собрать свой гаджет в пределах одной-двух тысяч рублей стало вполне реальным. Люди собирают себе самые разные устройства, а игровые приставки — одна из самых популярных тем. Однако, для многих людей, которые только начинают знакомится с миром embedded-электроники, собрать консоль в своем корпусе с Raspberry Pi на борту и RetroPie в качестве оболочки — за счастье.
Однако есть определенная категория электронщиков, к которой отношусь и я — нам нужно делать всё с нуля! Свои проекты я стараюсь реализовывать на самопальных фреймворках/движках, точно также я мыслю и в подходе электроники — ну не могу я использовать чужие решения и стараюсь разобраться в вопросе сам. За моей спиной есть весьма интересные демки. Например, это моя игрушка с незамысловатым названием «ралли-кубок ТАЗов», которую я написал за неделю с нуля (рендерер, звук, ввод, редактор уровней — все свое) в 2022 году:
Вот так, с любовью программировать игры, я и пришел к мысли сделать свою консоль, так как вижу её именно я. Только без чужих библиотек и наработок, но не прям уж bare metal. Сел я и начал думать, на чём же мы будем строить наш игровой девайс!
❯ Из чего будем делать?
Как я уже говорил выше, в наше время выбор железа для создания своих девайсов большой — тут и мощные микроконтроллеры/одноплатники, по производительности сравнимые с телефонами 2005-2006 годов, и различная периферия — аж глаза разбегаются. Однако проектировать будущую консоль нужно исходя из некоторых требований.
Характеристики моего девайса следующие:
Процессор: двухядерный ARM микроконтроллер RP2040 на частоте 133мгц, построенный на архитектуре Cortex-M3. Сам процессор распаян на плате Raspberry Pi Pico.
ОЗУ: 260 килобайт SRAM, встроена в процессор. Немного, но если грамотно распоряжаться ресурсами — то хватит.
ПЗУ: 2Мб SPI Flash-памяти, также распаяны на плате.
Дисплей: 1.8" TFT-матрица с разрешением 128x160. Выбор разрешения обусловлен производительностью будущей консоли — процессор банально не сможет заполнять матрицу с относительно высоким разрешением.
Ввод: 6 кнопок, 4 из которых — направление, 2 — действий. В будущем могут добавиться еще несколько.
Звук: динамик. Пока не знаю, с чего рулить будем — возможно, возьмем «железный» ШИМ-контроллер процессора, а возможно прикрутим внешний ЦАП с i2s.
Питание: 3.7в аккумулятор BL-4C. Да, да, тот самый с Nokia и современных кнопочников! Аккумулятора, емкостью в 800мАч должно хватать хотя-бы на 4-5 часов игры. При этом зарядка АКБ обеспечивается модулем TP4056.
Весьма неплохо для самоделки, согласны? Как я уже говорил раннее, эти характеристики примерно соответствуют мобильным телефонам 2004-2006 годов — Nokia 6600, Sony Ericsson K510i, Samsung D800. Отличие лишь в ОЗУ (в телефонах её 2-4 мегабайта) и периферийных модулях типа контроллера дисплея.
На фото E398 — мобилка 2004 года выпуска, но она здесь не просто так. :)
Важную пометку нужно сделать касательно дисплеев: эти 1.8" матрицы бывают приходят с «синевой» — это не железная проблема и не совсем брак. Сам контроллер в дисплея в них сильно греется (хотя токоограничивающий резистор стоит) и негативно влияет на клей, из-за чего матрицы отклеивается от подсветки и слои поляризации начинают «синить» картинку. Лечится проклееванием подложки матрицы суперклеем.
RPi Pico я решил выбрать, поскольку информации про них достаточно мало, характеристики хорошие и пока что никто особо ничего на них не делал, тем более в рунете. А ещё у них очень удобное и простое SDK, практически bare-metal. ESP32, например, работает на FreeRTOS и имеет кучу библиотек, здесь же API простое и понятное.
Закупаем все необходимое и начинаем творить!
❯ Графика
В первую очередь нам нужно подключить дисплей и что-нибудь на него вывести. Заодно и SPI погоняем на незнакомом чипсете, благо работа с ним очень простая — задаем конфигурацию пинам (gpio_set_function), настраиваем SPI-контроллер и можно посылать данные.
SPI у RP2040 работает на частоте вплоть до ~60мгц — это достойная скорость передачи, в том числе и для быстрого вывода графики. На самом деле, SPI даже предпочтительнее чем параллельный 8080-интерфейс для использования в микроконтроллерах: дело не только в количестве занимаемых пинов, но и в возможности использования DMA!
В подобных проектах всегда нужно делать так, чтобы дисплей можно было при необходимости поменять, а желательно вообще научить работать его с несколькими контроллерами: разные дисплеи одной диагонали могут использовать разные контроллеры. В моём случае, этоST7735. Для разрешений 240x320 используются ILI9325, ILI9341, ST7789. Команды инициализации дисплея честно позаимствованы, но именно в этом нет ничего зазорного — сама система команд относительно стандартизирована, отличается лишь первичная настройка питания, гамма-коррекции и т. д — часто init sequence вставляет сам производитель в даташит.
После инициализации дисплея пробуем что-нибудь вывести. Да, все работает без проблем. Пару важных нюансов: ST7735 требует посаженный на землю CS, в воздухе его оставлять нельзя, как некоторые ILI (вы ведь навряд ли будете вешать несколько устройств на одну шину с дисплеем, когда есть вторая?) и логическое состояние 1 на пине RESET (в воздухе и «на земле» он будет висеть в постоянном ресете).
Для полустатичной графики, можно обойтись лишь командами дисплея — например, тут есть удобные функции для заливки прямоугольников (setArea и пишем цвет без остановки) или скроллинга. Сделано это для более слабых микроконтроллеров. Нам они не подойдут — выделяем память под фреймбуфер/бэкбуфер и настраиваем канал DMA для разгрузки процессора в процессе передачи данных:
Саму картинку подготавливает процессор: именно он рисует картинки и он же делает их прозрачными. На него ложится основная работа, однако мы можем ему помочь разгрузиться, если отдадим передачу уже подготовленного кадра на дисплей на DMA (Direct Memory Access) — устройство в микроконтроллере, которое позволяет процессору настроить параметры передачи данных, а DMA их будет сам копировать из памяти или в память. Таким образом, можно реализовать асинхронное копирование нескольких блоков ОЗУ, или, как в моем случае — передачу буфера кадра на дисплей, пока процессор готовит следующий. Чем больше разрешение — тем больше эффекта от DMA!
Кроме того, важно выбрать формат цвета для нашего дисплея: я выбрал 2-х байтный RGB565 (5 бит красный, 6 бит зеленый, 5 бит синий). Это экономичный формат который выглядит красивее палитровой графики и кушает не так уж и много драгоценной памяти. Кроме того, на данный момент мы умеем отрисовывать изображения произвольных размеров с прозрачностью — вместо альфа-канала здесь используется так называемый colorkey — концепция, очень близкая к хромакею, только она берет в качестве трафарета конкретный цвет. В нашем случае это «255 0 255» (ярко розовый).
Общая производительность рендерера порадовала: он легко осилит около сотни-двух различных спрайтов с адекватной производительностью, в зависимости от их размера. Но для такого разрешения экрана и будущих игр — это неплохой результат!
❯ Ввод
Теперь нам нужно как-то управлять нашим девайсом. Для этого пора сделать реализовать геймпад: в рамках этой статьи, я собрал его на макетке.
Кидаем общий минус на все кнопки, а второй вывод размыкателя кидаем на соответствующие пины GPIO. Я выбрал предпоследние т. к. на них ничего важного не висит, текущая конфигурация занимает 6 пинов. На фото выглядит не очень красиво — на то она и макетка.
Переходим к реализации драйвера. Игры могут слушать события кнопок из специальной структуры —CInput, где на каждую кнопку выделено по одному полю. В будущем конфигурация геймпада может поменяться — например, я захочу добавить аналоговый стик.
Есть ещё способ реализации больших клавиатур и геймпадов: когда все кнопки вешаются на пару линий, где на выходе каждой кнопки есть резистор определенного номинала. ЦАП микроконтроллера считывает это значение (допустим — 1024 это вверх, а 2048 — вниз) и таким образом определяет текущую нажатую кнопку. Таким раньше любили промышлять китайцы, из-за чего нельзя было нажать одновременно вверх и вправо, или вниз и влево и т. п.
❯ Пишем игру
Теперь у нас есть минимально-необходимая основа для написания игры. Первой игрой для своей консоли я решил написать классический шутер в космосе — летаем на кораблике и сбиваем врагов, попутно уворачиваясь от их пулек. Заодно проверим консоль на стабильность.
Писать я её решил в классическом C-стиле, как и принято в embedded-мире: без std и тем более stl, без ООП и виртуальных методов, аллокаций по минимуму. В общем, примерно как писали игры под GBA! В первую очередь, подготавливаем спрайты нашей игры, прямо в пейнте, а затем конвертируем их в представление обычного массива байтов в виде header-файла. На первых порах это удобнее, чем делать свой ассет-пул:
Архитектуру я организовал в виде нескольких подфункций, каждая из которых занимается своим стейтом (world/menu) и своими объектами (playerUpdate) и их отдельные версии для отрисовки. Сами игровые объекты я описал в виде структур, а центральным объектом сделал CWorld.
Время я решил описывать в тиках, а не миллисекундах, как я обычно это делаю на ПК — у консоли железо одно и там следить за этим нужно меньше.
Единственные аллокации, что я использовал — это для пулов с пулями, и с врагами. Оба пула четко ограничены — до 8 врагов на экране, и до 16 пулек — вполне хватает. Динамические аллокации помогли мне найти серьезную ошибку в коде — в один из моментов игра просто валилась с Out Of Memory. После того, как я немного поменял условия и делал аллокейты тех же самых объектов каждый кадр — игра переставала крашится. Причина оказалась простая — невнимательность (вместо >= было >), по итогу при отрисовке спрайтов за пределами экрана, программа сама начинала портить вунтренние структуры аллокатара и самой игры (проявлялось в глюках и телепортациях). После фикса, все заработало как нужно. :)
Ну и для основной части геймплея с выстрелами и столкновениями, я предусмотрел несколько функций, которые спавнят игровые объекты и сами управляют пулом. Противники обновляются как обычно, для коллизий используется AABB (axis aligned bounding box, ну или его 2D-подмножество в виде rect vs rect).
По итогу, у нас получилось простенькая, но рабочая игрушка, которая без проблем работала почти все время, что я писал этот материал, а значит устройство работает стабильно. И я очень горд, что у меня получилось сделать рабочий прототип своего собственного гаджета!
Ниже выкладываю принципиальную схему устройства, она очень простая, поэтому смысла делить ее на несколько листов нет. Разводить учился, читая сервис-мануалы и схемы :)
❯ Заключение
Полная цена сборки прототипа составила:
Raspberry Pi Pico — 557 рублей (но я брал на Яндекс Маркете, на «алике» дешевле — около 300 рублей).
Дисплей — 380 рублей, заказывал на «алике».
Макетка — 80 рублей, в местном радиомагазине.
Кнопки. По 5 или 10 рублей штучка, пусть будет 60 рублей.
По итогу, прототип мне обошелся в 1077 рублей. Бюджетненько, да, с учетом того, что можно сделать еще дешевле? Я тут так подумал, у меня есть желание развивать и поддерживать консоль в будущем и под консоль уже можно делать что-то своё… может, если вам будет интересно, делать их на заказ? Соберу вам по себестоимости (до 1.000 рублей) + доставка, если хочется попрограммировать под что-то маленькое, но самому паять не хочется. Мне было бы очень приятно. Пишите в личку или комменты, если вас заинтересовало бы такое! :)
Весь процесс разработки этого девайса занял у меня всего несколько дней. Я и до этого понимал концепцию работы 2D-графики на видеокартах прошлого века, поэтому ничего особо нового я для себя не открыл. Однако, я попробовал свои силы в разработке игровых девайсов, которые могут приносить удовольствие — как ментальное от самого процесса сборки и программирования, так и физическое от осознания того, что игра на нем работает. :)
Однако, это далеко не конец проекта! У нас ещё много работы: нужно развести и протравить полноценную плату, реализовать звук и API для сторонних игр, придумать корпус и распечатать его 3D-принтере. Кстати, я ведь обещал что скоро будут и другие интересные проекты с 3D-принтером: как минимум, мы доделаем предыдущий проект игровой консоли из планшета с нерабочим тачскрином и RPi Pico.
Пост подготовлен при поддержке TimeWeb Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать новые статьи каждую неделю!
Разработка настолок не останавливается
Помните мой пост с пиццей? Наконец-то получилось с ребятами сделать скромный видео обзорчик для нее!
Простое в изготовлении садовое кресло
Садовое кресло :
Рейки длиной 375 мм — 6 шт.;
дополнительные завершающие детали по 875 мм — 2 шт. (задние ножки);
для спинки — 4 элемента по 787 мм, 2 бруска по 745.
для сиденья — перемычки по 228 мм — 9 шт, 35/35, 35/40 и выше какие вам угодно для вашего веса!
Взял здесь: https://t.me/dacha_i_remont/225
Я сделал самодельный Dualshock 4
Приключение на 20 минут, думал я. Купил все детальки и собрал.
Спойлер для ЛЛ и спидранеров ленты Пикабу: Все работает. Цена незначительно ниже чем оригинал в магазине. Не рекомендую так делать, если нет опыта в электронике.
Погнали
Теория к поиску запчастей
У Дуалшока за годы производства накопилось примерно 5 версий. Все они абсолютно разные как по электронике, так и по деталям корпуса, всё различной степени совместимости друг с другом. А внешне отличаются только по наличию подсветки тачпада у двух последних версий (так называемых v2). Первые пару версий были также с некоторыми вариациями деталей внутри корпуса для рынка США и Японии. У последних 3-х? есть 2 вида вариаций тачпада, причем у последней версии вариации тачпадов определённо несовместимы друг с другом. При покупке материнки последней версии, нужно уточнять её совместимость у продавца. Это если максимально вкратце.
На Али можно найти так называемые сеты или киты из наборов деталей, например корпуса. Мне удалось найти сет из деталей где есть всё кроме электронной начинки. Если хотите больше вариаций цветов корпуса, то наверно лучше собирать старые модели геймпадов - JDM-001 или JDM-011.
Я примерно ориентировался по этой картинке, найденной в Гугле:
Из всех купленных запчастей, оригинал только материнка. По виду материнка похоже на "Refurbished" - есть некоторые следы ремонта. Стики, как минимум потенциометры меняны (не думаю что в оригинале стояли черные), и стоят резисторы для правки дрифта.
Отвечая на вопрос оригинальности и реплики - геймпад можно считать оригиналом именно из-за материнки.
Сборка
В целом сборка не сложнее пазла, есть разборы на iFixit и видосы на Ютубе.
Первое с чем я столкнулся в сборке - это отсутствие прокладки под мембрану кнопок. В продаже их нет. И да, в некоторых местах, такое качество литья. Но это совсем не доставило проблем.
В качестве прокладки подошли пара слоёв вспененной штуки, которая была наклеена на моторчики. На JDM-055 моторчикам это не нужно.
Также динамик оказался немного не той модели и упорно не хотел держаться в корпусе. Вспененная штука также помогла, хорошая вещь. Я так и не разобрался как протестировать динамик, поэтому будем считать что всё ОК. Динамик должна закрывать пылезащитная сеточка - это вторая и последняя деталь которую не купить.
Триггер в сборе. Смазал их силиконовым смазкой на всякий.
Кнопки держатся за счёт резинок, что сильно облегчает сборку.
Засовываем кишки в верхнюю половинку корпуса.
И прикручиваем материнку.
Ещё одна проблема. Один винтик не подходит по длине чтобы прикрутить плату LED/USB к нижней половинке корпуса. Выручил напильник дремель. Кстати, всего в геймпаде 6 винтиков.
И осталось только закрутить всё вместе. Я так думал, но я ошибался.
Отдельное слово про батарейку. Та что я заказал, будет идти ещё долго, а собрать всё хочется. Внезапно, почти (с незначительными доработками в виде самодельного разъёма) идеально подошла батарейка от Нокии - BL-5C. Знал бы, не покупал бы. Батарейке не менее 66 миллионов лет и она была свидетелем как динозавры массово превращались в нефть. Несмотря на это, после небольшой зарядки, она работает как новая. Нет, синей изоленты не нашёл.
Как вы догадались геймпад после полной сборки не заработал. Подключив к блоку питания, я обнаружил что он после нажатия кнопки "PS", начинает потреблять небольшой ток и как бы работает, но лампочка не зажигается. Причина оказалась следующей - сломана дорожка на плате LED/USB.
Плата после ремонта. Палец для масштаба. Зацените качество ремонта, я сделал. Кто молодец?
После ремонта лампочка весело загорелась всеми цветами сразу.
Чтобы батарейка не хлябала внутри, добавил небольшой кусок пенополиуретана вырезанного в точности по размерам батарейки.
В целом всё работает. Всё настраивается в DS4Windows. Мертвых зон нет. Дрифта нет. Видео для любителей циркулярности стиков:
Единственный минус - есть нюанс с зарядкой. Геймпад заряжается не от всех кабелей. Из 3-х предложенных, ему по какой-то причине нравится только один.
Заключение
Сборка заняла пару вечеров. Ещё пару недель я активно изучал конструкцию геймпада и рыскал Али в поисках подходящих деталей. Есть немного подводных камней. Для сборки нужен инструмент. Сложность, если сравнивать с DIY KIT наборами с Али - 10/10. Но приключение того стоило. Мой внутренний самоделкин удовлетворён на 128%.
Цена
По цене довольно интересно. На момент покупки по цена самодельного геймпада вышла незначительно ниже чем новый Дуалшок в ДНС с максимально возможной скидкой. Ну можно ещё скинуть с самодельного рублей 450, если бы я не поспешил с покупкой батарейки. А если уж делать совсем кастомный геймпад, с цветом корпуса и кнопок строго на свой вкус, покупая всё по-отдельности, то цена будет дороже.
Так что если хотите Дуалшок как можно дешевле, то логичнее искать подержанный. На барахолках очень много подделок, все они как я говорил, отличаются заметными мертвыми зонами у стиков и триггеров.
Ссылки на запчасти (отсортировано по магазинам):
Материнка и мембрана под кнопки:
Тачпад и USB плата:
Набор из корпуса, кнопок и прочими деталями.
Винтики, динамик и моторчики:
Батарейка (не рекомендую, покупал максимально дешевую, не посмотрев отзывы, но пусть будет):
P.S. Заказал Холл стики, как придут будет ещё одна серия.
Путь мыловара
Похвастаться тем, что моя семья в пятом поколении варит мыло, я не могу. Хотя, с уверенностью могу утверждать, что моя бабушка в далёкой деревушке суровой ( на мой взгляд) Сибири точно варила мыло для хозяйственных нужд, мама помнит. Жаль, что рецепт не сохранился.
Свою собственную мыловарню я пока не открыла, но в этом направлении уверенно лежу и изучаю письменный материал по этой теме.
Попробовать решила самый доступный и простой вариант для понимания, а надо мне оно вообще... вдруг, не моё... вдруг не понравится.
Короче, купила брикет основы, форму самую, на мой взгляд, подходящую, краситель, пару ароматов .
Инструкция проста - основу нарезаем, растапливаем, капаем краситель и аромат по вкусу.
Всю смесь в форму заливаем и терпеливо ждём
На этом этапе опытный мастер мыльных дел спиртом бы все пузыри убрал, но это моё первое творение и пузыри совсем не смутили. Мыло застыло и тут же прошло проверку.
Сын оценил цвет, форму, аромат - всё, как ему нравится и кусок вполне удобный. На мой взгляд минус был только один - мыло почти не пенится, если не приложить достаточно усилий.
Ребенок с радостью бежит мыть руки мылом-лапкой, а я на поиски рецепта мыла с 0.
Поиграем в бизнесменов?
Одна вакансия, два кандидата. Сможете выбрать лучшего? И так пять раз.