Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Я хочу получать рассылки с лучшими постами за неделю
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
Создавая аккаунт, я соглашаюсь с правилами Пикабу и даю согласие на обработку персональных данных.
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam

Топ прошлой недели

  • Oskanov Oskanov 8 постов
  • alekseyJHL alekseyJHL 6 постов
  • XpyMy XpyMy 1 пост
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая кнопку «Подписаться на рассылку», я соглашаюсь с Правилами Пикабу и даю согласие на обработку персональных данных.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Новости Пикабу Помощь Кодекс Пикабу Реклама О компании
Команда Пикабу Награды Контакты О проекте Зал славы
Промокоды Скидки Работа Курсы Блоги
Купоны Biggeek Купоны AliExpress Купоны М.Видео Купоны YandexTravel Купоны Lamoda
Мобильное приложение

Raspberry pi

С этим тегом используют

Своими руками Arduino Электроника Linux Программирование YouTube Компьютер Все
513 постов сначала свежее
440
monobogdan
monobogdan
1 год назад
TECHNO BROTHER

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом?⁠⁠

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Я, как и многие мои читатели, очень люблю игры. Уже довольно обширное число моих статей было посвящено ремонту и моддингу самых разных игровых консолей — как китайских «нонеймов», так и брендовых PSP и PS Vita! Однако, меня тянет к железу не только желание отремонтировать и поставить в строй «устаревшие» девайсы, но и мания делать и созидать что-то своё! А ещё я очень люблю программировать игры и графику сам. Недавно я загорелся идеей разработать с нуля свой портативный «тетрис»: от схемы и разводки платы, до написания прошивки и игр под нее. Что получается, когда программист, который поставил электронику практически во главе своей жизни, пытается сделать свое устройство? Читайте в статье!

❯ Как я к этому вообще пришел?


Проекты разработки самодельных игровых приставок стали очень популярны к нашему времени. Если раньше embedded-разработка была достаточно дорогой и доступной лишь для избранных, то сейчас на рынке можно найти все что хочешь — и мощные микроконтроллеры с кучей периферии за 300 рублей, и готовые дисплейные модули по 250 рублей, и макетные платы с удобными dupont коннекторами за весьма скромные деньги.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Собрать свой гаджет в пределах одной-двух тысяч рублей стало вполне реальным. Люди собирают себе самые разные устройства, а игровые приставки — одна из самых популярных тем. Однако, для многих людей, которые только начинают знакомится с миром embedded-электроники, собрать консоль в своем корпусе с Raspberry Pi на борту и RetroPie в качестве оболочки — за счастье.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу


Однако есть определенная категория электронщиков, к которой отношусь и я — нам нужно делать всё с нуля! Свои проекты я стараюсь реализовывать на самопальных фреймворках/движках, точно также я мыслю и в подходе электроники — ну не могу я использовать чужие решения и стараюсь разобраться в вопросе сам. За моей спиной есть весьма интересные демки. Например, это моя игрушка с незамысловатым названием «ралли-кубок ТАЗов», которую я написал за неделю с нуля (рендерер, звук, ввод, редактор уровней — все свое) в 2022 году:

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу


Вот так, с любовью программировать игры, я и пришел к мысли сделать свою консоль, так как вижу её именно я. Только без чужих библиотек и наработок, но не прям уж bare metal. Сел я и начал думать, на чём же мы будем строить наш игровой девайс!

❯ Из чего будем делать?


Как я уже говорил выше, в наше время выбор железа для создания своих девайсов большой — тут и мощные микроконтроллеры/одноплатники, по производительности сравнимые с телефонами 2005-2006 годов, и различная периферия — аж глаза разбегаются. Однако проектировать будущую консоль нужно исходя из некоторых требований.

Характеристики моего девайса следующие:

  1. Процессор: двухядерный ARM микроконтроллер RP2040 на частоте 133мгц, построенный на архитектуре Cortex-M3. Сам процессор распаян на плате Raspberry Pi Pico.

  2. ОЗУ: 260 килобайт SRAM, встроена в процессор. Немного, но если грамотно распоряжаться ресурсами — то хватит.

  3. ПЗУ: 2Мб SPI Flash-памяти, также распаяны на плате.

  4. Дисплей: 1.8" TFT-матрица с разрешением 128x160. Выбор разрешения обусловлен производительностью будущей консоли — процессор банально не сможет заполнять матрицу с относительно высоким разрешением.

  5. Ввод: 6 кнопок, 4 из которых — направление, 2 — действий. В будущем могут добавиться еще несколько.

  6. Звук: динамик. Пока не знаю, с чего рулить будем — возможно, возьмем «железный» ШИМ-контроллер процессора, а возможно прикрутим внешний ЦАП с i2s.

  7. Питание: 3.7в аккумулятор BL-4C. Да, да, тот самый с Nokia и современных кнопочников! Аккумулятора, емкостью в 800мАч должно хватать хотя-бы на 4-5 часов игры. При этом зарядка АКБ обеспечивается модулем TP4056.


Весьма неплохо для самоделки, согласны? Как я уже говорил раннее, эти характеристики примерно соответствуют мобильным телефонам 2004-2006 годов — Nokia 6600, Sony Ericsson K510i, Samsung D800. Отличие лишь в ОЗУ (в телефонах её 2-4 мегабайта) и периферийных модулях типа контроллера дисплея.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу


На фото E398 — мобилка 2004 года выпуска, но она здесь не просто так. :)

Важную пометку нужно сделать касательно дисплеев: эти 1.8" матрицы бывают приходят с «синевой» — это не железная проблема и не совсем брак. Сам контроллер в дисплея в них сильно греется (хотя токоограничивающий резистор стоит) и негативно влияет на клей, из-за чего матрицы отклеивается от подсветки и слои поляризации начинают «синить» картинку. Лечится проклееванием подложки матрицы суперклеем.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



RPi Pico я решил выбрать, поскольку информации про них достаточно мало, характеристики хорошие и пока что никто особо ничего на них не делал, тем более в рунете. А ещё у них очень удобное и простое SDK, практически bare-metal. ESP32, например, работает на FreeRTOS и имеет кучу библиотек, здесь же API простое и понятное.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Закупаем все необходимое и начинаем творить!

❯ Графика


В первую очередь нам нужно подключить дисплей и что-нибудь на него вывести. Заодно и SPI погоняем на незнакомом чипсете, благо работа с ним очень простая — задаем конфигурацию пинам (gpio_set_function), настраиваем SPI-контроллер и можно посылать данные.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу


SPI у RP2040 работает на частоте вплоть до ~60мгц — это достойная скорость передачи, в том числе и для быстрого вывода графики. На самом деле, SPI даже предпочтительнее чем параллельный 8080-интерфейс для использования в микроконтроллерах: дело не только в количестве занимаемых пинов, но и в возможности использования DMA!

