This was school project with LED matrix with special shield. Unfortunately, comments are in czech language but I think the program is quite easy to understand. It´s unusable without the shield, but the basis can be used esewhere.

Dependencies:   MMA8451Q mbed

main.cpp

Committer:
xtypov00
Date:
2017-01-13
Revision:
0:b4a961ac4a97

File content as of revision 0:b4a961ac4a97:

#include "mbed.h"
#include "MMA8451Q.h"   //knihovna akcelerometru

#define MMA8451_I2C_ADDRESS (0x1d<<1)   //definice pro akcelerometr
MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS); //obsluha akcelerometru

void AdresRadku(int line);              //adresování řádků
void Zobraz(void);                      //funkce zprostředkující zobrazení
void Inicializace(void);                //inicalizace počáteční polohy svodidel a auta hráče
void SvodidlaPohyb(void);               //samostatný pohyb svodidel
void AutaPohyb(void);                   //generování a pohyb aut počítače
void Pohyb(void);                       //ovládání pozice auta hráče pomocí akcelerometru
void Kolize(void);                      //detekce kolize auta hráče s auty počítače
void Reset(void);                       //restart hry

Ticker disptick;    //definice časovače pro volání funkce zobrazení
Ticker tick;        //definice časovače pro volání funkce pohybu svodidel - 1px/s
Ticker tick2;       //definice časovače pro volání funkce pohybu aut počítače - 1px/0.25s

int randVector[] = {0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1}; //vektor náhodných čísel
int pocitadlo = 0; //pomocná proměnná pro vyber z náhodného vektoru
int rowAuto = 0;
int pomAuto;
int pomAuto2;
int poloha = 4;
float ay;
float prah;
int kolize;

//definování pinů pro zelenou barvu
DigitalOut zelena0(PTC7);
DigitalOut zelena1(PTC6);
DigitalOut zelena2(PTC5);
DigitalOut zelena3(PTC4);
DigitalOut zelena4(PTC3);
DigitalOut zelena5(PTC2);
DigitalOut zelena6(PTC1);
DigitalOut zelena7(PTC0);
 
//definování pinů pro červenou barvu
DigitalOut cervena0(PTC17);
DigitalOut cervena1(PTC16);
DigitalOut cervena2(PTC13);
DigitalOut cervena3(PTC12);
DigitalOut cervena4(PTC11);
DigitalOut cervena5(PTC10);
DigitalOut cervena6(PTC9);
DigitalOut cervena7(PTC8);
 
//definování pinů pro adresování řádků
DigitalOut ln0(PTB0);
DigitalOut ln1(PTB1);
DigitalOut ln2(PTB2); //2^3 = 8...8 radku kodovany binar. hodnotama 
  
                 
// pracovní pole pro matici čerevných LED
                // |0||1||2||3||4||5||6||7|
int poleCerveny[8][8] = {                        
                   {0, 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},    //2
                   {0, 0, 0, 0, 0, 0, 0, 0},    //3
                   {0, 0, 0, 0, 0, 0, 0, 0},    //4
                   {0, 0, 0, 0, 0, 0, 0, 0},    //5
                   {0, 0, 0, 0, 0, 0, 0, 0},    //6
                   {0, 0, 0, 0, 0, 0, 0, 0},  };//7

// pracovní pole pro matici zelených LED                   
int poleZeleny[8][8] = {                                       
                   {0, 0, 0, 0, 0, 0, 0, 0},             
                   {0, 0, 0, 0, 0, 0, 0, 0},    
                   {0, 0, 0, 0, 0, 0, 0, 0},    
                   {0, 0, 0, 0, 0, 0, 0, 0},    
                   {0, 0, 0, 0, 0, 0, 0, 0},    
                   {0, 0, 0, 0, 0, 0, 0, 0},    
                   {0, 0, 0, 0, 0, 0, 0, 0},    
                   {0, 0, 0, 0, 0, 0, 0, 0},  };






/*----------------------------------------------------------------------------*/
//                               MAIN                                         //
/*----------------------------------------------------------------------------*/

