Как сделать приставку на ардуино

Обновлено: 07.07.2024

Года полтора проходя мимо ретро игровых приставок в магазинах, аналогов Денди и Сеги, я думал прикупить и поиграть с детьми. Но останавливало то, что покупать в совокупности все приставки дорого, игр на них не так много, а картриджи не то чтобы массово продаются. Поэтому решил сделать приставку своими руками и чтобы была возможность запускать игры от любых приставок.

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

Сборку приставки я решил делать на одноплатном компьютере Raspbery Pi 3. Немного покопавшись в недрах AliExpress нашел комплект специально для сборки игровой ретро консоли. Заказал с доставкой из России и уже через 5 дней получил вот такую радость. Ссылка на магазин в котором покупал будет в конце статьи.

Сборка ретро консоли на Raspbery Pi 3

В комплекте шел собственно сам микрокомпьютер Raspbery Pi 3, корпус стилизованный под приставку, кулер с радиаторами, microSD карточка на 32GB 10class, 2 джойстика и блок питания. Первым делом собрал все это в корпус.

Как видите в корпусе размещен хаб с USB портами для подключения джойстиков. Хаб подключается напрямую к одному из портов Raspbery Pi. Так же на корпус выведен разъем RJ45 для подключения к локальной сети, но можно использовать и WiFi.

С помощью пин конекторов на шину микрокомпьютера подключаются кнопка управления питанием и кнопка Reset, а так же питание для кулера, который подсоединяется к разъему на плате в корпусе.

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

Удобно, что разъемы HDMI, MicroUSB для блока питания, а так же слот для карты памяти доступны снаружи при собранном корпусе, поэтому я все скрутил и перешёл к следующему этапу - установке операционной системы и закачке игр.

В собранном виде приставка очень компактная и практически бесшумная. Для настройки нам так же понадобятся клавиатура с USB разъемом и компьютерная мышь.

Установка RetroPie

В качестве операционной системы я использовал готовый образ RetroPie, который уже заточен для работы в качестве игровой приставки. Подробных инструкций в интернете полно, поэтому я расскажу по основным пунктам, а в конце вставлю видео с наглядной инструкцией по которой собирал сам. Если вам что-то будет не понятно то либо напишите в комментариях.

2. Распаковываем образ в папку RetroPie. У вас должен появится файл с расширением img.

3. Записываем файл образа на флэшку с помощью программы Win32 Disk Imager.

4. Вставляем флэшку в консоль и включаем. При первом запуске вам будет предложено настроить кнопки джойстика. Обычно RetroPie самостоятельно определяет джойстик, просто следуйте инструкциям на экране (к сожалению на английском). Тем не менее вы можете переназначить кнопки при необходимости в настройках. Подключить можно практически любые джойстики, в том числе от XBox например.

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

6. Когда скопировали файлы rom перезапустите консоль и в соответствующем разделе эмулятора, например NES увидите список игр. Запускаем и наслаждаемся ретро играми.

Приобретал комплект тут на Алиэкспресс . Ссылка партнерская буду благодарен, если приобретете по моей ссылке. Вам хороший набор, а мне лишняя копеечка для ремонта дома в деревне.

Как использовать плату Arduino для вывода какой-либо информации на ТВ? Оказывается есть такая библиотека TVOut ( статья на сайте >> ), которая позволяет выводить информацию на ТВ по НЧ-кабелю (тюльпан). Правда изображение будет черно-белым, однако этого будет достаточно для большинства проектов.

Вот игровая консоль, где используется данная библиотека

hackvision_02(1).jpg

Создадим свою ТВ-приставку, состоящую из Arduino-платы и двухкоординатного джойстика и напишем простенькую игру.
Вот вид нашей приставки

IMAG0341.jpg

ris21_07(1).jpg

Рассмотрим основные функции библиотеки.

Функции установки режима

Функция begin() инициализирует вывод видеосигнала (разрешение экрана по умолчанию 128x96)
Синтаксис:

  • mode – стандарт видеосигнала:
  • _PAL – режим PAL;
  • _NTSC – режим NTSC.
  • 0 – в случае удачного соединения, 4 – в случае неудачи (недостаточно памяти для буфера вывода).

