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.
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:

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:
Genial! Parabéns pela idéia e pela implementação =)
Nossa, realmente muito bom.
Parabéns!
FABULOSO, PODRIA PUBLICAR EL DIAGRAMA ELECTRONICO ?
GRACIAS
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).
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!
(:
Olá!
Entrei em seu blog para conhecer e fiquei admirada e contente por você!
Parabéns! Grande idéia!
Bjos
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
Oi Adriana! Valew!
:-)
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
good ! I’m learning……
Thank you! You often write very interesting articles. You improved my mood.
Hi Bruno
great job. What kind of potentiometers did you use. 100K 50K
Thanks
Chris
Hello, Jibby, thanks!
5K Potentiometer
Can I use your code in my own projects? What license is it released under?
You can use, just give the link to the site please:)
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!
Thanks Brent, I’m sure you can connect different matrices using the “Direct Driver” if it has at most 8×8 LEDs.
Good luck
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
hi Jaime, more infos about TimeOne: http://www.arduino.cc/playground/Code/Timer1
thanks
what pins did you have the potentiometers go to?
#define PIN_LEFT 4
#define PIN_RIGHT 5
Thanks, and then the other leads on the potentiometer go to 5v and ground?
figured it out, what resistance of potentiometer did you use? because my paddle is moving very fast
Sorry didn’t see the post about the 5k resistance, thanks for everything.
You can manipulate the code to adapt the speed:
left = constrain(map(left, 223, 800, 0, 6), 0, 6);
right = constrain(map(right, 223, 800, 6, 0), 0, 6);
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…
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.
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.
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?
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).
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.
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
hey man, where can we get an english version of you site,
great work by the way!
At the moment I have no version in English.
But you can try Google Translator (http://translate.google.com.br/translate?js=n&prev=_t&hl=pt-BR&ie=UTF-8&layout=2&eotf=1&sl=pt&tl=en&u=http%3A%2F%2Fblog.bsoares.com.br%2Farduino%2Fping-pong-with-8×8-led-matrix-on-arduino).
Thanks
hello it’s very cool and nice games :)
thank you
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
Very good :)
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.
Oi,
Engenhoso, mas me diga a verdade você teve de treinar bastante para jogar dessa forma certo? :)
e assim nasceu o playestation xbox e nintendo etc.
:)
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 :)
TimeOne:
http://www.arduino.cc/playground/Code/Timer1
Desculpe, você poderia me dar o diagrama de montagem de todo o projeto?
Diagrama da Matriz:
http://www.arduino.cc/playground/Main/DirectDriveLEDMatrix
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.
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.
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
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.
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!
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?
ou, aparece que o Timer1 nao foi declarado, como posso resolver isso? obrigado
O que controla a posiçao das tabelas como e que se chama? é uma resistencia variavel ou um potenciometro?