В подобных проектах всегда нужно делать так, чтобы дисплей можно было при необходимости поменять, а желательно вообще научить работать его с несколькими контроллерами: разные дисплеи одной диагонали могут использовать разные контроллеры. В моём случае, этоST7735. Для разрешений 240x320 используются ILI9325, ILI9341, ST7789. Команды инициализации дисплея честно позаимствованы, но именно в этом нет ничего зазорного — сама система команд относительно стандартизирована, отличается лишь первичная настройка питания, гамма-коррекции и т. д — часто init sequence вставляет сам производитель в даташит.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



После инициализации дисплея пробуем что-нибудь вывести. Да, все работает без проблем. Пару важных нюансов: ST7735 требует посаженный на землю CS, в воздухе его оставлять нельзя, как некоторые ILI (вы ведь навряд ли будете вешать несколько устройств на одну шину с дисплеем, когда есть вторая?) и логическое состояние 1 на пине RESET (в воздухе и «на земле» он будет висеть в постоянном ресете).

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Для полустатичной графики, можно обойтись лишь командами дисплея — например, тут есть удобные функции для заливки прямоугольников (setArea и пишем цвет без остановки) или скроллинга. Сделано это для более слабых микроконтроллеров. Нам они не подойдут — выделяем память под фреймбуфер/бэкбуфер и настраиваем канал DMA для разгрузки процессора в процессе передачи данных:

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Саму картинку подготавливает процессор: именно он рисует картинки и он же делает их прозрачными. На него ложится основная работа, однако мы можем ему помочь разгрузиться, если отдадим передачу уже подготовленного кадра на дисплей на DMA (Direct Memory Access) — устройство в микроконтроллере, которое позволяет процессору настроить параметры передачи данных, а DMA их будет сам копировать из памяти или в память. Таким образом, можно реализовать асинхронное копирование нескольких блоков ОЗУ, или, как в моем случае — передачу буфера кадра на дисплей, пока процессор готовит следующий. Чем больше разрешение — тем больше эффекта от DMA!

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Кроме того, важно выбрать формат цвета для нашего дисплея: я выбрал 2-х байтный RGB565 (5 бит красный, 6 бит зеленый, 5 бит синий). Это экономичный формат который выглядит красивее палитровой графики и кушает не так уж и много драгоценной памяти. Кроме того, на данный момент мы умеем отрисовывать изображения произвольных размеров с прозрачностью — вместо альфа-канала здесь используется так называемый colorkey — концепция, очень близкая к хромакею, только она берет в качестве трафарета конкретный цвет. В нашем случае это «255 0 255» (ярко розовый).

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



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

❯ Ввод


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

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Кидаем общий минус на все кнопки, а второй вывод размыкателя кидаем на соответствующие пины GPIO. Я выбрал предпоследние т. к. на них ничего важного не висит, текущая конфигурация занимает 6 пинов. На фото выглядит не очень красиво — на то она и макетка.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Переходим к реализации драйвера. Игры могут слушать события кнопок из специальной структуры —CInput, где на каждую кнопку выделено по одному полю. В будущем конфигурация геймпада может поменяться — например, я захочу добавить аналоговый стик.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу

Есть ещё способ реализации больших клавиатур и геймпадов: когда все кнопки вешаются на пару линий, где на выходе каждой кнопки есть резистор определенного номинала. ЦАП микроконтроллера считывает это значение (допустим — 1024 это вверх, а 2048 — вниз) и таким образом определяет текущую нажатую кнопку. Таким раньше любили промышлять китайцы, из-за чего нельзя было нажать одновременно вверх и вправо, или вниз и влево и т. п.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу

❯ Пишем игру


Теперь у нас есть минимально-необходимая основа для написания игры. Первой игрой для своей консоли я решил написать классический шутер в космосе — летаем на кораблике и сбиваем врагов, попутно уворачиваясь от их пулек. Заодно проверим консоль на стабильность.
Писать я её решил в классическом C-стиле, как и принято в embedded-мире: без std и тем более stl, без ООП и виртуальных методов, аллокаций по минимуму. В общем, примерно как писали игры под GBA! В первую очередь, подготавливаем спрайты нашей игры, прямо в пейнте, а затем конвертируем их в представление обычного массива байтов в виде header-файла. На первых порах это удобнее, чем делать свой ассет-пул:

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Архитектуру я организовал в виде нескольких подфункций, каждая из которых занимается своим стейтом (world/menu) и своими объектами (playerUpdate) и их отдельные версии для отрисовки. Сами игровые объекты я описал в виде структур, а центральным объектом сделал CWorld.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу


Время я решил описывать в тиках, а не миллисекундах, как я обычно это делаю на ПК — у консоли железо одно и там следить за этим нужно меньше.

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Единственные аллокации, что я использовал — это для пулов с пулями, и с врагами. Оба пула четко ограничены — до 8 врагов на экране, и до 16 пулек — вполне хватает. Динамические аллокации помогли мне найти серьезную ошибку в коде — в один из моментов игра просто валилась с Out Of Memory. После того, как я немного поменял условия и делал аллокейты тех же самых объектов каждый кадр — игра переставала крашится. Причина оказалась простая — невнимательность (вместо >= было >), по итогу при отрисовке спрайтов за пределами экрана, программа сама начинала портить вунтренние структуры аллокатара и самой игры (проявлялось в глюках и телепортациях). После фикса, все заработало как нужно. :)


Ну и для основной части геймплея с выстрелами и столкновениями, я предусмотрел несколько функций, которые спавнят игровые объекты и сами управляют пулом. Противники обновляются как обычно, для коллизий используется AABB (axis aligned bounding box, ну или его 2D-подмножество в виде rect vs rect).

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



По итогу, у нас получилось простенькая, но рабочая игрушка, которая без проблем работала почти все время, что я писал этот материал, а значит устройство работает стабильно. И я очень горд, что у меня получилось сделать рабочий прототип своего собственного гаджета!

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Ниже выкладываю принципиальную схему устройства, она очень простая, поэтому смысла делить ее на несколько листов нет. Разводить учился, читая сервис-мануалы и схемы :)

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу

❯ Заключение


Полная цена сборки прототипа составила:

  • Raspberry Pi Pico — 557 рублей (но я брал на Яндекс Маркете, на «алике» дешевле — около 300 рублей).

  • Дисплей — 380 рублей, заказывал на «алике».

  • Макетка — 80 рублей, в местном радиомагазине.

  • Кнопки. По 5 или 10 рублей штучка, пусть будет 60 рублей.


