Proiectul consta in realizarea unui cub format din 125 leduri ( latura formata din 5 leduri )care va avea 2 functionalitati :
1. Redarea unor animatii 2. Va reprezenta "terenul" pentru un joc de tip Snake3D.
Hardware :
Software :
Cost aproximativ : 200 lei
Pentru programarea microcontrolerului programele vor fi scrise în limbajul C folosind WinAvr.
Pentru cubul de leduri am folosit o matrice cub[5][5] care reprezenta coloanele cubului si un vector lay[5] ce reprezinta nivelele in cub. Astfel daca lay[4]= 1 si cub[3][2]=1 se va aprinde ledul de pe cub din pozitia led[4][3][2].
int cub[5][5]; int lay[5]; #define LAYER1 0x84 #define LAYER2 0x88 #define LAYER3 0x90 #define LAYER4 0xa0 #define LAYER5 0xc0 #define LAYER_PORT PORTD // Folosim Portul D pentru nivele
Functie care selecteaza un layer:
void select_layer(){ LAYER_PORT =0x00; int k,c=0; for(k=0;k<5;k++) if(lay[k]==1) c++; if(c%2 ==1){ if(lay[0]==1) LAYER_PORT ^= ~LAYER1; if(lay[1]==1) LAYER_PORT ^= ~LAYER2; if(lay[2]==1) LAYER_PORT ^= ~LAYER3; if(lay[3]==1) LAYER_PORT ^= ~LAYER4; if(lay[4]==1) LAYER_PORT ^= ~LAYER5; } else { if(lay[0]==1) LAYER_PORT ^= ~LAYER1; if(lay[1]==1) LAYER_PORT ^= ~LAYER2; if(lay[2]==1) LAYER_PORT ^= ~LAYER3; if(lay[3]==1) LAYER_PORT ^= ~LAYER4; if(lay[4]==1) LAYER_PORT ^= ~LAYER5; LAYER_PORT= ~LAYER_PORT; LAYER_PORT ^=(1<<PD7); } }
Pentru selectia unei coloane am folosit urmatoarea functie:
void set_col(){ PORTC = 0x00; PORTA = 0x00; PORTB = 0x00; select_layer(); int x , y; for(x=1;x<6;x++) for(y=1;y<6;y++){ int k=(x-1)*5+y; if((k<9)&&(k>=1)) if(cub[x-1][y-1]==1) PORTC = PORTC ^ (1<<(k-1)); if(k==9) if(cub[x-1][y-1]==1) PORTB = PORTB ^ (1 << 7); if(k==10) if(cub[x-1][y-1]==1) PORTB = PORTB ^ (1 << 6); if(k==11) if(cub[x-1][y-1]==1) PORTB = PORTB ^ (1 << 5); if(k==12) if(cub[x-1][y-1]==1) PORTD = PORTD ^ (1 << 7); if(13<=k&&k<21) if(cub[x-1][y-1]==1) PORTA = PORTA ^ (1<<(20-k)); if(21<=k&&k<26) if(cub[x-1][y-1]==1) PORTB = PORTB ^ (1<<(k-21)); } }
Astfel folosind aceste functii , matricea cub si vectorul lay putem aprinde ledurile dupa bunul plac.Folosirea matricei este necesara pentru a se putea aprinde mai multe nivele si coloane odata si stinge anumite leduri in functie de animatia folosita.
1.Efect de ploaie :
void ploaie(int time){ int e,g,h; g=rand()%5; h=rand()%5; for(e=5;e>0;e--){ lay[e]=1; cub[g][h]=1; set_col(); delay_real_ms(time); lay[e]=0; cub[g][h]=0; } }
2.Efect de explozie :
void eff1(time){ int e,g,h,m,r,p; e=2; g=3; h=3; for(m=0;m<3;m++){ lay[e-m]=1; lay[e+m]=1; for(r=g-m;r<g+m+1 ;r++) for(p=h-m;p<h+m+1 ;p++) cub[r-1][p-1]=1; set_col(); delay_real_ms(time); } for(m=2;m>=0;m--){ lay[e-m]=0; lay[e+m]=0; for(r=g-m;r<g+m+1;r++){ cub[r-1][h-m-1]=0; cub[r-1][h+m-1]=0; } for(p=h-m;p<h+m+1 ;p++) { cub[g-m-1][p-1]=0; cub[g+m-1][p-1]=0; } set_col(); delay_real_ms(time); } }
3.Efect de explozie 2:
void eff2(time){ int m,r,p; resetmat(); cub[0][0]=1; for(m=0;m<5;m++){ lay[m]=1; for(r=0;r<m+1 ;r++) for(p=0;p<m+1 ;p++) cub[r][p]=1; set_col(); delay_real_ms(time); } for(m=4;m>=0;m--){ lay[m]=0; for(r=m;r>=0;r--){ cub[r][m]=0; } for(p=m;p>=0 ;p--) { cub[m][p]=0; } set_col(); delay_real_ms(time); } }
4.Efect de translatare plan :
void eff3(time){ int m,r,p; resetmat(); for(m=0;m<5;m++) for(r=0;r<5 ;r++) cub[m][r]=1; for(m=0;m<5;m++){ lay[m]=1; set_col(); delay_real_ms(time); lay[m]=0; } resetmat(); for(m=0;m<5;m++) lay[m]=1; for(m=0;m<5;m++){ for(r=0;r<5 ;r++) cub[m][r]=1; set_col(); delay_real_ms(time); for(r=0;r<5 ;r++) cub[m][r]=0; } resetmat(); for(m=0;m<5;m++) lay[m]=1; for(m=3;m>=0;m--){ for(r=0;r<5 ;r++) cub[m][r]=1; set_col(); delay_real_ms(time); for(r=0;r<5 ;r++) cub[m][r]=0; } resetmat(); for(m=0;m<5;m++) for(r=0;r<5 ;r++) cub[m][r]=1; for(m=4;m>=0;m--){ lay[m]=1; set_col(); delay_real_ms(time); lay[m]=0; } }
5.Animatie care scrie PM :
void eff4(time){ int m,r,p; resetmat(); for(m=0;m<5;m++) { cub[0][m]=1; cub[m][0]=1; cub[m][2]=1; } cub[4][1]=1; for(m=0;m<5;m++) { lay[m]=1; set_col(); delay_real_ms(time); lay[m]=0; } delay_real_ms(2*time); resetmat(); for(m=0;m<5;m++) { cub[0][m]=1; cub[4][m]=1; } cub[3][1]=1; cub[2][2]=1; cub[1][1]=1; for(m=0;m<5;m++) { lay[m]=1; set_col(); delay_real_ms(time); lay[m]=0; } delay_real_ms(2*time); }
Cubul de led 5x5x5 functioneaza corespunzator prezinta 5 animatii independente conform planului. Placuta a doua care primea comenziile de la butoanele de control si le trimitea prin seriala la cealalta placuta s-a ars se pare cu 2 zile inainte de deadline.
Un sfat pentru cei care vor sa faca acest proiect :mare grija cand completati un traseu cu fir , desi initial masurati si nu face scurt cu nimic in anumite pozitii se poate atinge ceva si proiectul e compromis.
Pe de alta parte alegerea dimensiunii 5x5x5 a cubului a necesitat 30 de pini programabili si au mai ramas 2 pentru seriala . Programarea pe acest cub a necesitat mai multa munca decat pe unul de dimensiune 4 deoarece au fost necesare anumite mapari ale pinilor .
Dar in final a meritat efortul ! Pacat ca s-a ars cealalta placuta.