Dingoo A320 vs Arduino

Последняя мода на превращение Dingoo A320 в «аркадный кабинет» не оставлят и нашу лабораторию «сумасшедшего профессора». Сегодня мы подключили  джойстик от Super Nintendo к Dingoo A320 с помощью платы Arduino.

Сперва оговоримся, зачем все это. Самый простой ответ — «because we can». А если детально, то…

Очень хочется аркадный кабинет на базе A320. Да и Dingoo для экспериментов есть. Но для аркадного кабинета требуется аутентичный джойстик, не менее аутентичные кнопки — все это, конечно же, можно купить… Но конструкция, получаемая в результате — как ни крути — БОЛЬШАЯ. Да и затратно получается, как ни крути — и экран, и все остальное стоит денег. Многое придется СЛОМАТЬ в процессе постройки, а мы любим СОЗДАВАТЬ.

Вот она — мечта:

Итак, цель эксперимента — подключить джойстик от Super Nintendo, как наиболее подходящий по форм-фактору к Dingoo A320 без разрушения оного. Конечно, можно было рассверлить чип, вывести 13(!) проводов и все это подпаять к кнопкам A320, но мы пойдем другим путем — работающие SNES контроллеры не растут на деревьях.

Известно, что к Arduino c помощью библиотеки NesPad без проблем можно подключить эти самые джойстики. Ок, возьмем на заметку.

Вторая проблема — у Arduino нет того количества ножек, которые потребуются нам. 3 сигнала с SNES pad и 12 сигналов на Dingoo… Итого 15 — лимит превышен. Значит, будем размножать.

К счастью, в сети есть замечательные tutorial’ы, в частности один из них — от нашего соотечественника — Ильи Данилова. Вот схема оттуда, которая решает проблему.

Легким движением паяльника 3 выхода Arduino превращаются в 16 с помощью 8битного сдвигового регистра 74HC595.

Пора соединять одно устройство с другим. Но, нужно учесть один момент — Dingoo A320 оперирует с 3мя вольтами, а Arduino с 5ью. Для согласования сигналов будем использовать следующую схему:

В качестве диода используем 1N4148, а в качестве резистора — 100 Ом 0.125 ватт. Такая схема «не пропустит» 5 вольт через диод, но отлично сработает, когда будет «удавливать» выход кнопки  при нажатии. Хотим передать «СПАСИБО» администрации сайта zx-kit.ru за оказанные консультации!

Ну и последний штрих — «скетч» или «прошивка» для Arduino:

#include <SNESpad.h>

#define DS   11
#define SHCP 12
#define STCP 8

//"Near" 7hc595 is one connected directly to Arduino. The "Far" one is 
//"cascaded" to it.

//The signals are like this:
// Q7-Q1,Q15 are from high bit to lowest. (128-64-32-16-4-2-1)
// firstly "far" 7hc595 is stuffed, then the near one
// see "send2out"

//state definitions for out1 - "near" 7hc595

#define SELECT 0b01111111
#define START  0b10111111
#define A      0b11011111
#define B      0b11101111
#define X      0b11110111
#define Y      0b11111011
#define LSHIFT 0b11111101
#define RSHIFT 0b11111110

//state definitions for out0 - "far" 7hc595

#define UP     0b01111111
#define DOWN   0b10111111
#define LEFT   0b11011111
#define RIGHT  0b11101111
#define RESET  0b11110111
#define POWER  0b11111011
#define HOLD   0b11111101
#define UNUSED 0b11111110

byte decodeNear(int state)
{
  byte res=0b11111111;
  if ( state & SNES_SELECT )
    res = res & SELECT;

  if ( state & SNES_START )
    res = res & START;

  if ( state & SNES_A )
    res = res & A;

  if ( state & SNES_B )
    res = res & B;

  if ( state & SNES_X )
    res = res & X;

  if ( state & SNES_Y )
    res = res & Y;

  if ( state & SNES_L )
    res = res & LSHIFT;

  if ( state & SNES_R )
    res = res & RSHIFT;

  return res;

}

byte decodeFar(int state)
{
  byte res=0xff;
  if ( state & SNES_UP )
    res = res & UP;

  if ( state & SNES_DOWN )
    res = res & DOWN;

  if ( state & SNES_LEFT )
    res = res & LEFT;

  if ( state & SNES_RIGHT )
    res = res & RIGHT;

  // the rest shoud be processed in other place-because snes have only 12 btns  
  return res;
}

void send2out(byte out0, byte out1)
{

  shiftOut(DS,SHCP,MSBFIRST,out0); //far one
  shiftOut(DS,SHCP,MSBFIRST,out1); //near one
  digitalWrite(STCP,HIGH);
  delay(1);
  digitalWrite(STCP,LOW);

}

// setting up arduino pins for connection - as in snespad example
//strobe/clock/data
SNESpad nintendo = SNESpad(2,3,4);

int state = 0;
int currentstate = 0;
byte out0 = 0xff;
byte out1 = 0xff;
void setup() {
  pinMode(13, OUTPUT);

  pinMode(DS,OUTPUT);
  pinMode(SHCP,OUTPUT);
  pinMode(STCP,OUTPUT);
  digitalWrite(SHCP,LOW);
  digitalWrite(STCP,LOW);
  digitalWrite(13,HIGH);

  send2out(0xff,0xff); //pull all high

}

void loop() {

  currentstate = nintendo.buttons();
  if(state != currentstate)
  {
    out0=decodeFar(currentstate);
    out1=decodeNear(currentstate);

    //power,reset,hold are processed here (tbd)
    send2out(out0,out1);

  }
  state = currentstate;

}

Интересно посмотреть, что получилось в итоге.
Видео всего процесса запуска.

Что дальше ? Попробовать сделать отдельную плату небольшого формата и запустить всю схему от встроенного кварца на 8 Мгц. И вперед! Проектировать собственный Arcade Cab 😉

Обсуждение на Dingoonity

 



Добавить комментарий

Комментарии доступны через Intensedebate. Включите JavaScript.