Функции задержки

Функция delay() осуществляет задержку выведенного изображения.
Синтаксис:

  • ms – задержка в мс с точностью: 20 мс для PAL и 16 мс для NTSC.


Функция delay_frame() осуществляет задержку выведенного изображения.
Синтаксис:

Функция полезна для сведения к минимуму или устранения на мерцание экрана, вызванные обновлением экрана.

Функции получения параметров

Функция hres() возвращает горизонтальное разрешение экрана.
Синтаксис:

  • unsigned char – горизонтальное разрешение экрана.


Функция vres() возвращает вертикальное разрешение экрана.
Синтаксис:

  • unsigned char – вертикальное разрешение экрана.


Функция char_line() возвращает максимально возможное количество символов в одной строке при выводе текстовой информации.
Синтаксис:

Основные графические функции

Функция set_pixel() устанавливает цвет пикселя экрана в точке с заданными координатами.
Синтаксис:

  • x,y – координаты пикселя;
  • color – цвет пикселя:
  • 0 – черный;
  • 1 – белый;
  • 2 – инвертировать цвет.

Функция get_pixel() получает цвет пикселя экрана из точки с заданными координатами.
Синтаксис:

  • color – цвет пикселя:
  • 0 – черный;
  • 1 – белый;
  • 2 – инвертировать цвет.

Функция fill() заполняет экран заданным цветом.
Синтаксис:

  • color – цвет заполнения:
  • 0 – черный;
  • 1 – белый;
  • 2 – инвертировать цвет.

Функция clear_screen() очищает экран, заполняя заданным цветом.
Синтаксис:

  • color – цвет заполнения:
  • 0 – черный;
  • 1 – белый;
  • 2 – инвертировать цвет.


Функция invert() инвертирует содержимое экрана.
Синтаксис:

Функция shift_direction() сдвигает содержимое экрана.
Синтаксис:

  • distance – расстояние для сдвига содержимого экрана.
  • direction – направление сдвига:
  • UP=0 – вверх;
  • DOWN=1 – вниз;
  • LEFT=2 – влево;
  • RIGHT=3 – вправо.


Функция draw_line() соединяет на экране линией две точки.
Синтаксис:

  • x0,y0 – координаты первой точки;
  • x1,y1 – координаты второй точки;
  • color – цвет заполнения:
  • 0 – черный;
  • 1 – белый;
  • 2 – инвертировать цвет.

Функция draw_row() заполняет строку указанным цветом между двумя точками строки.
Синтаксис:

  • row – вертикальная координата строки;
  • x1,x2 – горизонтальный координаты точек строки;
  • color – цвет заполнения:
  • 0 – черный;
  • 1 – белый;
  • 2 – инвертировать цвет.

Функция draw_column() заполняет строку указанным цветом между двумя точками столбца.
Синтаксис:

  • column – горизонтальная координата столбца;
  • y1,y2 – вертикальные координаты точек столбца;
  • color – цвет заполнения:
  • 0 – черный;
  • 1 – белый;
  • 2 – инвертировать цвет.

Функция draw_rect() рисует на экране прямоугольник.
Синтаксис:

  • TVOut.draw_rect(x,y,w,h,color);
  • TVOut.draw_rect(x,y,w,h,color,fillcolor);
  • x,y – координаты левой верхней точки;
  • w,h – ширина и высота рисуемого прямоугольника;
  • color – цвет границ прямоугольника:
  • 0 – черный;
  • 1 – белый;
  • 2 – инвертировать цвет.
  • fillcolor – цвет заполнения прямоугольника:
  • 0 – черный;
  • 1 – белый;
  • 2 – инвертировать цвет.