int main() 
{  
    Inicializace();                         //inicalizace počáteční polohy oranžových svodidel a zeleného auta hráče
    disptick.attach(&Zobraz, 0.002);        //nastavení časovače pro rozsvicování displeye
    tick.attach(&SvodidlaPohyb, 1);         //nastavení časovače pro volání funkce zabezpečující pohyb svodidel
    tick2.attach(&AutaPohyb, 0.25);         //nastavení časovače pro volání funkce zabezpečující pohyb aut počítače
    while(1) 
    { 
        Pohyb();                                //ovládání pozice auta hráče pomocí akcelerometru
        Kolize();                               //detekce kolize auta hráče s auty počítače  
    }
}
/*----------------------------------------------------------------------------*/
//                                                                            //
/*----------------------------------------------------------------------------*/







/*---------------------------------Zobraz-------------------------------------*/

//rozsvicování matice na základě stavu pracovních polí v aktuálním kroku
void Zobraz(void)
{
        static int line = 0;    //proměná inicializující prnví řádek
                         
        AdresRadku(line);                   //adresování řádků pomocí funkce AdresRadku() 
        
        //Rozsvicování LEDek je zajištěno jejich uzeměním - tedy, když je na řídící vstup přivedena 0.
        //Z důvodu lepší oirentace při práci bylo využito negace, aby v následujícím algoritmu rozsvícení LEDek 
        //způsobovalo číslo 1.
                
        //rozsvicování zelených LED
        zelena0 =! poleZeleny[line][0];      
        zelena1 =! poleZeleny[line][1];
        zelena2 =! poleZeleny[line][2];
        zelena3 =! poleZeleny[line][3];
        zelena4 =! poleZeleny[line][4];
        zelena5 =! poleZeleny[line][5];
        zelena6 =! poleZeleny[line][6];
        zelena7 =! poleZeleny[line][7];  
        
        //rozsvícení červených LED
        cervena0 =! poleCerveny[line][0];      
        cervena1 =! poleCerveny[line][1];
        cervena2 =! poleCerveny[line][2];
        cervena3 =! poleCerveny[line][3];
        cervena4 =! poleCerveny[line][4];
        cervena5 =! poleCerveny[line][5];
        cervena6 =! poleCerveny[line][6];
        cervena7 =! poleCerveny[line][7];                               
        //v případě, že na stejné pozici svící obě LEDky, je barva oranžová                                
        
        wait(0.001);                //zpožděni-aby se to stihlo rozsvitit
        line++;                     //přepis proměnné na další řádek
        if(line == 8)               //v případě,že dojde na konec,jede se od zacatku
        {              
                line = 0;
        }
}

 
/*--------------------------------AdresRadku----------------------------------*/
//adresování řádků
void AdresRadku(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;
    }    
}


/*--------------------------------Inicializace--------------------------------*/
void Inicializace(void){
    int col;
    int row;
/*------------inicializace svodidel--------------*/    
    for(col=0;col < 8; col = col+7)
    {    
        for(row = 0; row < 8; row++)
        {  
            if(row == 0 ||row == 4)
            {      
                poleCerveny[row][col]=0; 
                poleZeleny[row][col]=0;
            }                                                      
            else
            {
               poleCerveny[row][col]=1;
               poleZeleny[row][col]=1;
            } 
        }
    } 
/*----inicializace auta hráče - pozice napravo---*/
        poleZeleny[4][4] = 1;
        poleZeleny[5][4] = 1;
        poleZeleny[6][4] = 1;
        poleZeleny[4][5] = 1;
        poleZeleny[5][5] = 1;
        poleZeleny[6][5] = 1;   
}


/*--------------------------------SvodidlaPohyb-------------------------------*/
void SvodidlaPohyb(void)
{
    int col;
    int row;
    int pom1; //pomocná proměnná    
    
    pom1 = poleCerveny[7][0]; //uloží hodnotu v poslendím 8. radku
    
    //posune svodidla o 1 pozici směrem dolu při každém zavolání funkce    
    for(col=0;col < 8; col = col+7)     //pracuje pouze v 1. a v posledním sloupci
    {
        for(row = 7; row > 0; row--)    //7. až 1. řádek přepíše na 8. až 2.
        {
          poleCerveny[row][col] = poleCerveny[row-1][col]; 
          poleZeleny[row][col] = poleZeleny[row-1][col];     
        }
    }   
    //poslední řádek přepíše jako 1. 
    poleCerveny[0][0] = pom1;
    poleCerveny[0][7] = pom1;
    poleZeleny[0][0] = pom1;
    poleZeleny[0][7] = pom1;
}


