This project was school project with special shield with LED matrix. So sorry but comments are in my language because I think this program is unusable for others when they haven't this special shield. But functions are simple for understanding ;-).
main.cpp
- Committer:
- lamaking
- Date:
- 2015-01-17
- Revision:
- 0:a837349b0219
File content as of revision 0:a837349b0219:
#include "mbed.h" #include "MMA8451Q.h" //kniznica akcelerometra #define MMA8451_I2C_ADDRESS (0x1d<<1) //definicia pre akcelerometer Ticker disptick; //definovanie casoveho prerusenia pre volanie funkcie vysvietenia AnalogIn randAdc(A3); // definovanie pinov pre zelenu farbu DigitalOut gr0(PTC7); DigitalOut gr1(PTC6); DigitalOut gr2(PTC5); DigitalOut gr3(PTC4); DigitalOut gr4(PTC3); DigitalOut gr5(PTC2); DigitalOut gr6(PTC1); DigitalOut gr7(PTC0); //definovanie pinov pre cervenu farbu DigitalOut rd0(PTC17); DigitalOut rd1(PTC16); DigitalOut rd2(PTC13); DigitalOut rd3(PTC12); DigitalOut rd4(PTC11); DigitalOut rd5(PTC10); DigitalOut rd6(PTC9); DigitalOut rd7(PTC8); //definovanie pinov pre adresaciu riadkov DigitalOut ln0(PTB0); DigitalOut ln1(PTB1); DigitalOut ln2(PTB2); // prototypy funkcii short RandSegment(void); //funkcia nahodne vybera novy segment pomocou citania A/D vstupu void SegmentInit(void); //prida jednotlivym segmentom informacie o ich vlastnostiach - pocet riadkov, stlpcov, rotovany segment, priradi pole s vlastnostou farby void SegmentCopy(struct segments *psgm, int segmentIn[2][4]); //v SegmentInit skopiruje vytvorene pole segmentu do pola v strukture (struct segments) void MoveDown(int array[8][16], int line); //posun pola smerom dole po odstranení zaplneneho riadku void LineCheck(void); //funkcia kontroluje zaplneny riadok void SegmentMove(struct segments *psgm); //funkcia sa stara o pohyby segmentu void WriteClrSeg(int wrtEnab, struct segments *psgm); //zmazanie alebo zapis segmentu pri pohybe maticou int DecLvl(void); //obsluha akcelerometra (preco prave Dec som zabudol) void LineAdd(int line); //adresacia riadkov void Display(void); //rozsvecovanie farieb v riadkoch podla hlavnej matice void OutPortInit(void); //nastavenie portov do pociatocneho stavu - vypnutie/zhasnutie //_____________________________________________________ int collision = 0; //globalna premenna zaznamenania kolizie pricom dany segment ostane ulozeny na danom mieste a vyberie sa novy short choice = 0; //globálna premenna vybranej struktury segmentu (pr. seg[choice]) //nasledujuce segmenty si nesu o sebe vlastnost farby(nulovy a parny stlpec v 1 - svieti zelena, neparny - cervena, obe - oranzova), neskor su priradene do struktury a su pridane dalsie vlastnosti //____________________________________________________kocka int segment0[2][4] = {{1,1, 1,1}, //oranzova {1,1, 1,1},}; int segment1[2][4] = {{1,0, 1,0}, //zelena {1,0, 1,0},}; int segment2[2][4] = {{0,1, 0,1}, //cervena {0,1, 0,1},}; //_____________________________________________________bodka int segment3[2][4] = {{1,1, 0,0}, //oranzova {0,0, 0,0},}; int segment4[2][4] = {{1,0, 0,0}, //zelena {0,0, 0,0},}; int segment5[2][4] = {{0,1, 0,0}, //cervena {0,0, 0,0},}; //____________________________________________________I int segment6[2][4] = {{1,1, 1,1}, //oranzova {0,0, 0,0},}; int segment61[2][4] = {{1,1, 0,0}, //oranzova rot1 {1,1, 0,0},}; int segment7[2][4] = {{1,0, 1,0}, //zelena {0,0, 0,0},}; int segment71[2][4] = {{1,0, 0,0}, //zelena rot1 {1,0, 0,0},}; int segment8[2][4] = {{0,1, 0,1}, //cervena {0,0, 0,0},}; int segment81[2][4] = {{0,1, 0,0}, //cervena rot1 {0,1, 0,0},}; //______________________________________________________L int segment9[2][4] = {{1,1, 1,1}, //oranzova {1,1, 0,0},}; int segment91[2][4] = {{1,1, 1,1}, //oranzova rot1 {0,0, 1,1},}; int segment92[2][4] = {{0,0, 1,1}, //oranzova rot2 {1,1, 1,1},}; int segment93[2][4] = {{1,1, 0,0}, //oranzova rot3 {1,1, 1,1},}; int segment10[2][4] = {{1,0, 1,0}, //zelena {1,0, 0,0},}; int segment101[2][4] = {{1,0, 1,0}, //zelena rot1 {0,0, 1,0},}; int segment102[2][4] = {{0,0, 1,0}, //zelena rot2 {1,0, 1,0},}; int segment103[2][4] = {{1,0, 0,0}, //zelena rot3 {1,0, 1,0},}; int segment11[2][4] = {{0,1, 0,1}, //cervena {0,1, 0,0},}; int segment111[2][4] = {{0,1, 0,1}, //cervena rot1 {0,0, 0,1},}; int segment112[2][4] = {{0,0, 0,1}, //cervena rot2 {0,1, 0,1},}; int segment113[2][4] = {{0,1, 0,0}, //cervena rot3 {0,1, 0,1},}; //________________________________________________________________ struct segments { //struktura segmentov char line; //pocet riadkov char colum; //pocet stlpcov char nextRot; //cislo noveho rotovaneho segmentu int segmentx[2][4]; //pole pre segmnet }seg[30]; //_________________________________________________________________ // | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | int dispArray[8][16] = { //pracovne pole, v ktorom sa vsetko odohrava, nulovy a parny stlpec v 1 - svieti zelena, neparny - cervena, obe - oranzova {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, //1 {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, //2 {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, //3 {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, //4 {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, //5 {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, //6 {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, //7 {0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}, };//8 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /*+++ MAIN +++*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int main() { SegmentInit(); //nahranie informacii do struktur segmentov (struct segments) OutPortInit(); //porty vypnute - zhasnuta matica disptick.attach(&Display, 0.002); //nastavenie prerusenia pre vysvecovanie displeja while(1) { choice = RandSegment(); //nahodny vyber segmentu while(collision != 1){ //pokial nenastane kolizia spodnej hrany segmentu SegmentMove(&seg[choice]); //pohybuj segmentov - v pravo, v lavo, dole, rotacia } LineCheck(); //skontroluje riadoky ci nie su zaplnene ak hej posunie sa vrchna cast dole collision = 0; } } /*--------------------------------------------------------*/ /*--- MAIN ---*/ /*--------------------------------------------------------*/ /*___________________________________________________________________________________________*/ /*++++++++++++++++++++++RandSegment+++++++++++++++++++++++*/ //funkcia nahodne vybera novy segment pomocou citania A/D vstupu short RandSegment(void){ static short num = 0; num = randAdc.read_u16()%12; //precitanie A/D s %12 - zvysok od 0 do 11 <-> zakladne segmenty od 0 do 11 return(num); } /*---------------------RandSegment-----------------------*/ /*++++++++++++++++++++++SegmentInit+++++++++++++++++++++++*/ //prida jednotlivym segmentom informacie o ich vlastnostiach - pocet riadkov, stlpcov, rotovany segment, priradi pole s vlastnostou farby void SegmentInit(void){ seg[0].line = 2; seg[0].colum = 4; seg[0].nextRot = 0; SegmentCopy(&seg[0], segment0); //oranzova kocka 2x2 seg[1].line = 2; seg[1].colum = 4; seg[1].nextRot = 1; SegmentCopy(&seg[1], segment1); //zelena kocka 2x2 seg[2].line = 2; seg[2].colum = 4; seg[2].nextRot = 2; SegmentCopy(&seg[2], segment2); //cervena kocka 2x2 //_________________________________________________________________ seg[3].line = 1; seg[3].colum = 2; seg[3].nextRot = 3; SegmentCopy(&seg[3], segment3); //oranzova bodka seg[4].line = 1; seg[4].colum = 2; seg[4].nextRot = 4; SegmentCopy(&seg[4], segment4); //zelena bodka seg[5].line = 1; seg[5].colum = 2; seg[5].nextRot = 5; SegmentCopy(&seg[5], segment5); //cervena bodka //__________________________________________________________________ seg[6].line = 1; seg[6].colum = 4; seg[6].nextRot = 12; SegmentCopy(&seg[6], segment6); //oranzova ciara seg[12].line = 2; seg[12].colum = 2; seg[12].nextRot = 6; SegmentCopy(&seg[12], segment61); //oranzova ciara rot seg[7].line = 1; seg[7].colum = 4; seg[7].nextRot = 13; SegmentCopy(&seg[7], segment7); //zelena ciara seg[13].line = 2; seg[13].colum = 2; seg[13].nextRot = 7; SegmentCopy(&seg[13], segment71); //zelena ciara rot seg[8].line = 1; seg[8].colum = 4; seg[8].nextRot = 14; SegmentCopy(&seg[8], segment8); //cervena ciara seg[14].line = 2; seg[14].colum = 2; seg[14].nextRot = 8; SegmentCopy(&seg[14], segment81); //cervena ciara rot //__________________________________________________________________ seg[9].line = 2; seg[9].colum = 4; seg[9].nextRot = 15; SegmentCopy(&seg[9], segment9); //oranzova L seg[15].line = 2; seg[15].colum = 4; seg[15].nextRot = 16; SegmentCopy(&seg[15], segment91); //oranzova L rot1 seg[16].line = 2; seg[16].colum = 4; seg[16].nextRot = 17; SegmentCopy(&seg[16], segment92); //oranzova L rot2 seg[17].line = 2; seg[17].colum = 4; seg[17].nextRot = 9; SegmentCopy(&seg[17], segment93); //oranzova L rot3 seg[10].line = 2; seg[10].colum = 4; seg[10].nextRot = 18; SegmentCopy(&seg[10], segment10); //zelena L seg[18].line = 2; seg[18].colum = 4; seg[18].nextRot = 19; SegmentCopy(&seg[18], segment101); //zelena L rot1 seg[19].line = 2; seg[19].colum = 4; seg[19].nextRot = 20; SegmentCopy(&seg[19], segment102); //zelena L rot2 seg[20].line = 2; seg[20].colum = 4; seg[20].nextRot = 10; SegmentCopy(&seg[20], segment103); //zelena L rot3 seg[11].line = 2; seg[11].colum = 4; seg[11].nextRot = 21; SegmentCopy(&seg[11], segment11); //cervena L seg[21].line = 2; seg[21].colum = 4; seg[21].nextRot = 22; SegmentCopy(&seg[21], segment111); //cervena L rot1 seg[22].line = 2; seg[22].colum = 4; seg[22].nextRot = 23; SegmentCopy(&seg[22], segment112); //cervena L rot2 seg[23].line = 2; seg[23].colum = 4; seg[23].nextRot = 11; SegmentCopy(&seg[23], segment113); //cervena L rot3 } /*----------------------SegmentInit-----------------------*/ /*++++++++++++++++++++++SegmentCopy+++++++++++++++++++++++*/ //v SegmentInit skopiruje vytvorene pole segmentu do pola v strukture (struct segments) void SegmentCopy(struct segments *psgm, int segmentIn[2][4]){ static int i,j; for(i = 0 ; i < (psgm->line); i++){ //riadok for(j = 0 ; j < (psgm->colum); j++ ){ //slpec psgm->segmentx[i][j] = segmentIn[i][j]; } } } /*--------------------SegmentCopy------------------------*/ /*++++++++++++++++++++++LineCheck+++++++++++++++++++++++*/ //funkcia kontroluje zaplneny riadok void LineCheck(void){ static int ch=0; static int lnCh, colCh; for(lnCh = 0; lnCh < 8; lnCh++){ ch = 0; for(colCh=0; colCh < 15; colCh+=2){ if((dispArray[lnCh][colCh]==1) || (dispArray[lnCh][colCh+1]==1)){ //ak je bod vysvieteny ch++;} //pripocita k premennej else { colCh = 15; //ak bod v riadku nie je vysvieteny nema cenu ho cely kontrolovat a skoci sa tak na dalsi riadok ch = 0; } } if((ch == 8)){ //ak je cely riadok vysvieteny for(colCh=0; colCh < 16; colCh++){ //nuluj riadok dispArray[lnCh][colCh] = 0; } MoveDown(dispArray, lnCh); //posunie zvysok pola dole a kontroluje sa zvysok a teda proces sa opakuje kym sa neskontroluje cele pole } } } /*-------------------------LineCheck----------------------------*/ /*++++++++++++++++++++++++MoveDown++++++++++++++++++++++++++++++*/ //posun pola smerom dole po odstranení zaplneneho riadku void MoveDown(int dispArray[8][16], int line){ static int ln, col; for(ln = line; ln>=0; ln--){ for(col=0; col < 16; col++){ if(ln>=1){ dispArray[ln][col] = dispArray[ln-1][col]; } if(ln<1){ dispArray[ln][col] = 0; } } } } /*-----------------------MoveDown-------------------------------*/ /*+++++++++++++++++++++SegmentMove++++++++++++++++++++++++*/ //funkcia sa stara o pohyby segmentu static int x=6, y=0; //suradnice segmentu pricom hodnotu na suradnici x,y je vzdy lavy horny roh segmentu void SegmentMove(struct segments *psgm){ static long int counter=0; //vytvara zdrzanie pri pohybe static int col, ln, dm; //col, ln - premenne v cykloch pri kontrole kolizii, dm detekcia kolizie, zakaze pohyb danym smerom if( ((x == 6) && (y == 0)) && counter == 0){ //kontrola pri novom segmente ci nedojde ku kolizii for(ln = 0; ln < psgm->line; ln++){ //skontroluje ci v priestore nedojde ku kolizii for(col=0; col < psgm->colum; col+=2){ if((dispArray[y+ln][x+col] | dispArray[y+ln][x+col+1]) & (psgm->segmentx[ln][col] | psgm->segmentx[ln][col+1]) == 1){ //zistuje ci nie je v danom bode kolizia so segmentom ln = psgm->line; //ak je kolizia nema cenu kontrolovat zvysok col = psgm->colum; // static int lnclr, colclr; //vynulovanie celeho pola for(lnclr = 0; lnclr < 8; lnclr++){ // for(colclr=0; colclr < 16; colclr++){ // dispArray[lnclr][colclr] = 0; // } } } } } } WriteClrSeg(1, &seg[choice]); //zapise segment do pola counter++; //counter zacina pocitat if((counter%4000 == 0)){ //ak je counter nasobkom 4000 je umozneny pohyb pomocou akcelerometra if(DecLvl()==3) { //podmienka pre pohyb v pravo WriteClrSeg(0, &seg[choice]); //zmaze segment z pola, inak by za sebou nechaval zapisane hodnoty for(ln = 0; ln < psgm->line; ln++){ //skontroluje ci v priestore pohybu nedojde ku kolizii for(col=0; col < psgm->colum; col+=2){ if((dispArray[y+ln][x+col+2] | dispArray[y+ln][x+col+1+2]) & (psgm->segmentx[ln][col] | psgm->segmentx[ln][col+1]) == 1){ ln = psgm->line; col = psgm->colum; dm = 1; //doslo ku kolizii } } } if (dm == 0){ //nedoslo ku kolizii, segment sa moze pohnut x+=2; if (x>16-(psgm->colum)){ x=16-(psgm->colum); } } dm = 0; //po kolizii sa premenna vynuluje WriteClrSeg(1, &seg[choice]); //opatovne zapisanie segmentu do pola } if((DecLvl()==4) ){ //opodmienka pre pohohyb v lavo - analogia s pohybom v pravo WriteClrSeg(0, &seg[choice]); for(ln = 0; ln < psgm->line; ln++){ //skontroluje ci v priestore pohybu nedojde ku kolizii for(col=0; col < psgm->colum; col+=2){ if((dispArray[y+ln][x+col-2] | dispArray[y+ln][x+col+1-2]) & (psgm->segmentx[ln][col] | psgm->segmentx[ln][col+1]) == 1){ ln = psgm->line; col = psgm->colum; dm = 1; } } } if (dm == 0){ x-=2; if (x<0){ x=0; } } dm = 0; WriteClrSeg(1, &seg[choice]); } if(DecLvl()==1){ //pohyb k sebe - segment pada zrychlene dole counter = 40001; } if(DecLvl()==2){ //pohyb od seba - rotacia segmentu WriteClrSeg(0, &seg[choice]); //zmaze segment z pola for(ln = 0; ln < seg[psgm->nextRot].line; ln++){ //skontroluje ci v priestore rotovaneho segmentu nedojde ku kolizii for(col=0; col < seg[psgm->nextRot].colum; col+=2){ if(((dispArray[y+ln][x+col] | dispArray[y+ln][x+col+1]) & (seg[psgm->nextRot].segmentx[ln][col] | seg[psgm->nextRot].segmentx[ln][col+1]) == 1) || ((seg[psgm->nextRot].line-1+y) > 7) || ((seg[psgm->nextRot].colum-1+x) > 15)){ ln = seg[psgm->nextRot].line; //parametre orotovaneho segmentu col = seg[psgm->nextRot].colum; // dm = 1; //premenna naznacujuca koliziu } } } if (dm == 0){ choice = psgm->nextRot; //nahradi segment za rotovany } dm = 0; WriteClrSeg(1, &seg[choice]); //zapise segment do pola } } if(counter >= 40001){ //zdrzanie WriteClrSeg(0, &seg[choice]); //zmaze segment z pola counter = 0; //vynuluje counter y++; //segment sa posunie dole ak splni podmnienku nizsie for(ln = 0; ln < psgm->line; ln++){ //skontroluje ci v priestore pohybu nedojde ku kolizii for(col=0; col < psgm->colum; col+=2){ if(((dispArray[y+ln][x+col] | dispArray[y+ln][x+col+1]) & (psgm->segmentx[ln][col] | psgm->segmentx[ln][col+1]) == 1) || ((y+psgm->line-1) > 7) ){ y--; //segment sa dostal mimo pola alebo sa dostal do kolizie, suradnica sa vracia ln = psgm->line; //aby sa nemusel kontrolovat pripadne zvysok col = psgm->colum; // dm = 1; collision = 1; //detekuje sa kolizia a vyberie sa novy segment } } } WriteClrSeg(1, &seg[choice]); if (dm == 1){ //po detekcii kolizie sa nastavia pociatocne suradnice y = 0; x = 6; dm = 0; } } } /*---------------------------SegmentMove---------------------------*/ /*+++++++++++++++++++++++++++WriteClrSeg+++++++++++++++++++++++++++*/ //zmazanie alebo zapis segmentu pri pohybe maticou void WriteClrSeg(int wrtEnab, struct segments *psgm){ //ak je wrtEnab 0 zmaze sa ak 1 zapise sa dany segment do pola, segment sa cita zo struktury vybranej randomom static int ln, col; for(ln = 0; ln < psgm->line; ln++){ for(col=0; col < psgm->colum; col++){ if(wrtEnab == 1){ dispArray[ln+y][col+x] |= psgm->segmentx[ln][col];} else{ dispArray[ln+y][col+x] = (psgm->segmentx[ln][col] == 1 ? 0:dispArray[ln+y][col+x] );} } } } /*-------------------------WriteClrSeg-----------------------------*/ /*++++++++++++++++++++++++++++++DecLvl+++++++++++++++++++++++++++++*/ //obsluha akcelerometra MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS); int DecLvl(void){ static float ax, ay; static float point = 0.34; //nastavenie uhla...cca 30° +- nieco ax = float(acc.getAccX()); //citanie hodnoty v x-ovej osi akcelerometra ay = float(acc.getAccY()); //citanie hodnoty v y-ovej osi akcelerometra if((ax > point)){ //k sebe return(1); } else if((ax < -point)){ //od seba return(2); } else if((ay > point)){ //naklon v pravo return(3); } else if((ay < -point)){ //naklon v lavo return(4); } return 0; } /*--------------------------------DecLvl-------------------------------*/ /*++++++++++++++++++++++++++++++Display+++++++++++++++++++++++++++++*/ //rozsvecovanie farieb v riadkoch podla hlavnej matice void Display(void){ static int line = 0; LineAdd(line); //adresacia riadku pomocou funkcie, gr0 = !dispArray[line][0]; //parny a nulovy stlpec znaci zelenu farbu (dany bod svieti po pripojeni na zem, ale zapis svietecej casti v poli je pomocou 1) gr1 = !dispArray[line][2]; gr2 = !dispArray[line][4]; gr3 = !dispArray[line][6]; gr4 = !dispArray[line][8]; gr5 = !dispArray[line][10]; gr6 = !dispArray[line][12]; gr7 = !dispArray[line][14]; rd0 = !dispArray[line][1]; //neparny riadok znaci cervenu farbu rd1 = !dispArray[line][3]; rd2 = !dispArray[line][5]; rd3 = !dispArray[line][7]; rd4 = !dispArray[line][9]; rd5 = !dispArray[line][11]; rd6 = !dispArray[line][13]; rd7 = !dispArray[line][15]; //ak su vysvietene obe, svieti oranzova wait(0.001); line++; //nasledujuci riadok if(line == 8){ line = 0; } } /*--------------------------------Display-------------------------------*/ /*++++++++++++++++++++++++++++++++LineAdd++++++++++++++++++++++++++++++++++*/ //adresacia riadkov void LineAdd(int line){ switch(line){ case 0: ln0 = 0; ln1 = 0; ln2 = 0; break; case 1: ln0 = 1; ln1 = 0; ln2 = 0; break; case 2: ln0 = 0; ln1 = 1; ln2 = 0; break; case 3: ln0 = 1; ln1 = 1; ln2 = 0; break; case 4: ln0 = 0; ln1 = 0; ln2 = 1; break; case 5: ln0 = 1; ln1 = 0; ln2 = 1; break; case 6: ln0 = 0; ln1 = 1; ln2 = 1; break; case 7: ln0 = 1; ln1 = 1; ln2 = 1; break; default: break; } } /*-----------------------LineAdd------------------------*/ /*+++++++++++++++++++++++OutPortInit++++++++++++++++++++*/ //nastavenie portov do pociatocneho stavu - vypnutie/zhasnutie void OutPortInit(void){ rd0 = 1; rd1 = 1; rd2 = 1; rd3 = 1; rd4 = 1; rd5 = 1; rd6 = 1; rd7 = 1; gr0 = 1; gr1 = 1; gr2 = 1; gr3 = 1; gr4 = 1; gr5 = 1; gr6 = 1; gr7 = 1; } /*---------------------OutPortInit--------------------*/