Функция draw_circle() рисует на экране круг.
Синтаксис:

  • TVOut.draw_ circle(x,y,r,color);
  • TVOut.draw_ circle(x,y,r,color,fillcolor);
  • x,y – координаты центра круга;
  • r – радиус круга;
  • color – цвет границ круга:
  • 0 – черный;
  • 1 – белый;
  • 2 – инвертировать цвет.
  • fillcolor – цвет заполнения круга:
  • 0 – черный;
  • 1 – белый;
  • 2 – инвертировать цвет.

Функция bitmap() выводит на экран растровое изображение.
Синтаксис:

  • x,y – координаты левого верхнего угла точки вывода;
  • bmp – указатель на массив памяти, где хранится картинка;
  • w,h – ширина, высота выводимого изображения;

Ниже рассмотрим процесс создания кода выводимых растровых изображений.

Функции вывода текстовой информации

  • font4x6;
  • font6x8;
  • font8x8;
  • font8x8ext.

Функция select_font() выбирает шрифт для вывода текстовой информации.
Синтаксис:


Функция print_char() выводит символ на экран.
Синтаксис:

  • x,y – позиция на экране для вывода символа;
  • char – символ из текущего шрифта.


Функция set_cursor() устанавливает позицию курсора для вывода текстовой информации на экран.
Синтаксис:

Функция print() выводит на экран строку, символ или число.
Синтаксис:

  • TVOut.print(x,y,string);
  • TVOut.print(x,y,char,base);
  • TVOut.print(x,y,int,base).
  • x,y – координаты курсора.
  • base – формат вывода:
  • BYTE = 0;
  • DEC = 10 (default);
  • HEX = 16.


Функция println() выводит на экран строку, символ или число и в конце символ перевода строки:
Синтаксис:

  • TVOut.println(x,y,string);
  • TVOut.println(x,y,char,base);
  • TVOut.println(x,y,int,base).
  • x,y – координаты курсора.
  • base – формат вывода:
  • BYTE = 0;
  • DEC = 10 (default);
  • HEX = 16.

Функции вывода аудио

Функции вывода звука позволяют отправлять на телевизор через аудиовыход сигнал определенной частоты.
Функция tone() выдает аудиосигнал определенной частоты.
Синтаксис:

  • TVOut.tone(frequency,duration);
  • TVOut.tone(frequency).
  • frequency – частота аудиосигнала;
  • duration – длительность сигнала.

Функция noTone() прекращает выдачу аудиосигнала.
Синтаксис:

Создание собственных шрифтов

Рассмотрим процесс создания пользовательских шрифтов для библиотеки TVOut.

Библиотека позволяет создавать собственные шрифты.
Существуют два вида шрифтов – фиксированной и переменной ширины. Для шрифтов фиксированной ширины первые три байта массива содержат данные о ширине символа (4), высоте символа (6) и первый печатный символ (32) . Затем идут данные для каждого последующего символа.

Для шрифтов переменной ширины в описании каждого символа первый байт определяет ширину данного символа.

Создадим пользовательский шрифт myfont1. Для пользовательского шрифта myfont1 в папке TVOutfonts создаем 2 файла: myfont1.h и myfont1.cpp.
Вот содержимое файла myfont1.h

Теперь для использования библиотекой TVOut нашего пользовательского шрифта myfont1 в скетче необходимо подключить файл

Создание графических примитивов.

Библиотека TVOut позволяет загружать на экран растровые изображения. Рассмотрим создание кода для загрузки растрового изображения функцией bitmap() библиотеки TVOut.

Сначала необходимо создать 1 битное (двухцветное изображение), например в графическом редакторе Paint.

ris21_03.jpg

ris21_04.jpg

Нажимаем на кнопку Convert и получаем массив.

ris21_05.jpg


Далее создаем 2 файла. Первый c расширением .h, например MyBitmap1.h.


Далее создаем файл MyBitmap1.cpp , в него (в поле данных массива unsigned char MyBitmap1[]) копируем данные конвертации, убирая символы "", и вставляя в начале ширину и высоту изображения в пикселах.

Сохраняем файлы MyBitmap1.h и myBitmap.cpp в директории нашего скетча. Для вывода нашего изображения на экран телевизора вызываем функцию TVOut.bitmap():