По итогу, прототип мне обошелся в 1077 рублей. Бюджетненько, да, с учетом того, что можно сделать еще дешевле? Я тут так подумал, у меня есть желание развивать и поддерживать консоль в будущем и под консоль уже можно делать что-то своё… может, если вам будет интересно, делать их на заказ? Соберу вам по себестоимости (до 1.000 рублей) + доставка, если хочется попрограммировать под что-то маленькое, но самому паять не хочется. Мне было бы очень приятно. Пишите в личку или комменты, если вас заинтересовало бы такое! :)

Сам себе игровая консоль: как я сделал свой «тетрис» с нуля. Что происходит, когда программист встречается с железом? Гаджеты, Gamedev, Разработка, Своими руками, Raspberry pi, Самоделки, Железо, 2D, Игры, Консоли, Видео, Без звука, Длиннопост, Авторская неделя на Пикабу



Весь процесс разработки этого девайса занял у меня всего несколько дней. Я и до этого понимал концепцию работы 2D-графики на видеокартах прошлого века, поэтому ничего особо нового я для себя не открыл. Однако, я попробовал свои силы в разработке игровых девайсов, которые могут приносить удовольствие — как ментальное от самого процесса сборки и программирования, так и физическое от осознания того, что игра на нем работает. :)

Однако, это далеко не конец проекта! У нас ещё много работы: нужно развести и протравить полноценную плату, реализовать звук и API для сторонних игр, придумать корпус и распечатать его 3D-принтере. Кстати, я ведь обещал что скоро будут и другие интересные проекты с 3D-принтером: как минимум, мы доделаем предыдущий проект игровой консоли из планшета с нерабочим тачскрином и RPi Pico.

Пост подготовлен при поддержке TimeWeb Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать новые статьи каждую неделю!

Показать полностью 23 1
[моё] Гаджеты Gamedev Разработка Своими руками Raspberry pi Самоделки Железо 2D Игры Консоли Видео Без звука Длиннопост Авторская неделя на Пикабу
34
1482
monobogdan
monobogdan
1 год назад
TECHNO BROTHER

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума!⁠⁠

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



В прошлой статье, мы с вами рассмотрели на что способен одноплатный компьютер, который стоит всего 1.000 рублей. Как мы выяснили, перспективы у данного девайса весьма неплохие, однако по факту, Orange Pi продаёт практически голую железку, которую нужно дорабатывать самому. Да, тут есть Ubuntu/Fedora, да, тут выведена гребенка с I2C/SPI — однако из коробки это всё работает криво-косо, либо не работает совсем. Даже обещанные шины SPI/I2C фактически не доступны в системе «из коробки». Материалов о доработке этого одноплатника в сети мало, поэтому я решил довести его до ума сам и поделится с вами — в том числе, готовыми бинарными образами! Интересно, на что способен доработанный одноплатник по цене ящика пива? :)

Над чем будем работать

В прошлой статье, мы с вами определились с потенциальными перспективами такого устройства. По цене 3х ESP32, производитель предлагает нам два полноценных вычислительных ARM-ядра, 256 мегабайт оперативной памяти, 512 мегабайт встроенной NAND-памяти, контроллер питания с возможностью работы от литий-ионных АКБ и 3G модем. Но в бочке меда нашлась ложка дегтя: никто не собирался это всё поддерживать и Orange Pi практически сразу «забили» на поддержку устройства, ограничившись портом Debian/Ubuntun на устройство.

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



Более того, производитель даже не описал как работать с GPIO и шинами устройства — что фактически превращало его из одноплатника в обычную ТВ-приставку, только без нормального видеовыхода. Меня крайне удивило, почему над такой дешевой платой не хотело работать коммьюнити — большинство людей только видели всю ситуацию и шли оставлять негативный отзыв, не попытавшись даже разобраться. А ведь для опытного линуксоида-эмбеддера здесь работы на день-два!

Ко всему прочему, в Linux не работает GSM-стек. Да, совсем. Производитель даже не стал кооперироваться с MediaTek, чтобы попытаться реализовать работу с модемом на уровне системы. А ведь фактически, вся работа с модемом происходит лишь на уровне AT-команд. Так в чем же проблема была?

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



Со всем этим мне и предстоит разобраться! Клонируем репозиторий с исходниками ядра и бежим собирать!

Собираем ядро. I2C и SPI.

Вместо типичного Buildroot, Orange Pi использует свою собственную простую систему сборки на shell-скриптах: в качестве тулчейна используется уже готовый linaro. Отчасти, это связано с самими чипами, на которых работают их устройства — MediaTek, например, не использует Mainline ядро и в процессе сборке имеет ещё кучу шагов для подготовки финального образа. Там даже menuconfig не работает и все изменения приходится делать в уже сгенерированной когда-то конфигурации.

Клонируем репозиторий с системой сборки и запускаем скрипт:

git clone https://github.com/orangepi-xunlong/OrangePi_Build cd OrangePi_Build ./Build_OrangePi.sh

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



Выбираем нашу плату — 3G IoT и ждем, пока система сборки фактически скачает все необходимое для сборки — исходный код ядра, папки external (драйвера, загрузчик и порт linux MediaTek). Обратите внимание, OrangePi даже систему сборки завязали на конкретной версии системы: только Ubuntu 18.04, но на самом деле, ядро соберется без проблем практически где угодно. После того, как все было скачано, переходим в папку с скриптом сборки и запускаем скрипт сборки:

cd ../OrangePi3G_iot/
./build.sh


А нет, не запускаем — скрипт жалуется на то, что не может поставить некоторые пакеты. Не беда — ставим bsdtar и python minimal вручную и идем править код скрипта. Находится в он scripts/general.sh: убираем оттуда устаревшие имена пакетов.

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



После этого, компиляция ядра должна пройти успешно. Обратите внимание на версию вашей платы — те, что продают сейчас — именно A. Если пытаться подкинуть им ядро для B, то они будут уходить в kernel panic из-за отсутствия eMMC.

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



Если mkbootimg будет жаловаться на libstdc++6, то ставим его x86 версию из репозиториев.

Готовое ядро будет лежать вoutput/kernel/boot.img, которое можно прошить на устройство. С одним маленьким нюансом — оно рассчитано на загрузку из внутренней памяти, которой критически мало для дистрибутива Linux! У нас нет boot_sd.img, который есть в оригинальном дистрибутиве. Попытка разобрать образ стандартным AndImgTool не увенчалась успехом — рамдиск встроен прямо в образ zImage, а не отдельно, как это обычно бывает у Android-образов.

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



