Ping Pong com Matriz de Leds 8×8

Há alguns dias consegui duas matrizes de leds 8×8 azuis e resolvi brincar com elas :)
O resultado foi um jogo de Ping Pong, sim O primeiro videogame lucrativo da história. É de fato um joguinho bem interessante e facíl para quem pratica eletrônica digital por hobby.

Em primeiro lugar achei melhor criar um protótipo do game em Flash (ActionScript 3.0) para não ficar “queimando os miolos” direto no C++. Pra quem quiser anexo o código fonte do game final e protótipo aqui.

This movie requires Flash Player 9

Espaço para iniciar.
Seta para cima e para baixo para mover as astes.

Para ligar e desligar cada led da matriz utilizei como referência o código encontrado no Arduino Playground (http://www.arduino.cc/playground/Main/DirectDriveLEDMatrix), só que minha matriz é diferente do utilizado no exemplo, então fiz algumas pequenas alterações no método doubleBuffer. Resumindo, no exemplo encontrado no Playground a matriz utilizada tem a linha como cátodo já minha matriz tem a coluna como cátodo.
Abaixo a especificação da matriz utilizada:

8x8-led-matriz-especification

Código-fonte:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
/**
 * Ping Pong with 8x8 Led Dot Matrix on Arduino
 *
 * @author  Bruno Soares
 * @website www.bsoares.com.br
 */


#include "TimerOne.h"

#define PIN_LEFT 4
#define PIN_RIGHT 5

unsigned int left = 0;
unsigned int right = 0;
int angle = 0;
int radians;

byte rows[8] = {9, 14, 8, 12, 1, 7, 2, 5};
byte cols[8] = {13, 3, 4, 10, 6, 11, 15, 16};
byte pins[16] = {5, 4, 3, 2, 14, 15, 16, 17, 13, 12, 11, 10, 9, 8, 7, 6};
byte screen[8] = {0, 0, 0, 0, 0, 0, 0, 0};
volatile byte screenRow = 0;
volatile byte screenCol = 0;

int _angle;
int _px;
int _py;
int _w = 7;
int _h = 7;
int _wall[] = {3, 3};
int _count = 0;
int _speed = 3;
int _countPoints = 0;


void setup() {
  Timer1.initialize(100);
  for (int i = 2; i <= 17; i++)
    pinMode(i, OUTPUT);
  Timer1.attachInterrupt(doubleBuffer);
 
  Serial.begin(9600);
 
  face();
  reset();
}

void doubleBuffer() {
  digitalWrite(translatePin(rows[screenRow]), LOW);
  digitalWrite(translatePin(cols[screenCol]), HIGH);
 
  screenCol++;
  if (screenCol >= 8) {
    screenCol = 0;
    screenRow++;
    if (screenRow >= 8) {
      screenRow = 0;
    }
  }
 
  if((screen[screenRow] >> screenCol) & B1 == B1) {
    digitalWrite(translatePin(rows[screenRow]), HIGH);
    digitalWrite(translatePin(cols[screenCol]), LOW);
  } else {
    digitalWrite(translatePin(rows[screenRow]), LOW);
    digitalWrite(translatePin(cols[screenCol]), HIGH);
  }
}

byte translatePin(byte original) {
  return pins[original - 1];
}

void allOFF() {
  for (int i = 0; i < 8; i++)
    screen[i] = 0;
}

void on(byte row, byte column) {
    screen[column-1] |= (B1 << (row - 1));
}

void off(byte row, byte column) {
    screen[column-1] &= ~(B1 << (row - 1));
}

void calcWall()
{
  left = analogRead(PIN_LEFT);
  right = analogRead(PIN_RIGHT);
  left = constrain(map(left, 223, 800, 0, 6), 0, 6);
  right = constrain(map(right, 223, 800, 6, 0), 0, 6);
 
  clearWall();
 
  on(1, left + 1);
  on(1, left + 2);
  on(8, right + 1);
  on(8, right + 2);
 
  _wall[0] = left;
  _wall[1] = right;
  show();
}

void clearWall()
{
  for (int i = 0; i < 8; i++)
    screen[i] &= B01111110;
}

void clearGame()
{
  for (int i = 0; i < 8; i++)
    screen[i] &= B10000001;
}

void loop() {
  calcWall();
  enterFrameHandler();
  delay(50);
}

void enterFrameHandler()
{
  if (_count++ < _speed)
    return;
 
  _count = 0;
  checkCollision();
  calcAngleIncrement();
  show();
}

void retorted(int angle)
{
  Serial.println(angle);
  _angle = angle;
 
  if (++_countPoints % 5 == 0 && _speed > 1)
    _speed--;
}

void resetAnim()
{
  for (int i = 0; i < 8; i++)
  {
    screen[i] = B11111111;
    delay(25);
  }
  for (int i = 0; i < 8; i++)
  {
    screen[i] = B00000000;
    delay(25);
  }
}

void face()
{
  on(1, 1);
  on(1, 2);
  on(2, 1);
  on(2, 2);
  on(7, 1);
  on(7, 2);
  on(8, 1);
  on(8, 2);
  on(1, 1);
  on(1, 2);
  on(4, 4);
  on(4, 5);
  on(5, 4);
  on(5, 5);
  on(2, 7);
  on(7, 7);
  on(3, 8);
  on(4, 8);
  on(5, 8);
  on(6, 8);
  delay(5000);
}

void reset()
{
  resetAnim();
 
  _px = random(3, 5);
  _py = random(3, 5);
  _angle = random(0, 2) == 0 ? 0 : 180;
  _speed = 5;
  _countPoints = 0;
 
  show();
  delay(500);
}

void show()
{
  clearGame();
  on(_px + 1, _py + 1);
}

void checkCollision()
{
  if (_px == _w - 1)
  {
    if (_angle == 315 || _angle == 0 || _angle == 45)
    {
      if (_py == _wall[1] || _py == _wall[1] + 1)
      {
        if (_angle == 0 && _py == _wall[1])
          retorted(225);
        else if (_angle == 0 && _py == _wall[1] + 1)
          retorted(135);
        else if (_angle == 45 && _py == _wall[1])
          retorted(135);
        else if (_angle == 45 && _py == _wall[1] + 1)
          retorted(180);
        else if (_angle == 315 && _py == _wall[1])
          retorted(180);
        else if (_angle == 315 && _py == _wall[1] + 1)
          retorted(225);
      }
    }
  }
  else if (_px == 1)
  {
    if (_angle == 225 || _angle == 180 || _angle == 135)
    {
      if (_py == _wall[0] || _py == _wall[0] + 1)
      {
        if (_angle == 180 && _py == _wall[0])
          retorted(315);
        else if (_angle == 180 && _py == _wall[0] + 1)
          retorted(45);
        else if (_angle == 135 && _py == _wall[0])
          retorted(45);
        else if (_angle == 135 && _py == _wall[0] + 1)
          retorted(0);
        else if (_angle == 225 && _py == _wall[0])
          retorted(0);
        else if (_angle == 225 && _py == _wall[0] + 1)
          retorted(315);
      }
    }
  }
 
  if (_px == _w)
  {
    reset();
  }
  else if (_px == 0)
  {
    reset();
  }
  else if (_py == _h)
  {
    if (_angle == 45)
      _angle = 315;
    else if (_angle == 135)
      _angle = 225;
  }
  else if (_py == 0)
  {
    if (_angle == 225)
      _angle = 135;
    else if (_angle == 315)
      _angle = 45;
  }
}

void calcAngleIncrement()
{
  if (_angle == 0 || _angle == 360)
  {
    _px += 1;
  }
  else if (_angle == 45)
  {
    _px += 1;
    _py += 1;
  }
  else if (_angle == 135)
  {
    _px -= 1;
    _py += 1;
  }
  else if (_angle == 180)
  {
    _px -= 1;
  }
  else if (_angle == 225)
  {
    _px -= 1;
    _py -= 1;
  }
  else if (_angle == 315)
  {
    _px += 1;
    _py -= 1;
  }
}

Código fonte do experimento (Arduino e Flash).

Conteúdo relacionado:
Instructables
Mais fotos no Flickr
Ping Pong com Matriz de Leds 8×8 no YouTube
Arduino 8×8 LED Matrix Direct drive
O primeiro videogame lucrativo da história (Pong)
Led Dot Matrix
TimerOne


Posts relacionados:

  1. PianoDuino (Arduino + Processing + SoundCipher)
  2. Controlando Led RGB com Arduino e Processing
  3. Controlando a Arduino com PHP via porta serial
  4. Twitter Hardware
  5. Jogando Super Nintendo no Android com controle original

  1. Gui Ambros disse:

    Genial! Parabéns pela idéia e pela implementação =)

  2. Rafael Lima disse:

    Nossa, realmente muito bom.
    Parabéns!

  3. RAUL RENDON disse:

    FABULOSO, PODRIA PUBLICAR EL DIAGRAMA ELECTRONICO ?
    GRACIAS

  4. Bruno Soares disse:

    Olá Raul, você pode pegar o esquema do Direct Driver 8×8 Led Matrix no site da arduino (http://www.arduino.cc/playground/Main/DirectDriveLEDMatrix)
    http://www.arduino.cc/playground/uploads/Main/Matrix.gif

    Os dois potenciometros liguei nos pinos Analog IN (4 e 5).

  5. Idiana disse:

    Olá Bruno!

    Que muito montar o circuito.Porém não está acessando as paginas que você
    postou.E eu não compreendi a pci com as portas lógicas.A pci vem pronta ou podemos montá-la também?Gostaria que me enviasse o esquema elétrico e se possível informações a respeito do projeto com mais detalhes.Preciso apresentar um projeto do tipo e programar em C++.

    Obrigada!
    (:

  6. Adriana disse:

    Olá!
    Entrei em seu blog para conhecer e fiquei admirada e contente por você!
    Parabéns! Grande idéia!
    Bjos

  7. Bruno Soares disse:

    Olá Idiana, acho que pra começar você precisa saber que o projeto foi montando com a placa Arduino Diecimila (http://arduino.cc/).
    O esquema para você ligar a placa a Matriz de Led você encontra aqui: http://www.arduino.cc/playground/Main/DirectDriveLEDMatrix
    Depois de tudo conectado você pode baixar o programa que escrevi e gravar na Arduino, utilizando o software do proprio fornecedor (http://arduino.cc/en/Main/Software).

    qualquer dúvida posta ai :)
    vlw

  8. Bruno Soares disse:

    Oi Adriana! Valew!

    :-)

  9. james disse:

    Hi,bruno. Great work.
    We are LED dot matrix manufacturer in China.
    Anybody here want to source dot matrix or do LED business,please contact me
    james@ledlightmaker.com or go to http://www.ledlightmaker.com
    Thanks

  10. hxembed disse:

    good ! I’m learning……

  11. Kouba disse:

    Thank you! You often write very interesting articles. You improved my mood.

  12. Jibby disse:

    Hi Bruno
    great job. What kind of potentiometers did you use. 100K 50K
    Thanks

    Chris

  13. Bruno Soares disse:

    Hello, Jibby, thanks!
    5K Potentiometer

  14. Steven Osborn disse:

    Can I use your code in my own projects? What license is it released under?

  15. Bruno Soares disse:

    You can use, just give the link to the site please:)

  16. Bernt disse:

    Thanks for the sweet pong! I have a different matrix, but just adapted the pin mappings. I like your style of coding. I find it easier to understand than the scrolling text and the game of life in the ‘direct drive led matrix’ post on arduino.cc, even if its workings are more complex. Thanks again!

  17. jaime iuit disse:

    hi bruno parents are your projects, and I wonder if you kindly give me information about the library’s timerone is that I wanted to check your ping pong project but it generates an error on this parcel will appreciate it very much. thanks

  18. Taylor Bagshaw disse:

    what pins did you have the potentiometers go to?

  19. Bruno Soares disse:

    #define PIN_LEFT 4
    #define PIN_RIGHT 5

  20. Taylor Bagshaw disse:

    Thanks, and then the other leads on the potentiometer go to 5v and ground?

  21. Taylor Bagshaw disse:

    figured it out, what resistance of potentiometer did you use? because my paddle is moving very fast

  22. Taylor Bagshaw disse:

    Sorry didn’t see the post about the 5k resistance, thanks for everything.

  23. Alexandre disse:

    Gostaria de deixar aqui os meus parabéns pelo excelente blog e também fazer uma sugestão: a de publicar uma postagem aqui informando sobre a existencia do \Portal das Video Aulas\, um site que reuni diversas video-aulas gratuitas, que vão desde aulas de inglês, até como tocar violão… com o objetivo de democratizar o acesso ao conhecimento no Brasil. O endereço do site é http://www.portaldasvideoaulas.com.br
    Obrigado…

  24. Euclides Rezende disse:

    Boa noite Bruno.

    Seria possível usar os pinos que vão para a matriz 8 x 8, conectando em uma placa com optoacopladores e drivers para controlar motores de passo? É possível controlar os leds através do PC (e não por 1 programa dentro do Arduino)? Vc. tem como fazer este teste?

    Obrigado.

    • Bruno Soares disse:

      Olá, Euclides, é possível sim, vc pode usar um processing, flash, c#, c++, php, em fim, muitas linguagens pra fazer isto.
      Da uma olhada aqui no blog, tem exemplos com processing, php e flash.

      • Euclides Rezende disse:

        Bruno.

        Esta matriz é passiva, correto? Não tem memória, assim e necessário bufferizar o status de cada cruzamento para que atenda a um fio de motor. Qual a menor versão do Arduino capaz de controla-la. Vc. sabe?

        • Bruno Soares disse:

          A matriz é simples, a cada 100 microsegundos acendo um led. Não sei como vc quer ligar os motes.
          A arduino atual faz o trabalho muito bem (Uno – http://arduino.cc/en/Main/ArduinoBoardUno).

          • Euclides Rezende disse:

            Este Arduino:

            http://produto.mercadolivre.com.br/MLB-169623976-arduino-duemilanove-com-atmega328-_JM

            funcionaria?

            Veja este projeto:

            http://www.cncmania.com.br/site/projetos/phase_driver_herculano.rar

            A ideia seria colocar em cada interseccao dos LEDs uma etapa de potencia optoacoplada como a deste projeto. Os motores de passo seriam colocados a cada 4 LEDs (Cada motor precisa de 4 fios para acionamento) Minha duvida e se o acionamento dos 4 fios seriam feitos ao mesmo tempo ou se a multiplexao em camera lenta nao permitiria que a sequencia das bobinas dos motores fossem acionadas e assim o motor nao acionaria. Entendeu?

            Se for possivel, a etapa que vem do Arduino poderia acionar ate 8 x 8 = 64 / 4 = 16 Motores.

            Para o projeto que pretendo 8 ja bastam. Mas preciso tambem de sinalizacao se houver fim de curso. Para que todos os circuitos sejam paralizados para analise de ocorrencia de problemas. Controlando a matriz, sobram portas para se entrar com o sinal desses sensores?

            Se sim, seria possivel transmitir este sinal para o computador que esteja controlando tudo? Para que o programa enviasse um comando “zero” para todos os optoacopladores?

            Eu não tenho experiência com o Arduino, vc. poderia me dar assistência nesta parte?

            Obrigado se puder responder.

  25. Bruno Soares disse:

    Euclides, quanto a Arduino, acho melhor você já pegar o modelo mais novo (Arduino Uno). Comprei as minhas com este cara aqui:
    Rogerio – rgrp.silva [arroba] gmail com
    Foi mais barato que esta que você encontrou no mercadolivre e mais nova também.

    Quanto aos motores, a forma que ligo cada led na matriz é independente, ou seja, aciono uma lina e uma coluna d cada vez, durante um tempo muito curto, desta forma nunca fica mas que um fio ligado.

    Abraços e boa sorte

  26. mew disse:

    hey man, where can we get an english version of you site,

    great work by the way!

  27. gamezat disse:

    hello it’s very cool and nice games :)
    thank you

  28. Shadi Soundation disse:

    Thank you so much for the Inspiration and coding ! I wish you all the best.
    It took me a while to figure out the pin numbers for my matrix (24 pins, 2 colors) and adapt the code to my needs! I made a little modification by using red for one team and green for the another one! The Joysticks comes handy but its just a fancy additive !!
    http://vimeo.com/28466780

  29. Bruna Ramos disse:

    Bruno!
    Ótimo trabalho! Parabéns!
    Apenas não entendi uma coisa:

    O que fazem as váriaveis _count, _speed e _countpoints?

    Percebi que o jogo fica mais rápido após algum tempo, porém também não achei que parte do código faz isso, então atrelei a essas variáveis… se você pudesse me informar melhor…
    Obrigada!

    Bruna Ramos.

  30. Pedro Free disse:

    Oi,
    Engenhoso, mas me diga a verdade você teve de treinar bastante para jogar dessa forma certo? :)

  31. adailton disse:

    e assim nasceu o playestation xbox e nintendo etc.

    :)

  32. navneet disse:

    hiiiii bruno
    actually my arduino software giving an error on uploading the prog. code regarding TimerOne.h that there is no such directory exist..
    plz.. help me :)

  33. Biagio disse:

    Desculpe, você poderia me dar o diagrama de montagem de todo o projeto?

  34. adailton disse:

    ai amigo tem como diminuir a quantidade de fios usando algum transistor ou resistor? quero montar um painel grande mas a quantidade de fio que vai fica meio dificil de se tranalhar.

  35. Leandro Pereira disse:

    Olá, tenho uma dúvida sobre essas matrizes, é possível literalmente qualquer configuração de ligação dos leds dela? Pode soar ignorância mas não consigo entender como deixar, por exemplo, todos acesos menos o linha 7 / coluna 2… Estou errado ou existe esse tipo de limitação? Aguardo seu retorno.

    sds.

  36. saeed disse:

    Hi, how many header file i should add to library TimeOne.h and Time1.h .

    are they should kept in folder or just copy .H file and .CCP file to library . pls help

  37. I’m gone to tell my little brother, that he should also pay a quick visit this blog on regular basis to obtain updated from hottest news.

  38. Jonathan Ribeiro disse:

    Olá Bruno!

    Meu grupo está com um projeto na faculdade para a montagem de um trabalho em arduíno e fiquei bastante interessado no seu projeto de ping pong em matriz 8×8(http://blog.bsoares.com.br/arduino/ping-pong-with-8×8-led-matrix-on-arduino). Gostaria de saber como você configurou a montagem desses fios, procurei artigos na internet e não encontrei nada que pudesse aproveitar.

    Desde já agradeço a atenção dispensada.
    Obrigado!

  39. Ahmar disse:

    Hey, i couldn’t understand where to put potentiometer pins, pin 4 and 5 are already occupied by the matrix, you mean to say pin A4 and A5 on analog input? and please tell me how can we increase the size of bat which is currently of two dots to three or more?

  40. joaquim disse:

    ou, aparece que o Timer1 nao foi declarado, como posso resolver isso? obrigado

  41. Pedro Sousa disse:

    O que controla a posiçao das tabelas como e que se chama? é uma resistencia variavel ou um potenciometro?

  42. Muito bom cara! É sempre legal ver que a eletrônica ainda está viva e que o arduino nos possibilita expandir nossa criatividade. []s

  43. Nilton disse:

    hola buen proyecto, pero no me corre aparece eun error en Timer, porfa aque se debe

  44. fabio disse:

    olá estou tentando montar uma matriz de led 8×8 mas estou errando na programação ou tentando aprender tem como vc me explicar como eu faço ? na internet tem varios mas não consegui montar nenhum deles.

  45. fabio disse:

    OBS estou tentrando com pic linguagem c

  46. Thanks for sharing your info. I truly appreciate your efforts and
    I am waiting for your further write ups thanks once again.

  47. Alex disse:

    Hi Bruno,
    I’m trying to implement the game you made. I’m using your code and schematic for 8×8 Led matrix from Arduino Playground, it seams like you have used different scheme. Is there any chance you can do a quick sketch of the connections you have made?

    Thank you!

  1. There are no trackbacks for this post yet.

Leave a Reply