/*--------------------------------AutaPohyb-----------------------------------*/
void AutaPohyb(void)
{

    int col2; //sloupec, ve kterém se auto počítače nachází - mění se podle hodnot randVectoru
    
    
    //"pocitadlo" = pozice v randVectoru; začíná se od počáteční pozice 0
    //"rowAuto" - zajišťuje posun aut; počáteční hodnota je 0, ale 1. auto se objeví až po zavolání funkce
    
    if(randVector[pocitadlo] == 1)   //když bude aktuální hodnota randVectoru rovna 1, auto  počítače bude nalevo
    {
        col2 = 2; //levý (3.) sloupec
        poleCerveny[rowAuto][col2] = 1;
        poleCerveny[rowAuto][col2+1] = 1;        
    }
    else    //při hodnotě 0 bude auto počítače napravo
    {
        col2 = 4; //pravý (5.) sloupec
        poleCerveny[rowAuto][col2] = 1;
        poleCerveny[rowAuto][col2+1] = 1;
    } 
     rowAuto++; //zvýší hodnotu o 1, aby se v náseledující iteraci auto počítače objevilo na dalším čádku
 
 //----zhasínání LEDek, kterými prošlo auto počítače----//    
    if(rowAuto > 3)
    {          
        poleCerveny[rowAuto-4][col2] =! 1;
        poleCerveny[rowAuto-4][col2+1] =! 1;
    }
    else if(rowAuto > 4)
    {          
        poleCerveny[rowAuto-5][col2] =! 1;
        poleCerveny[rowAuto-5][col2+1] =! 1;
    }
    else if(rowAuto > 5)
    {          
        poleCerveny[rowAuto-6][col2] =! 1;
        poleCerveny[rowAuto-6][col2+1] =! 1;
    }
    else if(rowAuto > 6)
    {          
        poleCerveny[rowAuto-7][col2] =! 1;
        poleCerveny[rowAuto-7][col2+1] =! 1;
    }
    else if(rowAuto > 7)
    {          
        poleCerveny[rowAuto-8][col2] =! 1;
        poleCerveny[rowAuto-8][col2+1] =! 1;
    }
     
    else if(rowAuto == 1)
    {          
        poleCerveny[5][pomAuto] =! 1;
        poleCerveny[5][pomAuto+1] =! 1;
    }
        
    else if(rowAuto == 2)
    {         
        poleCerveny[6][pomAuto2] =! 1;
        poleCerveny[6][pomAuto2+1] =! 1;
    }
        
    else if(rowAuto == 3)
    {          
        poleCerveny[7][2] =! 1;
        poleCerveny[7][4] =! 1;
        poleCerveny[7][3] =! 1;
        poleCerveny[7][5] =! 1;
    }
        
//----opakovaní cyklu + další pohola auta počítače----//  
    if(rowAuto > 7) //jakmile řádky dojedou na konec, jede se od začátku  
    {         
        rowAuto = 0;
        pocitadlo++;  //zvýšení proměnné o 1, aby aktualizovala pozice nového auta počítače
    }

//pokud cyklus dojede na konec randVectoru, jede se opět od začátku
    int n = sizeof(randVector) / sizeof(randVector[0]);
    if(pocitadlo > n-1) //n =10, ale indexuju max do 9
    { 
         pocitadlo = 0;
    }
// pomocné proměnné, které si pamatují, v jaké pozici bylo auto počítače v předchozím cyklu
// z důvodu postupného smazání tohoto starého auta            
    pomAuto2=pomAuto; //pozice starého auta v před-předposlední pozici           
    pomAuto = col2; //pozice starého auta v předposlední pozici
}


