Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Rubio
Escuela de Ingeniería
Proyecto de Escritura en una Matriz LED 8x8
Usando Programación en Arduino
Profesor Guía
Ayudante
2 Solución...............................................................................................4
Discusión y conclusiones......................................................................10
Bibliografía............................................................................................11
A Un apéndice.......................................................................................13
Introducción
En el contexto de los grandes avances en las tecnologías de la información y
comunicaciones se hace cada vez más relevante para los profesionales universitarios,
especialmente ingenieros, el ambientarse y capacitarse en el uso de algoritmos y
lenguajes de programación que les permitan comprender los trabajos y ensayos
realizados por sus colegas, a la vez que les ayudan en la modelación y simulación de
los diversos variables que se encuentran presentes en los ámbitos que estudian o
investigan. No basta con ser capaz de utilizar alguno u otro software relativo a su
especialización, se requiere tener conocimientos de programación.
Debido a que este informe se realiza durante la primera asignatura de la carrera, que
tiene un carácter introductorio al mundo de la ingeniería, es que no se profundiza en
los distintos aspectos más técnicos del informe. El objetivo es una introducción a lo
que es la programación con código, no se espera obtener un amplio dominio del
lenguaje de programación, ya que eso está muy por sobre el alcance de este
proyecto.
El presente informe trata acerca del uso del microcontrolador conocido como
ARDUINO y de la implementación de un código que permita representar imágenes y
figuras fácilmente reconocibles en una matriz LED de 8x8 luces.
Objetivos generales
Obtener una primera aproximación a lo que son los lenguajes de
programación.
Desarrollar e implementar un código en el entorno de programación
ARDUINO.
Redactar en conformidad un informe que ocupe la plantilla de informes EIE.
1
Introducción
2
1 Antecedentes Generales y
Propuesta
El MAX7219 es ideal para controlar fácilmente una gran cantidad de diodos LED o
dígitos de 7 segmentos. También podemos controlar una matriz de LED de 8x8 con un
sólo chip.
1.3 Pong
El juego Pong es un juego de deportes en dos dimensiones que simula una mesa. El
jugador controla una paleta moviéndola verticalmente y puede competir tanto contra
la maquina u otro jugador humano. Los jugadores usan las paletas para pegarle a una
pelota de un lado hacia el otro. El juego consiste en que el jugador con más puntos
3
1Antecedentes Generales y Propuesta
Arduino Uno:
Potenciometro:
4
2 Solución
En el presente segmento se procederá a explicar el código utilizado en el proyecto
para la implementación del conocido juego Pong. No sea realiza una explicación
exhaustiva de cada línea de código ni de cada comando utilizado, ya que eso estaría
por sobre el alcance del presente proyecto, pero sí se realiza una explicación del
algoritmo de trabajo y de las distintas variables utilizadas.
Las primeras líneas de código hasta la línea 71 se utilizan principalmente para definir
diferentes parámetros y variables globales utilizados en el proyecto, los cuales se
detallan a continuación
5
Solución
byte sad: imagen que se presenta al comenzar una partida. Se define como 8
números binarios de 8 bits que indican con un 1 las luces de la matriz que
deben estar encendidas y con un 0 las luces que deben estar apagadas.
byte smile: imagen que se presenta al perder una partida. Se define de la
misma manera que el anterior.
byte direction: número de 8 bits que representa la dirección que puede tomar
la pelota. Puede tomar cualquier valor entre 0 y 7. El 0 corresponde al norte y
el resto de los valores toman la dirección que corresponde según el sentido
horario.
Intxball: posición actual de la pelota en el eje x.
Intyball: posición actual de la pelota en el eje y.
Intyball_prev: posición de la pelota en el eje y durante el estado anterior.
Byte xpad: número de 8 bits que se ocupa para definir la posición en el eje x
de la “paleta” en el juego. Corresponde a la totalidad de la paleta.
ball_timer: variable utilizada para asignar el delay al comenzar una nueva
partida.
79 void newGame(){
80 lc.clearDisplay(0);
81 // posición inicial
82 xball = random(1,7);
83 yball =1;
84 direction = random(3,6);// Movimiento al sur
85 for(int r =0; r <8; r++){
86 for(int c =0; c <8; c++){
87 lc.setLed(0, r, c, HIGH);
88 delay(NEW_GAME_ANIMATION_SPEED);
89 }
90 }
91 setSprite(smile);
92 delay(1500);
93 lc.clearDisplay(0);
94 }
6
Solución
96 void setPad(){
97 xpad = map(analogRead(POTPIN),0,1020,8- PADSIZE,0);
98 }
Entre las líneas 114 y 137 se definen tres nuevas variables que se ocupan para
analizar el estado actual de la pelota para saber cómo responder. La variable
checkBounce se ocupa para ver cuándo la pelota llega a los bordes del display.
Mientras la pelota no llegue a los bordes, la variable tendrá valor 0, pero si la pelota
llega a algún borde la variable tomará el mismo valor que la variable auxiliar bounce.
La variable getHit se ocupa para ver si la pelota toca a la paleta al llegar a la parte
inferior del display y toma diferentes valores dependiendo de en qué sección la pelota
toca a la paleta o si no la toca. La variable checkLoose toma el valor 1 cuando la
pelota llega a la parte inferior del display y la variable getHit tiene el valor de
HIT_NONE.
Las líneas de código entre la 139 y la 241 definen el movimiento de la pelota mientras
está en juego a través de la función moveBall. Cuando la pelota choca con algún
borde o con la paleta cambia su dirección dependiendo de la dirección desde la que
golpea y el lugar en el que golpea. Si todo funciona bien y la partida no ha terminado,
los valores de posición de la pelota en el eje x y en el eje y aumentan o disminuyen
en 1 durante cada iteración del programa.
7
Solución
8
Solución
202 }
203 if(direction ==2&& yball ==6){
204 direction =1;
205 }
206 if(direction ==6&& yball ==0){
207 direction =5;
208 }
209 if(direction ==6&& yball ==6){
210 direction =7;
211 }
212
213 // Caso de las esquinas
214 if(xball ==0&& yball ==0){
215 direction =3;
216 }
217 if(xball ==0&& yball ==6){
218 direction =1;
219 }
220 if(xball ==7&& yball ==6){
221 direction =7;
222 }
223 if(xball ==7&& yball ==0){
224 direction =5;
225 }
226
227 yball_prev = yball;
228 if(2< direction && direction <6){
229 yball++;
230 }elseif(direction !=6&& direction !=2){
231 yball--;
232 }
233 if(0< direction && direction <4){
234 xball++;
235 }elseif(direction !=0&& direction !=4){
236 xball--;
237 }
238 xball = max(0, min(7, xball));
239 yball = max(0, min(6, yball));
240 debug("AFTER MOVE");
241 }
La función gameOver cuando es llamada produce la imagen del byte sad en el display
por 1,5 segundos y luego apaga todas las luces. La función gameDraw traspasa la
información de posición de la pelota al display. Cada vez que la pelota cambia de
posición prende la luz que corresponde a la nueva posición y borra (apaga) la última
posición que tomó la pelota.
9
Solución
La función setup debe realizarse cada vez que se prenda el dispositivo, ya que el
modo normal del MAX7219 cada vez que se prende es el de ahorro de energía. Esta
función activa al MAX7219, define la intensidad de brillo del display y llama a la
función newGame para comenzar una partida.
10
Solución
11
3 Desarrollo
En la presente sección se procederá a indicar los distintos elementos físicos utilizados
y a explicar el esquema de conexión, como para que puedan fácilmente reproducirse
los resultados del proyecto.
Los primeros pasos a seguir son conseguir los elementos necesarios y realizar el
esquemade conexión para la implementación del proyecto, como se muestra en la
Figura 1.[ CITATION sch16 \l 13322 ]
12
Solución
ARDUINO UNO.
Matriz LED 8x8.
C.I. MAX7219.
Potenciómetro de 10[kΩ].
PiezoBuzzer.
Protoboard.
Cambles de conexión.
Para esta aplicación se puede eliminar el PiezoBuzzer, puesto que no hace nada, pero
puede ocuparse para añadir algunos sonidos queinmerjan al jugador
13
4 Resultados
14
Discusión y conclusiones
Las conclusiones finales del trabajo no se consideran como capítulos del texto, sin
embargo ellas son obligatorias para la estructura general del informe de proyecto e
independientes de aquellas que puedan existir en cada capítulo.
15
Solución
Bibliografía
[4 A. Passoti, «Arduino Pong with 8x8 LED matrix and MAX7219,» itOPEN, 09 Marzo
] 2012. [En línea]. Available: https://www.itopen.it/.
16
Solución
1 /**
2 * Jugar pong en una matriz 8x8
3 *
4 * 0 1 2 3 4 5 6 7
5 * 0
6 * 1
7 * 2 7 0 1
8 * 3 6 X 2 (direcciones)
9 * 4 5 4 3
10 * 5
11 * 6
12 * 7 [pad]
13 *
14 *
15 *
16 *
17 */
18
19
20 #include"LedControl.h"
21 #include"Timer.h"
22
23
24 #define POTPIN A5 // Potenciometro
25 #define PADSIZE 3
26 #define BALL_DELAY 200
27 #define GAME_DELAY 10
28 #define BOUNCE_VERTICAL 1
29 #define BOUNCE_HORIZONTAL -1
30 #define NEW_GAME_ANIMATION_SPEED 50
31 #define HIT_NONE 0
32 #define HIT_CENTER 1
33 #define HIT_LEFT 2
34 #define HIT_RIGHT 3
35
36
37 //#define DEBUG 1
38
39 byte sad[]={
17
Solución
40 B00000000,
41 B01000100,
42 B00010000,
43 B00010000,
44 B00000000,
45 B00111000,
46 B01000100,
47 B00000000
48 };
49
50 byte smile[]={
51 B00000000,
52 B01000100,
53 B00010000,
54 B00010000,
55 B00010000,
56 B01000100,
57 B00111000,
58 B00000000
59 };
60
61
62 Timer timer;
63
64 LedControl lc =LedControl(4,3,2,1);
65
66 byte direction;// Rosa de los vientos, 0 es el norte
67 int xball;
68 int yball;
69 int yball_prev;
70 byte xpad;
71 int ball_timer;
72
73 void setSprite(byte*sprite){
74 for(int r =0; r <8; r++){
75 lc.setRow(0, r, sprite[r]);
76 }
77 }
78
79 void newGame(){
80 lc.clearDisplay(0);
81 // posición inicial
82 xball = random(1,7);
83 yball =1;
84 direction = random(3,6);// Movimiento al sur
85 for(int r =0; r <8; r++){
86 for(int c =0; c <8; c++){
87 lc.setLed(0, r, c, HIGH);
88 delay(NEW_GAME_ANIMATION_SPEED);
89 }
90 }
91 setSprite(smile);
92 delay(1500);
93 lc.clearDisplay(0);
94 }
95
96 void setPad(){
97 xpad = map(analogRead(POTPIN),0,1020,8- PADSIZE,0);
98 }
99
100 void debug(constchar* desc){
101 #ifdef DEBUG
102 Serial.print(desc);
103 Serial.print(" XY: ");
104 Serial.print(xball);
18
Solución
19
Solución
170 }
171
172 // Verificar golpe: direccion modificada es izquierda o derecha
173 switch(getHit()){
174 case HIT_LEFT:
175 if(direction ==0){
176 direction =7;
177 }elseif(direction ==1){
178 direction =0;
179 }
180 break;
181 case HIT_RIGHT:
182 if(direction ==0){
183 direction =1;
184 }elseif(direction ==7){
185 direction =0;
186 }
187 break;
188 }
189
190 // Verificar direcciones ortogonales y bordes
191 if((direction ==0&& xball ==0)||(direction ==4&& xball ==7)){
192 direction++;
193 }
194 if(direction ==0&& xball ==7){
195 direction =7;
196 }
197 if(direction ==4&& xball ==0){
198 direction =3;
199 }
200 if(direction ==2&& yball ==0){
201 direction =3;
202 }
203 if(direction ==2&& yball ==6){
204 direction =1;
205 }
206 if(direction ==6&& yball ==0){
207 direction =5;
208 }
209 if(direction ==6&& yball ==6){
210 direction =7;
211 }
212
213 // Caso de las esquinas
214 if(xball ==0&& yball ==0){
215 direction =3;
216 }
217 if(xball ==0&& yball ==6){
218 direction =1;
219 }
220 if(xball ==7&& yball ==6){
221 direction =7;
222 }
223 if(xball ==7&& yball ==0){
224 direction =5;
225 }
226
227 yball_prev = yball;
228 if(2< direction && direction <6){
229 yball++;
230 }elseif(direction !=6&& direction !=2){
231 yball--;
232 }
233 if(0< direction && direction <4){
234 xball++;
20
Solución
21