Покопавшись в скриптах сборки, я так и не понял логику создания boot_sd, ничего связанного с sd я не нашел даже grep'ом по всей папке. Ну что-ж, тогда попробуем обходным путем: скомпилируем нужные драйвера в виде загружаемых модулей (ko). Идём в наш конфиг, расположенный в linux/arch/arm/configs/3giot_defconfig и меняем CONFIG_I2C_CHARDEV и CONFIG_SPI_SPIDEV на m. Пояснение: y заставит систему сборки скомпоновать драйвер статически с ядром, а m выделит его в виде отдельного модуля ko, который затем можно загрузить черезinsmod.

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



Снова собираем ядро, на этот раз компиляция занимает не больше минуты. Нужные нам файлы появятся в linux/drivers/spi/spidev.ko и linux/drivers/i2c/i2c-d-ev.ko. Переносим их на хост-пк, а затем и на само устройство с помощью SSH:

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



Загружаем модули ядра:

insmod i2c-dev.ko


И та-дам! Целых две i2c шины появилось в системе (/dev/i2c-0, /dev/i2c-1). Устанавливаем i2c-tools и идем проверять с помощью i2cdetect: первая шина полностью свободна под наши проекты, а на второй по некоторым адресам висит периферия (FM-радио как вариант):

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



I2C теперь точно работает! Но как насчет SPI?

insmod spidev.ko
Device or resource busy.



Увы! spidev нельзя подгружать динамически, только статически линковать с ядром, чего мы сделать пока не можем. Однако техническая возможность заставить работать SPI есть: например, написать свой драйвер, который транслирует команды из юзерспейса в SPI API, которое работает на уровне ядра.

GPIO

В прошлой статье, я вкратце рассказал, как работать с gpio из user-space на уровне терминала. Однако, большинство разработчиков потенциально будет пользоваться нативным API для GPIO — ну не всерьез же им парсить вывод состояния в консоль? Поэтому я решил написать крошечную библиотеку для работы с GPIO, такую же простую, как и DigitalWrite/DigitalRead!

Давайте сначала разберемся, как именно работать с драйвером GPIO. Для этого открываем исходники ядра и смотрим внимательно, что нам предлагает драйвер: в нашем случае, это вызовы IOCTL, да еще и простые и понятные. Это просто отлично! Я написал single-header библиотеку минут за 10: без проверки ошибок, но работоспособная.

void gpioInit();

void gpioSetDir(int num, byte dir);

byte gpioGetDir(int num);

void gpioWrite(int num, byte value);

byte gpioGetState(int num); byte gpioRead(int num);

void gpioSetPullState(int num, byte enabled, byte up);



Пример использования (141 — крайний пин на гребенке):

#define GPIO_IMPL

#include "gpio.h"

#include <stdio.h>

void testPin(int pin)

{

printf("Pin state %i is %i\n", pin, gpioGetState(pin));

gpioSetDir(pin, 1);

gpioWrite(pin, 0);

printf("Pin state %i is %i\n", pin, gpioGetState(pin));

gpioWrite(pin, 1);

printf("Pin state %i is %i\n", pin, gpioGetState(pin));

}

int main(int argc, char** argv) {

gpioInit();

testPin(141);

}

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



Модем

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

В устройствах MediaTek, драйвер для общения с GPS, A-GPS и модемом один — ccci, судя по всему cross chip communication interface. Именно ccci создает устройства, с в которые поступает вход с микрофона и выход на динамики, а также он создает управляющие интерфейсы для общения с различными модулями этого SoC.

При старте ядра, ccci создаёт много устройств — ccci_ioctl, ccci_ipc, ccci_fs и самое нужное нам —ttyC0/ttyC1/ttyC2— в зависимости от количества СИМ-карт в системе. Кроме ccci, в системе есть некий 6620_launcher — бинарник, который загружает прошивку Wi-Fi и gsm0710muxd — специальный сервис, который позволяет в GPRS-сетях одновременно разговаривать и сидеть в интернете.

На смартфонах MTK есть factory mode — так называемый тестовый режим, который гоняют на заводах. Вы, вероятно, когда-то видели китайские меню похожее на рекавери — это и есть factory mode. Из этого режима можно дозвонится в 911 и активировать модем без запуска Android и RIL. Как это работает? Идём читать исходники ядра!

В factory-режиме, для каждого теста, программа активирует модем заново. Для этого есть функции тестового режима для работы с AT-командами и для инициализации модема. Сначала, она открывает терминал /dev/ttyC0 — именно там происходит общение с модемом с помощью AT-команд:

Мы сделали вам плату, а дальше вы сами: Доводим дешевый одноплатник за "косарь" до ума! Гаджеты, Смартфон, Программирование, IT, Orange Pi, Одноплатный компьютер, Linux, Android, Raspberry pi, Минипк, Дешево, Покупка, Моддинг, Своими руками, Embedded, Длиннопост, Авторская неделя на Пикабу



После этого, программа выводит модем из режима сна с помощью команды «AT+ESLP=0», инициализирует СИМ-карту с помощью команды «AT+ESIMS» и задает режим работы с помощью «AT+EFUN=1» и «AT+CREG=1». После этого, модем начинает искать сеть и доступен для обычного общения с помощью AT-команд. Однако, написав тестовую софтину для общения с модемом из под Debian, я получал ошибки вида Device not found. Почему? Пока не знаю. Однако я продолжаю изучать данный вопрос!

Заключение

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

К счастью, довести гаджет до ума мы смогли своими силами. Весьма странно, что такой крупный и уважаемый производитель как Orange Pi, банально решил «забить» на поддержку собственного устройства. И я лично считаю, что не стоит закидывать в долгий ящик их тем читателям, которые купили когда-то себе подобный девайс и забили, смирившись с отсутствием гайдов.

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

Показать полностью 11
[моё] Гаджеты Смартфон Программирование IT Orange Pi Одноплатный компьютер Linux Android Raspberry pi Минипк Дешево Покупка Моддинг Своими руками Embedded Длиннопост Авторская неделя на Пикабу
149
miayuyu
miayuyu
1 год назад

Как мне их продать?⁠⁠

Как мне их продать? Raspberry pi, Продажа, Нужен совет
Как мне их продать? Raspberry pi, Продажа, Нужен совет
Показать полностью 2
Raspberry pi Продажа Нужен совет
25
7
Nird.d
Nird.d
1 год назад
Home Assistant

MQTT не видит больше 12 устройств⁠⁠

Добрый день.

Прошу помощи. С какого-то момента MQTT перестал определять больше 12 zigbee устройств. Удаляю интеграцию, создаю заново, находит снова 12 но других. Сначала думал дело в стике, купил свежий Sonoff история та же. HA в докере на ubuntu сервере. В качестве железа - малинка 3В. Версия HA 2023.07.2 На какой-то старой версии, точно поддерживалось 18 устройств. Может кто сталкивался с таким? Похоже на какое-то ограничение, но в какую сторону копать - не пойму.

Ubuntu Raspberry pi Компьютерная помощь Текст
5
35
Akvariumist2gr
Akvariumist2gr
1 год назад
Лига Геймеров

Play off/on⁠⁠

Эмуляторы и немного собственного опыта, или как прикрутить PS ко всему что можно.

Немного воспоминаний из детства.
Скорее всего у многих в детстве была какая-нибудь консоль. В моем случае денди.

Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост

Поначалу играть было практически невозможно (мне лет 5, наверное, было). Причиной тому было то, что в доме (2 этажа, 12 квартир) все хорошо друг друга знали и спокойно заходили к соседям без стука попить чаю. Играл весь дом, были драки за пульт (джойстик). И пока дойдёт очередь до тебя можно было немного подрасти, да ещё этот чёртов кинескоп, который можно было посадить (и другие детские психотравмы). У нас первых во дворе появилась денди и знали об этом тоже все, ещё до того, как купили.
У жены в детстве была сега.

Вот такая прибуда (SEGA) есть у нас, которая через sd карту читает игры.

Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост

И в Mortal Kombat на ней, она выносит меня в пух и прах.

Но история не об этом, а о том, как поиграть в PS 1-3 и другие консоли, не имея этих самых консолей.
Для начала задался поиском всевозможных эмуляторов на ПК, перебрал достаточно и остановился на (RetroArch, RPSX3). А так как современные смартфоны вполне себе производительные, на них с лёгкостью устанавливаются те же эмуляторы и коннектятся джойстики. Плюс ко всему можно на тв поставить трансляцию экрана со смартфона и сиди играй, ностальгируй.

К телефону прикрутил (AetherSX2) PS1-2 игры запускал, к примеру вот:

Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост
Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост
Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост

Запустить что-то из PS2 на телефоне было больше спортивным интересом. Попробовал, получилось, даже можно играть. В моем случае телефон - это Sony Xperia xz1 восстановленный, прямиком из Китая.

На ПК RPSX3

Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост
Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост
Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост
Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост
Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост
Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост

Не всё играбельно, но во многое можно поиграть, и как я понял пройти. К примеру, сесть с женой вечерком и навалять друг другу в Mortal Kombat или TEKKEN - это многого стоит))
Характеристики пк есть в в этом посте: Неприятности случаются или поиск мастера.

Появилась необходимость приобретения джойстиков, вариантов масса, полазив на сайте объявлений нашёл за 600 рублей пару аналогов dualshock 4 (немного глючных с залипающими кнопками). Перед покупкой попробовал подключить к телефону, все поочерёдно подключились. Отправился домой с надеждой что хотя-бы один получиться собрать полностью функционирующим. Дома не долго думая разобрал, почистил от пыли, поправил залипшие мембраны, собрал и все заработало, без глюков, оба два.

Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост

После удачных попыток запуска эмуляторов и тестов, отправился в плавание по просторам интернета с поднятым чёрным флагом в поисках игр для PSок, для сеги уже есть скаченые. Установил эмуляторы на телефон, пк и тв-приставку от xiaomi (с ней проблемы, не подключаются джойстики)

Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост

Но я упрямый, я пошёл дальше. На данный момент к телеку подключена маленькая коробочка с установленной в неё RetroArch. Если подробнее, то вспомнил про находку коробочки без опознавательных знаков с 4х usb, hdmi, micro usb и lan портами (нашёл в квартире когда переехали в другой город), не зная на тот момент что это такое, убрал в ящик с надписью "может пригодится". Три года ждала своего часа. Любопытства ради раскрутил её посмотреть что это за зверь такой, а это raspberry pi 3, тут щелкнуло что на сайте retroarch видел упоминание о них. Несколько несложных манипуляций (скачивание, запись образа на microsd) и есть коробулька которая может воспроизводить консоли до PS-1.

Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост

Игры загружены на usb флешку, джойстики по bluetooth подсоеденены.

Чуть не забыл рассказать про Bluetooth адаптер приобретённых на озоне за недорого, заработал и на raspberry pi.

Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост

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

Play off/on Компьютер, Android, Playstation, Консоли, Raspberry pi, Retroarch, Эмулятор, Длиннопост

P. S. По настройкам эмуляторов подсказать не смогу тут я не очень умный, настраивал методом "научного тыка"

Спасибо что дочитали.

"Аквариумист_2_группы"
"Болею аквариумом, увлекаюсь рассеянным склерозом"

Показать полностью 16
[моё] Компьютер Android Playstation Консоли Raspberry pi Retroarch Эмулятор Длиннопост
3
17
kokiteris
kokiteris
1 год назад
Наши 90-е

У кого есть?⁠⁠

У кого есть?
Картинка с текстом X (Twitter) Зашакалено Ностальгия Raspberry pi
8
7
MarkParker.5
MarkParker.5
2 года назад
Умный дом
Серия MajorDom

Внутри MajorDom v1.0 — Разбираем архитектуру новой системы умного дома⁠⁠

Статья на английском / read in english

В предыдущей статье я рассказал о том, как возникла идея создания умного дома. Теперь я хочу более подробно рассмотреть архитектуру первой версии этой системы.

МажорДом состоит из нескольких ключевых компонентов: девайсы, хаб, облако, мост, мобильное приложение и голосовой ассистент.

Девайсы обеспечивают управление физическими устройствами в доме. С помощью радиомодулей и протокола "Мерлин", они обмениваются данными, получают команды от хаба и отправляют ему события.

Хаб является центральным элементом системы. Он обеспечивает управление девайсами и координирует их работу. Хаб хранит основную базу данных с информацией о пользователях, доме, комнатах и девайсах. Через локальный HTTP-сервер и WS-сервер, хаб предоставляет API для работы с базой данных и высокоуровневого управления девайсами.

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

Мост представляет собой WS-сервер, который обеспечивает связь между хабом и удаленными пользователями через интернет. Он позволяет отправлять команды и получать информацию с хаба, не находясь в домашней локальной сети.

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

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

Нестрашна даже полная потеря интернет-соединения на хабе. Вся логика и обработка команд происходят локально, что обеспечивает независимость от интернет-соединения и сохраняет возможность управления устройствами в локальной сети. Но такой сценарий редкость, ведь хаб может подключаться одновременно по wifi и ethernet кабелю, а в будущем будет добавлена поддержка сим-карт сотовой сети.

Управление умным домом осуществляется через мобильное приложение, которое предоставляет удобный интерфейс для пользователей. Однако на практике, роль мобильного приложения часто сводится к настройке системы, а ежедневное управление устройствами осуществляется с помощью автоматических сценариев и голосового ассистента.

Как и хаб, голосовой ассистент может работать полностью офлайн, что обеспечивает безопасность, конфиденциальность и надежность использования.

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

Показать полностью
[моё] IT Программирование Arduino Разработка Приложение Умный дом Автоматизация Голосовой помощник Голосовое управление Raspberry pi Текст
1
194
monobogdan
monobogdan
2 года назад
TECHNO BROTHER

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера⁠⁠

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера Смартфон, Телефон, Идея, Своими руками, Arduino, Embedded, Встраиваемые системы, Планшет, Игры, Консоли, Самоделки, Моддинг, Android, Linux, Java, C++, Kernel, Покупка, Raspberry pi, Микроконтроллеры, Видео, Длиннопост

К сожалению, в наше время многие старые, но весьма неплохие по характеристикам гаджеты отправляются напрямую в помойку, и их владельцы не подозревают, что им можно найти применение. Сервер, мультимедийная-станция, да даже просто как TV-приставка — люди в упор не замечают сфер, где старенький планшет мог бы быть полезен. Но как быть, если посвящаешь жизнь портативным гаджетам, кодингу и копанию в железе? Правильно: сделать довольно мощную игровую консоль из старого планшета самому! Сегодня вам расскажу, как я сделал свою портативную приставку из планшета с нерабочим тачскрином, Raspberry Pi Pico и 8 кнопок! За рабочим результатом прячется несколько дней работы: поиск UART на плате, разработка контроллера геймпада на базе RPi Pico, написание приложения-сервиса, которое слушает события и отправляет их в подсистему ввода Linux в обход Android. Интересно? Тогда жду вас под катом!

❯ Мотивация


Прошло уже практически 10 лет с того момента, как у меня появилась моя первая портативная консоль. Несмотря на то, что я был заядлым ПК-игроком, я уже успел посмотреть на PS3 и PSP, но денег на их покупку у меня особо не было, да и к тому времени уже был в наличии Android-планшет. Но к моему 13-летию в 2014 году, когда я ходил и выбирал себе будущий девайс на день рождения, отец и мама решили подарить мне мою первую портативную консоль. Изначально, я уговаривал её купить мне целых два девайса, но бюджет был ограничен 4.000 рублей, а я хотел взять смартфон Fly IQ239 и консоль JXD S601 одновременно:

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера Смартфон, Телефон, Идея, Своими руками, Arduino, Embedded, Встраиваемые системы, Планшет, Игры, Консоли, Самоделки, Моддинг, Android, Linux, Java, C++, Kernel, Покупка, Raspberry pi, Микроконтроллеры, Видео, Длиннопост


Однако, увидев здоровую 7-дюймовую консоль в магазине TREC (думаю, жители южной части РФ помнят такой), мама уговорила меня взять именно её, мотивируя это «ну и чего ты будешь тыкаться в этот мелкий экран? Возьми большую». После покупки гаджета, я был доволен: играл какие-то игрушки с ретро-платформ, устанавливал игры на Android, сидел в ВК через Kate Mobile. Что еще нужно было школяру? Однако, планшет прожил у меня недолго: с очередного лага я психанул и ударил по нему кулачком, унеся на тот свет и дисплей и тачскрин. Так консолька и пролежала в подвале около 8 лет. Впрочем, мне продолжали импонировать подобные устройства и в прошлом году я купил и написал про несколько подобных девайсов.

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера Смартфон, Телефон, Идея, Своими руками, Arduino, Embedded, Встраиваемые системы, Планшет, Игры, Консоли, Самоделки, Моддинг, Android, Linux, Java, C++, Kernel, Покупка, Raspberry pi, Микроконтроллеры, Видео, Длиннопост



Несколько месяцев назад, мой читатель Кирилл Севостьянов с Хабра прислал мне HTC HD2 в качестве донора и планшет Prestigio PMP7170B3G, который был рабочим, но… у него отказал тачскрин. Я всё думал, чего бы с ним сделать и решил реализовать игровую консольку своими руками из подручных средств. Идея крутилась в голове довольно давно, но реализовал я её только сейчас.

❯ Что нам нужно сделать?