/*-----------------------------------Pohyb------------------------------------*/
void Pohyb(void)
{   
    prah = 0.3;          //nastavení prahu, vymezující úhel detekce
    ay = float(acc.getAccY());          //odečítání Y-ové osy akcelerometru

      
    if((ay > prah))     //náklon vpravo
    {       
        poloha =4;  //pravý (5.) sloupec
        //rožnout auto hráče napravo
        poleZeleny[4][poloha] = 1;
        poleZeleny[5][poloha] = 1;
        poleZeleny[6][poloha] = 1;
        poleZeleny[4][poloha+1] = 1;
        poleZeleny[5][poloha+1] = 1;
        poleZeleny[6][poloha+1] = 1;
        //zhasnout auto hráče vlevo
        poleZeleny[4][poloha-2] =! 1;
        poleZeleny[5][poloha-2] =! 1;
        poleZeleny[6][poloha-2] =! 1;
        poleZeleny[4][poloha-1] =! 1;
        poleZeleny[5][poloha-1] =! 1;
        poleZeleny[6][poloha-1] =! 1;
    } 
    else if((ay < -prah)) //náklon vlevo
    { 
        poloha =2;  //levý (3.) sloupec
        //rožnout auto hráče vlevo
        poleZeleny[4][poloha] = 1;
        poleZeleny[5][poloha] = 1;
        poleZeleny[6][poloha] = 1;
        poleZeleny[4][poloha+1] = 1;
        poleZeleny[5][poloha+1] = 1;
        poleZeleny[6][poloha+1] = 1;
        //zhasnout auto hráče vpravo
        poleZeleny[4][poloha+2] =! 1;
        poleZeleny[5][poloha+2] =! 1;
        poleZeleny[6][poloha+2] =! 1;
        poleZeleny[4][poloha+3] =! 1;
        poleZeleny[5][poloha+3] =! 1;
        poleZeleny[6][poloha+3] =! 1;   
    }
}


/*-----------------------------------Kolize-----------------------------------*/
void Kolize(void)
{
    //detekování překryvu matice červených LEDek a matice zelených LEDek
    //detekce probíha pouze ve dvou krajních bodech, ktere dostatečně pokrývají všechny možné kolize
    //poloha těchto bodů je závislá pouze na proměnné "poloha", která určuje, zda jsou vpravo či v levo
    if (poleZeleny[4][poloha] == poleCerveny[4][poloha] || poleZeleny[6][poloha] == poleCerveny[6][poloha])
    {
        
        //při detekci kolize dojde ke zmražení všech pohybů
        tick.detach(); 
        tick2.detach();
        
    //-----zobrazí se oranžový vrak auta-----//    
        poleZeleny[4][poloha-1] = 1;
        poleZeleny[5][poloha] = 1;
        poleZeleny[6][poloha-1] = 1;
        poleZeleny[4][poloha+2] = 1;
        poleZeleny[5][poloha+1] = 1;
        poleZeleny[6][poloha+2] = 1;
        
        poleCerveny[4][poloha-1] = 1;
        poleCerveny[5][poloha] = 1;
        poleCerveny[6][poloha-1] = 1;
        poleCerveny[4][poloha+2] = 1;
        poleCerveny[5][poloha+1] = 1;
        poleCerveny[6][poloha+2] = 1;
        
        //prosvitalo puvodni zeleny auto
        poleZeleny[4][poloha] =! 1;
        poleZeleny[4][poloha+1] =! 1;
        poleZeleny[6][poloha] =! 1;
        poleZeleny[6][poloha+1] =! 1;
        
        wait(2); //zachování tohoto statického obrazu na dobu 2s
        Reset(); // zavolá funkci reset
    }
}



/*-----------------------------------Kolize-----------------------------------*/
void Reset(void)
{
    int col;
    int row;
    
//---na 2s se zobrazí pouze červené LED na celé ploše matice---//    
    for(col = 0; col < 8; col++)
    {
        for(row = 0; row < 8; row++)
        {
            poleZeleny[row][col]=0;
            poleCerveny[row][col]=1; 
        }
    } 
    wait(2);
    
//--------proběhne resetovací fáze--------//
//zhasnutí celé LED matice
    for(col = 0; col < 8; col++)
    {
        for(row = 0; row < 8; row++)
        {
            poleCerveny[row][col]=0; 
        }
    } 
    
//re-inicializace    
    Inicializace();
    pocitadlo = 0;
    rowAuto = 0;
    poloha =4;
    
//zrušení zmražení všech pohybů   
    tick.attach(&SvodidlaPohyb, 1);
    tick2.attach(&AutaPohyb, 0.25);
}