C библиотекой ознакомились, собрана игровая консоль - теперь можно приступать к написанию игры.

victoruni Опубликована: 02.02.2013 0 0


Вознаградить Я собрал 0 1


Но ясный пень, в таком виде ( вывод в COM-порт ) игра представляет скорее академический интерес для очень маленького круга заинтересованных людей. Давайте двигаться дальше. А не реализовать ли нам все это в виде портативной игровой консоли?? Я понимаю, что ПОРТАТИВНАЯ ИГРОВАЯ КОНСОЛЬ звучит достаточно громко, но попытка-не пытка.
Давайте разберемся в составных частях (модулях) настоящих приставок (Tetris, GameBoy,PSP, NDS и т.п.).

1) Экран. Отображает игровую ситуацию и всякую полезную информацию;
2) Органы управления (кнопки, джойстики, сенсорный ввод и т.п.);
3) Система энергоснабжения (АКБ, зарядное, преобразователь и т.п.);
4) Звуковая подсистема;
5) Основной “мозг”-процессор приставки.

Так вот, все эти модули (в том или ином виде) будут и в нашем сокобане.


Экран.
Это самый важный компонент будущей игровой приставки. С него то я и начал. Если бы этот этап завершился неудачей, я вряд ли бы продолжил работу над этим проектом.
Очень-очень долго у меня валялась парочка графических экранов 128x64. Ну никак я не мог найти им достойного применения. Экранчик достаточно большой по габаритным размерам (больше самого Arduino). Я уже как-то давно пытался найти ему применение и даже сделал некий шилд для удобного и быстрого подключения к Ардуино. Но при использовании стандартной библиотеки на МК Atmega8 практически не оставалось памяти для чего-то полезного. Экран пролежал у меня на столе пару дней с демонстрашкой работы (наверняка вы ее видели, там что-то типа круга, и рисуются диагональные линии с подсчетом FPS) и отправился отдыхать на неопределенное время в коробочку со всякими остальными “проектами-недоделками”.

А тут такой вариант. Зачем что-то искать или покупать! Как говорит Иванович — “Используй то, что под рукою и не ищи себе другого”!

Хорошее описание подключения такого дисплея и работы с ним есть тут .

Далее по схеме. Такое подключение (данные передаются только в одну сторону MK->GLCD) не подразумевает чтение из GLCD, а это значит, что линию R/W тоже можно принудительно посадить на землю. Вот тебе и еще один сэкономленный пин!

Вторая схема на 74HC165 . Это сестра-антипод моей любимой 74HC595. Эта микросхема преобразует параллельный интерфейс в последовательный. Толковое описание тут . Такой вариант по функционалу полностью аналогичен первой схеме (со всеми недостатками и достоинствами), но более экономичен в плане необходимых пинов — 3 штуки.

Как-то эти варианты громоздки и увесисты. И, что самое главное, у меня этих микросхем под рукой не оказалось.

Обычно производители рекомендуют заряжать Li-Ion АКБ постоянным током не более 70% от емкости АКБ. Странная связь — “Емкость — ток”. Как в анекдоте про прапорщика, связавшего время и пространство: ”Копать отсюда и до обеда”. Лучше я поясню примером: АКБ 1000 mAh (или 1Ah), значит максимальный ток заряда должен быть не более 0.7А. Меньше — не страшно. В данной схеме максимальный ток определяется номиналом резистора R13.
Расчет такой: R13=0.65/Imax. Для заряда током 0.5А => R13=0.65/0.5=1.3 Ома.
Магическая константа 0.65 — это всего лишь напряжение на базе для полного открытия биполярного транзистора T2.

Настройка схемы трудностей не вызывает.
1. Без нагрузки (не подключая АКБ) устанавливаем подстроечным резистором R12 напряжение 4.2 Вольта на выходе подключения АКБ.
2. Подключаем батарею.
3. Проверяем ток зарядки (напомню, что он не должен превышать расчетного. Читай выше).
4. Ожидаем погасания светодиода (может занять прилично времени). Батарея заряжена.

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

