Fui convidado para palestrar sobre Arduino (pra variar... ;-) na Semana de Computação da UFF (de 8 a 11 de novembro de 2010) e, sempre que apresento a plataforma de hardware e software livres, gosto de demonstrar exemplos e um projeto - por exemplo: no FISL11 demonstrei o Turiquinhas, no Dev in Rio 2010 demonstrei o Semáforo DojoRio.
Como o Turiquinhas ainda está na oficina (com o eixo quebrado), resolvi fazer um pequeno projeto prático para apresentar na Semana de Computação da UFF: como controlar servomotores utilizando um controle de SNES.
Foto por armless
Apresentei esse projeto também na Latinoware 2010, em Foz do Iguaçu/PR (dentro da Itaipu Binacional) - que foi um evento sensacional! Para quem não teve a oportunidade de assistir, seguem os slides de minha palestra, que não mudaram muito de um evento para o outro:
Chega de enrolação - vamos agora então falar de como pegar os dados do controle de SNES com o Arduino! Inicialmente, para fazer a aquisição dos dados (saber quais botões estão pressionados no momento), tentei utilizar a biblioteca NESpad/SNESpad, porém não obtive sucesso - já havia tentado utilizá-la no FISL11, junto com o Fávio Amieiro, mas ela não funcionou, porém na época não pesquisei a fundo sobre o problema. Dessa vez resolvi pesquisar mais sobre, aprendi como um controle de SNES funciona internamente e verifiquei que a temporização da biblioteca não estavam corretos, daí postei uma issue no issue tracker do NESpad para que eles corrijam o problema, porém o autor disse que nos controles de SNES dele a temporização funcionava. Então decidi criar uma função (no melhor estido DIY :D) para fazer aquisição dos dados de acordo com a descrição que havia lido. Em breve darei mais uma olhada na biblioteca para verificar qual problema pode ter acontecido e tentar fazê-la funcionar para qualquer controle (pode ser que o controle que o autor da biblioteca tenha utilizado funcione de forma diferente do meu).
Antes de mostrar o código, vamos ver como o controle de SNES se comunica com o mundo externo: o conector possui 7 pinos, onde apenas 5 são realmente utilizados. Veja o esquema:
Basicamente, internamente o controle do SNES tem um registrador de 16 bits cuja saída é serial (entrada possivelmente paralela). O que temos que fazer é dar um pulso no pino
strobe e então pegar bit a bit (no total são 16) no pino
data, dando um pulso entre cada bit no pino
clock a cada 6 microsegundos (período = 12 microsegundos). Os pinos
+5V e
GND fornecem energia para o circuito interno do controle e os pinos
N/C não são utilizados.
O que fiz então foi uma função que respeita a temporização e joga os 16 bits em uma variável do tipo unsigned int; a função demora em torno de 200 microsegundos para retornar esse inteiro (de 16 bits) - o detalhe é que o controle tem apenas 12 botões (cima, baixo, esquerda, direita, A, B, X, Y, select, start, L e R), então os 4 bits mais significativos do registrador de 16 bits não são utilizados (vêm sempre com o mesmo valor). Outro ponto importante é que o registrador é ativado em baixa (1 = botão não pressionado, 0 = botão pressionado), então no final da minha função eu inverto bit a bit dos valores lidos, para facilitar o uso dos dados. Além disso, defini algumas constantes que relaciona a posição do bit com cada botão do controle (exemplo: o botão B corresponde ao bit menos significativo). O código, que está disponível no meu BitBucket, ficou assim:
O código acima apenas lê os valores e controla dois servomotores e um alto falante, de acordo com os botões que foram pressionados. A cada loop, pego o estado dos botões com o comando:
buttonsPressed = getSNESbuttons(CLOCK, STROBE, DATA);
(os parâmetros da função são os números dos pinos onde o clock, strobe e data estão ligados) e para verificar, por exemplo, se o botão para cima foi apertado, faço um AND bit-a-bit com a constante relativa a esse botão:
if (buttonsPressed & SNES_UP) {
//apertou botão para cima...
}
Segue a foto do projeto que apresentei nas palestras:
Arduino + controle de SNES + servomotores + alto falante (foto por Tatiana Al-Chueyr, Latinoware 2010)
Sobre esse pequeno projeto e a palestra que ministrei na UFF: parece que a galera gostou - bastante gente da UFF entrou na lista ArduInRio. :-)
Ficou interessado? Gostou do artigo? Quer saber mais sobre o Arduino? Que tal fazer um Curso de Arduino no Rio de Janeiro? ;-) Caso tenha utilizado a função que criei (ela é software livre!) ou tenha qualquer dúvida, comente!