Итак, что должно быть у портативной консоли? Чипсет, дисплей, звук, ОС — это всё нам уже предоставляет планшет. Нам остаётся лишь сделать свой геймпад. Давайте подумаем, что нам будет нужно для того, чтобы его сделать и передавать от него события на планшет:

  • Контроллер для геймпада: тут нам подойдет практически любой микроконтроллер, который работает от 3.3в. Выбор большой: Arduino Pro Mini 3.3v, ESP32, RPi Pico. Я остановился на последнем: недавно я взял себе две штучки «пощупать» их — и они мне очень понравились!

  • Физический интерфейс: с планшетом нужно как-то общаться. У нас есть три варианта: USB (не факт, что поддержка преобразователей включена в ядре), UART и SPI/I2C на пятачках тачскрина (потребуют написания драйвера т. к. в android-устройствах нет прямого доступа к SPI/I2C из userland'а). Я остановился на UART: его легко найти на большинстве китайских планшетов, а если не получилось — то на помощь может прийти схема платы.

  • Программная реализация: как это будет работать? Я решил реализовать геймпад в виде сервиса на Android, который слушает состояния кнопок с UART и «инжектит» события напрямую в драйвер ввода. Таким образом, поддержка нашего геймпада появляется даже в самой системе — можно управлять менюшкой или приложениями как с клавиатуры!


    С планом определились, пора начать с программной части: сначала нам обязательно понадобится ROOT-доступ. Его получение на разных девайсах отличается — на prestigio уже был порт CWM и я просто поставил SuperSU. Без ROOT доступа мы не сможем использовать UART!

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера Смартфон, Телефон, Идея, Своими руками, Arduino, Embedded, Встраиваемые системы, Планшет, Игры, Консоли, Самоделки, Моддинг, Android, Linux, Java, C++, Kernel, Покупка, Raspberry pi, Микроконтроллеры, Видео, Длиннопост


Теперь нам нужно найти пятачки UART на плате. Разведен он не везде, но в случае устройств на MediaTek — почти всегда, ещё и пятачки подписаны. На моём планшете он нашёлся сразу: был между двух металлических экранов и соответствовал 4-ому каналу UART. Получить к нему доступ можно в /dev/ttyMT3. Я использую ESP32 в качестве UART преобразователя: подпаиваемся к RX/TX, запускаем putty и заходим в adb shell. Определяем бодрейт (скорость) нашего UART порта — на MediaTek он обычно равен 921600, на других чипсетах — 115200. Пытаемся что-то вывести и хоба — мы уже можем «поболтать» с планшетом!

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера Смартфон, Телефон, Идея, Своими руками, Arduino, Embedded, Встраиваемые системы, Планшет, Игры, Консоли, Самоделки, Моддинг, Android, Linux, Java, C++, Kernel, Покупка, Raspberry pi, Микроконтроллеры, Видео, Длиннопост

❯ Приложение-сервис


Итак, у нас уже есть доступ к UART и мы можем общаться с планшетом из внешнего мира. Но получить события с кнопок пол дела, нужно их ещё и послать в систему. Для этого есть целых три способа:

  1. InputManager.injectInputEvent — именно этим методом пользуется команда input, которую вы можете использовать через adb. Но увы, он работает только при наличие разрешения INJECT_EVENTS, который доступен только системным приложениям — находятся они в /system/app и подписаны тем же сертификатом, что и остальная прошивка.

  2. Модуль uinput дает возможность создать виртуальное устройство ввода и посылать события из userland'а — т. е. из прикладного приложения. У моего планшета было устройство /dev/uinput, но lsmod показывал, что сам модуль не загружен. Так что отметаем — он есть не везде.

  3. Прямой инжект событий в character устройство — весьма грязный хак, который позволяет инжектить события, не притворяясь системным приложением, но имеет некоторые ограничения. Именно его я и выбрал и о ограничениях ниже.


Сначала нам нужно узнать, какие кнопки поддерживают загруженные устройства ввода в системе. Для этого используем команду getevent -li. Там есть разные устройства ввода, в том числе и тачскрин (если вам нужно симулировать нажатия на экран), мне же подошёл драйвер физических кнопок mtk-kpd. Он занимается обработкой кнопок громкости, включения и т. п. Тут важно обратить внимание на то, что если попытаться послать кнопку, которое устройство не реализует (например пробел), то ничего не произойдет:

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера Смартфон, Телефон, Идея, Своими руками, Arduino, Embedded, Встраиваемые системы, Планшет, Игры, Консоли, Самоделки, Моддинг, Android, Linux, Java, C++, Kernel, Покупка, Raspberry pi, Микроконтроллеры, Видео, Длиннопост



Инжект событий я писал на C, т. к. это требовало прямой записи input_event, а в Java прокинул его через Jni. Концепция простая: открываем устройство /dev/input/event2 и посылаем в него события ввода и синхронизации (это обязательно!), которые затем Android читает и обрабатывает:

#include <linux/uinput.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

#include <android/log.h>

#include <jni.h>

int uinput;

extern "C" JNIEXPORT void JNICALL Java_com_monobogdan_inputservicebridge_InputNative_init(JNIEnv *env, jclass clazz) {

uinput = open("/dev/input/event2", O_WRONLY);

__android_log_print(ANDROID_LOG_DEBUG , "Test", uinput >= 0 ? "Open event OK" : "Failed to open event"); }

void emit(int fd, int type, int code, int val) {

struct input_event ie; ie.type = type;

ie.code = code; ie.value = val;

ie.time.tv_sec = 0;

ie.time.tv_usec = 0;

write(fd, &ie, sizeof(ie)); }

extern "C" JNIEXPORT void JNICALL Java_com_monobogdan_inputservicebridge_InputNative_sendKeyEvent(JNIEnv *env, jclass clazz, jint key_code, jboolean pressed) {

__android_log_print(ANDROID_LOG_DEBUG , "Test", "Send");

emit(uinput, EV_KEY, key_code, (bool)pressed ? 1 : 0);

emit(uinput, EV_SYN, SYN_REPORT, 0);

}

Основной обработкой занимается сервис, который я реализовал в отдельном потоке: он слушает события с UART и посылает соответствующие изменения состояния через sendKeyEvent. На вход приходят простые сообщения вида:

U L где U/D — нажато, не нажато, а L — однобайтовый идентификатор кнопки. В случае L — это влево, R — вправо и т. п. Вся доступная раскладка хранится в словаре. Причём само чтение из UART реализовано костылем с чтением «чужого» stdout, т. к. android-приложения не умеют сами по себе работать с root правами. В теории, это могло дать неприятный оверхед, но на практике никакого серьезного инпут лага это не создает. Не забываем сделать устройство event записываемым — ставим ему права 777:

package com.monobogdan.inputservicebridge;

public class InputListener extends Service {

private static final int tty = 3;

private InputManager iManager;

private Map<Character, Integer> keyMap;

private Method injectMethod;

private Process runAsRoot(String cmd)

{

try {

return Runtime.getRuntime().exec(new String[] { "su", "-c", cmd });

}

catch (IOException e)

{

e.printStackTrace();

return null;

}

}

@override

public void onCreate() {

super.onCreate();

// According to linux key map (input-event-codes.h)

keyMap = new HashMap<>();

keyMap.put('U', 103);

keyMap.put('D', 108);

keyMap.put('L', 105);

keyMap.put('R', 106);

keyMap.put('E', 115);

keyMap.put('B', 158);

keyMap.put('A', 232);

keyMap.put('C', 212);

InputNative.init();

try {

runAsRoot("chmod 777 /dev/input/event2").waitFor();

} catch (InterruptedException e) {

throw new RuntimeException(e);

}

Executors.newSingleThreadExecutor().execute(new Runnable() {

@override

public void run() {

Process proc = runAsRoot("cat /dev/ttyMT" + tty);

BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));

while(true)

{

try {

String line = reader.readLine();

if(line != null && line.length() > 0) {

Log.i("Hi", "run: " + line);

boolean pressing = line.charAt(0) == 'D';

int keyCode = keyMap.get(line.charAt(2));

Log.i("TAG", "run: " + keyCode);

InputNative.sendKeyEvent(keyCode, pressing);

}

}

catch(IOException e)

{

e.printStackTrace();

}

/*try {

Thread.sleep(1000 / 30);

} catch (InterruptedException e) {

e.printStackTrace();

}*/

}

}

});

}

@override

public IBinder onBind(Intent intent) {

return null;

}

}

Таким образом, если мы отправляем с ПК «D L» — система считает, что мы зажали стрелку влево, а U L — считает что мы отпустили. Но если mtk-kpd поддерживает стрелки и еще некоторые действия без каких либо проблем, то enter в список обрабатываемых кнопок не входит: придется мудрить! И тут нам приходит на помощь механизм трансляции кодов кнопок в действия: они хранятся в специальных файлах .kl в /system/usr/keylayout/. Я назначил DPAD_CENTER на… кнопку регулировки громкости звука! Ну, а почему бы и нет. :) Таким образом можно переназначить уже имеющиеся кнопки громкости на, например, start/select.

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера Смартфон, Телефон, Идея, Своими руками, Arduino, Embedded, Встраиваемые системы, Планшет, Игры, Консоли, Самоделки, Моддинг, Android, Linux, Java, C++, Kernel, Покупка, Raspberry pi, Микроконтроллеры, Видео, Длиннопост

❯ Геймпад


После того, как сервис был готов и отлажен, нужно было реализовать хардварную часть проекта — сам геймпад. В качестве контроллера я, как уже говорил, выбрал Raspberry Pi Pico на базе МК RP2040 — бодреньком контроллере с двумя ARM Cortex-M0 ядрами. Стоит копейки, а в отличии от ESP'шек, его SDK не такое перегруженное и выглядит более приближенным к bare-metal.

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера Смартфон, Телефон, Идея, Своими руками, Arduino, Embedded, Встраиваемые системы, Планшет, Игры, Консоли, Самоделки, Моддинг, Android, Linux, Java, C++, Kernel, Покупка, Raspberry pi, Микроконтроллеры, Видео, Длиннопост



На данный момент, я решил развести все кнопки на бредборде — макетной плате без пайки, т. к. макеток для пайки у меня под рукой не было. Сделал примитивный геймпад:

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера Смартфон, Телефон, Идея, Своими руками, Arduino, Embedded, Встраиваемые системы, Планшет, Игры, Консоли, Самоделки, Моддинг, Android, Linux, Java, C++, Kernel, Покупка, Raspberry pi, Микроконтроллеры, Видео, Длиннопост



Развел на соответствующие GPIO:

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера Смартфон, Телефон, Идея, Своими руками, Arduino, Embedded, Встраиваемые системы, Планшет, Игры, Консоли, Самоделки, Моддинг, Android, Linux, Java, C++, Kernel, Покупка, Raspberry pi, Микроконтроллеры, Видео, Длиннопост



И написал примитивную прошивку, которая отслеживает состояние кнопок. В прошивке точно так же есть словарь, задающий ассоциацию между физическими пинами и «виртуальными» кнопками. При нажатии или отжатии кнопки, программа изменяет стейт и отсылает новое состояние планшету.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "pico/stdlib.h"

#include "pico/time.h"

#include "hardware/uart.h"

struct keyMap

{

int gpio;

char key;

bool pressed;

int lastTick;

};

keyMap keys[] = {

{

15,

'L',

false,

0

},

{

14,

'U',

false,

0

},

{

13,

'D',

false,

0

},

{

12,

'R',

false,

0

},

{

11,

'E',

false,

0

},

{

10,

'B',

false,

0

},

{

20,

'A',

false,

0

},

{

21,

'C',

false,

0

}

};

#define KEY_NUM 8

int main() {

stdio_init_all();

uart_init(uart0, 921600);

gpio_set_function(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART);

gpio_set_function(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART);

sleep_ms(1000); // Allow serial monitor to settle

for(int i = 0; i < KEY_NUM; i++)

{

gpio_init(keys[i].gpio);

gpio_set_dir(keys[i].gpio, false);

gpio_pull_up(keys[i].gpio);

}

while(true)

{

int now = time_us_32();

for(int i = 0; i < KEY_NUM; i++)

{

char buf[5];

buf[1] = ' ';

buf[3] = '\n';

buf[4] = 0;

if(!gpio_get(keys[i].gpio) && !keys[i].pressed && now - keys[i].lastTick > 15500)

{

buf[0] = 'D';

buf[2] = keys[i].key;

puts(buf);

keys[i].lastTick = now;

keys[i].pressed = true;

continue;

}

if(gpio_get(keys[i].gpio) && keys[i].pressed && now - keys[i].lastTick > 15500)

{

buf[0] = 'U';

buf[2] = keys[i].key;

puts(buf);

keys[i].pressed = false;

keys[i].lastTick = now;

}

}

}

}

Собираем всё вместе и тестируем. Хоба, всё работает, мы можем перемещаться по менюшке используя наш геймпад!

Сам себе игровая консоль: превращаем планшет с нерабочим тачскрином в игровой девайс из 8 кнопок и микроконтроллера Смартфон, Телефон, Идея, Своими руками, Arduino, Embedded, Встраиваемые системы, Планшет, Игры, Консоли, Самоделки, Моддинг, Android, Linux, Java, C++, Kernel, Покупка, Raspberry pi, Микроконтроллеры, Видео, Длиннопост



А почему бы не попробовать поиграть в какую-нибудь игру? Ну мы же консоль вроде делаем: берём эмулятор NES, биндим кнопки в настройках и наслаждаемся игрой в Марио!

❯ Заключение


Реализация этого проекта заняла у меня не так уж и много времени: всего около 3-х дней работы по вечерам. Вероятно кто-то спросит: «а чего ты просто Bluetooth геймпад не купил?». Так это не прикольно ведь. Гораздо приятнее играть в девайс, к которому ты приложил руку сам. Более того, не у всех старых планшетов есть BT. Обошёлся на данной стадии проект недорого: планшет мне подарили бесплатно (точно также у вас дома может лежать подобный), RPi Pico — 350 рублей, кнопки по 10 рублей/штучка.

В целом, я сам по себе обожаю копаться в различных железках и их софтварной части (вспомнить хотя-бы статью про перекомпиляциюu-boot из вендорских исходников для нонейм консоли), а созидать что-то свое вообще вызывает какие-то нереальные всплески эндорфина — оно и понятно! :)

Однако несмотря на то, что мы уже имеем рабочий «прототип», проект далёк от завершения: я намерен довести его до конца и окончательно перевоплотить старый планшет в автономную игровую консоль (и рассказать об этом во второй части статьи). Для этого мне понадобится распечатать корпус и кнопки на 3D-принтере. К сожалению, у меня в городе ни у кого особо нет 3D-принтеров, поэтому начну копить на Ender 3, а от вас, читателей, с удовольствием почитаю мнение в комментариях и советы касательно выбора принтера!

Статья подготовлена при поддержке TimeWeb Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать еженедельные статьи про моддинг различных гаджетов!

Показать полностью 10 1
[моё] Смартфон Телефон Идея Своими руками Arduino Embedded Встраиваемые системы Планшет Игры Консоли Самоделки Моддинг Android Linux Java C++ Kernel Покупка Raspberry pi Микроконтроллеры Видео Длиннопост
33
Посты не найдены
О Нас
О Пикабу
Контакты
Реклама
Сообщить об ошибке
Сообщить о нарушении законодательства
Отзывы и предложения
Новости Пикабу
RSS
Информация
Помощь
Кодекс Пикабу
Награды
Команда Пикабу
Бан-лист
Конфиденциальность
Правила соцсети
О рекомендациях
Наши проекты
Блоги
Работа
Промокоды
Игры
Скидки
Курсы
Зал славы
Mobile
Мобильное приложение
Партнёры
Промокоды Biggeek
Промокоды Маркет Деливери
Промокоды Яндекс Путешествия
Промокоды М.Видео
Промокоды в Ленте Онлайн
Промокоды Тефаль
Промокоды Сбермаркет
Промокоды Спортмастер
Постила
Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии