Así de simple, sin circuitos añadidos.
Este es el código para el cubo en PAL:
Increíble lo que puede llegar a hacer una placa Arduino... el chip Atmega tiene capacidad para mostrar un videojuego tipo tetris en pantalla a través de una conexión V-Out normal (de la que traen televisores y marcos TFT), gracias a la librería Video Game Shield.
¿No os parece simplemente genial? La sencillez al poder... |
Las conexiones de sincronización y señal al Arduino |
En este vídeo se explica con detalle:
Este es el código para el cubo en PAL:
#include <TVout.h> #include <fontALL.h> #include "schematic.h" #include "TVOlogo.h" TVout TV; int zOff = 150; int xOff = 0; int yOff = 0; int cSize = 50; int view_plane = 64; float angle = PI/60; float cube3d[8][3] = { {xOff - cSize,yOff + cSize,zOff - cSize}, {xOff + cSize,yOff + cSize,zOff - cSize}, {xOff - cSize,yOff - cSize,zOff - cSize}, {xOff + cSize,yOff - cSize,zOff - cSize}, {xOff - cSize,yOff + cSize,zOff + cSize}, {xOff + cSize,yOff + cSize,zOff + cSize}, {xOff - cSize,yOff - cSize,zOff + cSize}, {xOff + cSize,yOff - cSize,zOff + cSize} }; unsigned char cube2d[8][2]; void setup() { TV.begin(PAL,120,96); TV.select_font(font6x8); intro(); TV.println("I am the TVout\nlibrary running on a freeduino\n"); TV.delay(2500); TV.println("I generate a PAL\nor NTSC composite video using\ninterrupts\n"); TV.delay(2500); TV.println("My schematic:"); TV.delay(1500); TV.bitmap(0,0,schematic); TV.delay(10000); TV.clear_screen(); TV.println("Lets see what\nwhat I can do"); TV.delay(2000); //fonts TV.clear_screen(); TV.println(0,0,"Multiple fonts:"); TV.select_font(font4x6); TV.println("4x6 font FONT"); TV.select_font(font6x8); TV.println("6x8 font FONT"); TV.select_font(font8x8); TV.println("8x8 font FONT"); TV.select_font(font6x8); TV.delay(2000); TV.clear_screen(); TV.print(9,44,"Draw Basic Shapes"); TV.delay(2000); //circles TV.clear_screen(); TV.draw_circle(TV.hres()/2,TV.vres()/2,TV.vres()/3,WHITE); TV.delay(500); TV.draw_circle(TV.hres()/2,TV.vres()/2,TV.vres()/2,WHITE,INVERT); TV.delay(2000); //rectangles and lines TV.clear_screen(); TV.draw_rect(20,20,80,56,WHITE); TV.delay(500); TV.draw_rect(10,10,100,76,WHITE,INVERT); TV.delay(500); TV.draw_line(60,20,60,76,INVERT); TV.draw_line(20,48,100,48,INVERT); TV.delay(500); TV.draw_line(10,10,110,86,INVERT); TV.draw_line(10,86,110,10,INVERT); TV.delay(2000); //random cube forever. TV.clear_screen(); TV.print(16,40,"Random Cube"); TV.print(28,48,"Rotation"); TV.delay(2000); randomSeed(analogRead(0)); } void loop() { int rsteps = random(10,60); switch(random(6)) { case 0: for (int i = 0; i < rsteps; i++) { zrotate(angle); printcube(); } break; case 1: for (int i = 0; i < rsteps; i++) { zrotate(2*PI - angle); printcube(); } break; case 2: for (int i = 0; i < rsteps; i++) { xrotate(angle); printcube(); } break; case 3: for (int i = 0; i < rsteps; i++) { xrotate(2*PI - angle); printcube(); } break; case 4: for (int i = 0; i < rsteps; i++) { yrotate(angle); printcube(); } break; case 5: for (int i = 0; i < rsteps; i++) { yrotate(2*PI - angle); printcube(); } break; } } void intro() { unsigned char w,l,wb; int index; w = pgm_read_byte(TVOlogo); l = pgm_read_byte(TVOlogo+1); if (w&7) wb = w/8 + 1; else wb = w/8; index = wb*(l-1) + 2; for ( unsigned char i = 1; i < l; i++ ) { TV.bitmap((TV.hres() - w)/2,0,TVOlogo,index,w,i); index-= wb; TV.delay(50); } for (unsigned char i = 0; i < (TV.vres() - l)/2; i++) { TV.bitmap((TV.hres() - w)/2,i,TVOlogo); TV.delay(50); } TV.delay(3000); TV.clear_screen(); } void printcube() { //calculate 2d points for(byte i = 0; i < 8; i++) { cube2d[i][0] = (unsigned char)((cube3d[i][0] * view_plane / cube3d[i][2]) + (TV.hres()/2)); cube2d[i][1] = (unsigned char)((cube3d[i][1] * view_plane / cube3d[i][2]) + (TV.vres()/2)); } TV.delay_frame(1); TV.clear_screen(); draw_cube(); } void zrotate(float q) { float tx,ty,temp; for(byte i = 0; i < 8; i++) { tx = cube3d[i][0] - xOff; ty = cube3d[i][1] - yOff; temp = tx * cos(q) - ty * sin(q); ty = tx * sin(q) + ty * cos(q); tx = temp; cube3d[i][0] = tx + xOff; cube3d[i][1] = ty + yOff; } } void yrotate(float q) { float tx,tz,temp; for(byte i = 0; i < 8; i++) { tx = cube3d[i][0] - xOff; tz = cube3d[i][2] - zOff; temp = tz * cos(q) - tx * sin(q); tx = tz * sin(q) + tx * cos(q); tz = temp; cube3d[i][0] = tx + xOff; cube3d[i][2] = tz + zOff; } } void xrotate(float q) { float ty,tz,temp; for(byte i = 0; i < 8; i++) { ty = cube3d[i][1] - yOff; tz = cube3d[i][2] - zOff; temp = ty * cos(q) - tz * sin(q); tz = ty * sin(q) + tz * cos(q); ty = temp; cube3d[i][1] = ty + yOff; cube3d[i][2] = tz + zOff; } } void draw_cube() { TV.draw_line(cube2d[0][0],cube2d[0][1],cube2d[1][0],cube2d[1][1],WHITE); TV.draw_line(cube2d[0][0],cube2d[0][1],cube2d[2][0],cube2d[2][1],WHITE); TV.draw_line(cube2d[0][0],cube2d[0][1],cube2d[4][0],cube2d[4][1],WHITE); TV.draw_line(cube2d[1][0],cube2d[1][1],cube2d[5][0],cube2d[5][1],WHITE); TV.draw_line(cube2d[1][0],cube2d[1][1],cube2d[3][0],cube2d[3][1],WHITE); TV.draw_line(cube2d[2][0],cube2d[2][1],cube2d[6][0],cube2d[6][1],WHITE); TV.draw_line(cube2d[2][0],cube2d[2][1],cube2d[3][0],cube2d[3][1],WHITE); TV.draw_line(cube2d[4][0],cube2d[4][1],cube2d[6][0],cube2d[6][1],WHITE); TV.draw_line(cube2d[4][0],cube2d[4][1],cube2d[5][0],cube2d[5][1],WHITE); TV.draw_line(cube2d[7][0],cube2d[7][1],cube2d[6][0],cube2d[6][1],WHITE); TV.draw_line(cube2d[7][0],cube2d[7][1],cube2d[3][0],cube2d[3][1],WHITE); TV.draw_line(cube2d[7][0],cube2d[7][1],cube2d[5][0],cube2d[5][1],WHITE); } |
Increíble lo que puede llegar a hacer una placa Arduino... el chip Atmega tiene capacidad para mostrar un videojuego tipo tetris en pantalla a través de una conexión V-Out normal (de la que traen televisores y marcos TFT), gracias a la librería Video Game Shield.
En formato PAL (para el cual trae ejemplos también) tiene una resolución suficiente de 120x96 pixels; teniendo en cuenta que tiene que hacer la conversión de la señal por software en tiempo real y además dejar tiempo para hacer cálculos para nuestro programa, es bastante impresionante.
Puede que el único problema para utilizar este método para mostrar información en pantalla sea ese; lo limitado que nos quede el Atmel para hacer otros cálculos en nuestro proyecto, o el consumo de memoria; aunque siempre se puede poner otro arduino conectado en serie para que se repartan el trabajo XDD.
Fuentes:
Esto ya me ha dejado anonadado, compañero...
ResponderEliminarReconstituyo todo mi proyecto en lo que ha salida de datos se refiere. Sencillamente genial...
jejeje... me acordé de ti cuando vi la gráfica en la página de Video Game Shield, compañero de aventuras XD.
ResponderEliminarSí que es cañero, sólo utiliza 2 salidas digitales, pero al fin y al cabo, el vídeo es digital. Que tenga potencia para hacerlo con esta resolución es lo que me deja a mí :O.
Hola:
EliminarHe intentado usar la librería y me da error.En estas líneas:
TV.begin(PAL,120,96);
TV.select_font(font6x8);
en la primera cambio PAL por 1,pero en la siguiente compilación me da error en la siguiente.¿Habeistenido el mismo problema?