Преобразователь напряжения.
Для питания всего нашего устройства нужно 5 вольт. Li-ion АКБ выдает 3.7 Вольта. А это значит, что нам нужен DC-DC преобразователь, причем Step-Up, т.е. из низкого напряжения в высокое. Такой преобразователь можно купить у китайцев в виде готовой платы, но долго ждать. Да и не наш это метод. Сделаем сами. Теорию о принципах работы такого рода преобразователей советую почитать у DiHalta .
Схема такая:

Нетипичное соотношение резисторов R8 и R9, а именно эта парочка определяет значение напряжения на выходе, обусловлено наличием в схеме диода D6. Кстати, как оказалось при дальнейшем проектировании схемы, он не особо нужен. Если выбросить из схемы этот диод, то значения резисторов (для получения на выходе 5 вольт) должны быть такие R9=3kOm, R8=1kOm.
Конечно же, я предварительно протестировал работоспособность зарядной части и преобразователя. Первоначальный прототип силовой части (для тестирования и отладки) выглядел у меня так:

Плата сделана под SMD элементы из-за лени сверлить отверстия :)

Звук.
Ну и для воспроизведения звука в данной поделке вполне достаточно обычного биппера.
Конденсатор С5 и подключение к пину с аппаратным ШИМ — лишние и в схеме остались рудементально. Это часть так называемой RC-цепочки. Дело в том, что когда я смотрел на проект в “крупную клетку”, я думал, что звук будет полифоническим… Не осилил :( По крайне мере пока. А в схеме решил оставить, так сказать, на перспективу.


Ой! “А слона-то я и не приметил”!
Чуть не забыл. Естественно, мозгом всей системы будет… будет… (барабанная дробь)… АР-ДУ-И-НО. (Хм, прямо как в песне: “Ту-ру-ту-ту-ту-ту, скажите как его зовут. ”). Но небольшое уточнение. Дело в том, что после приобретения корпуса, я понял, что стандартную Ардуино разместить внутри его не получится. Но у меня уже давно лежал без дела один из подарков за участие в конкурсе “Кибервесна” — это контроллер универсальный ORduino Nano v. 1.1+. Маленький, с mini-USB на борту, полностью совместимый по функционалу с “большой Ардуиной”. Он идеально подойдет для моих целей.


Окончательно схема нашей игровой консоли выглядит так:

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

Чуть чуть лирики. Процедура “разместить в корпус” у моих друзей на работе всегда вызывает улыбку. В моем близком окружении сделать “это” хорошо никогда никому не удавалось. Из какого бы материала ни был корпус (пластик, металл, дерево, стеклотекстолит), какие бы ухищрения для предварительной разметки ни использовали, какие бы ( из доступных нам) инструментов ни применялось — результат никогда не был “идеальным”. Да, мы можем сделать и спаять практически идеальную плату или схему, но получить законченное, подогнанное изделие с аккуратными отверстиями пока никак. Да и честно говоря, мы уже перестали на работе подтрунивать друг над другом за кривые отверстия, неровно расположенные элементы управления, разношерстные болты и гайки, которые присутствуют на наших самоделках.

На верхней половинке корпуса я разместил экран и пять кнопок. Под круглыми накладками-грибками (колпачками) размещена печатная плата с кнопками.



Пришлось повозиться с установкой этой платы, размещая ее на нужной высоте. Нужно было добиться такого положения, чтобы кнопки-накладки не проваливались очень глубоко, но и не нажимали кнопочки на плате от нечего делать (самопроизвольно). Я нашел подходящий по высоте кусок пластика и просто приклеил площадки к корпусу суперклеем. Сам удивлен, но эта часть (экран и кнопки) вышла более чем неплохо.


Ниже фото “предпоследней примерки”. Верхняя половинка — экран и кнопки, нижняя — основная плата и Ардуино. АКБ пока не установлен.

Окончательно готовая игровая приставка выглядит так:

вид сбоку:

С такого ракурса видны: кнопка включения, индикатор заряда и кривенькое отверстие под mini-USB разъем :)

Пришло время захватить мир

Пришло время захватить мир

В настоящее время они довольно устарели, и только самые ностальгирующие геймеры будут играть на ней. Для тех из нас, кто перешел на современные системы или просто пытается идти в ногу с повседневной работой, NES стала пылесборником. Но, если вы возитесь с электроникой, NES может стать полезной в DIY мире с помощью своего простого в управлении контроллера. Контроллер NES может управлять множеством предметов от освещения до робота и даже до вашего устройства судного дня – его возможности зависят только от вашего воображения! Для этого проекта мы будем использовать не более чем Arduino Uno и контроллер NES, чтобы продемонстрировать, насколько просто они могут взаимодействовать.

Перечень компонентов

Аппаратное обеспечение:

  • Arduino Uno;
  • перемычки для макетной платы;
  • NES контроллер (оригинальный или аналог);
  • макетная плата (необязательно);
  • удлинитель NES (необязательно).

Программное обеспечение:

Теория

Способ использования 4021 можно увидеть ниже. Это схема того, как контроллер NES выглядит изнутри.

Схема контроллера NES

Схема контроллера NES

Чтобы подвести итог, код Arduino должен выполнять следующее:

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


Задняя панель контроллера NES

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

Печатная плата контроллера NES

Печатная плата контроллера NES

Теперь вы можете увидеть обратную сторону печатной платы. Конкретно эта печатная плата изготовлена из гетинакса, что является обычным явлением в бытовой электронике, поскольку он намного дешевле в производстве. Однако, в качестве примечания, большинство качественных печатных плат изготавливаются из стеклотекстолита. Помимо печатной платы, вы можете увидеть микросхему 4021 вместе с проводами кабеля. Можно поразиться, насколько всё просто. Инженеры Nintendo сделали это, сохранив высокую функциональность, всего на одной микросхеме. Чтобы увидеть другую сторону печатной платы, осторожно снимите ее. Если вы внимательно посмотрите на дорожки, то сможете заметить, что их рисовали вручную. Должно быть, это был довольно сложный процесс. Вы можете заметить, что на другой стороне нет резисторов. Но для опытного взгляда они находятся на виду. На самом деле это черные прямоугольники с блестящей зеленой поверхностью. Это углеродные резисторы, которые были напечатаны на печатной плате, чтобы сэкономить время и деньги. И так как они имеют одинаковый номинал, это, вероятно, было идеальным решением в то время. Последнее, что нужно убрать с контроллера, – это контакты кнопок и резиновые кнопки. Они работают за счет того, что черная круглая часть резиновой прокладки устанавливает соединение между контактами кнопки с помощью углеродного слоя. Хотя он не кажется проводящим, его достаточно, чтобы установить логический высокий или низкий уровень состояния кнопки.

Передняя часть платы контроллера NES

Передняя часть платы контроллера NES

Соединим всё вместе

Схема соединений в этом проекте довольно проста, так как разъем контроллера NES легко позволяет использовать перемычки для макетных плат. Конечно, если вы хотите что-то более надежное, то можно купить удлинитель кабеля контроллера NES, разрезать его и воспользоваться проводами из него. Таким образом, вы можете вставить их напрямую в Arduino, получив надежное соединение и ответный разъем для контроллера.

Схема соединений показана ниже.

Схема подключения контроллера NES (Dendy) к Arduino Uno

Схема подключения контроллера NES (Dendy) к Arduino Uno

Как вы можете видеть, контроллеру для взаимодействия требуются только 5 из 7 контактов. Два для питания (+5V и GND), один для фиксирования состояния кнопок (D2), один для тактового сигнала состояний кнопок (D3) и один для считывания последовательных данных о состояниях кнопок (D4)

Код Arduino

Мысли на будущее

Если вам понравился данный проект, и вы хорошо научились взаимодействовать с контроллером NES, то контроллер SNES – это почти то же самое, но с большим регистром сдвига (16 бит вместо 8 бит).

Читайте также: