Programa de MIP

Dependencies:   bloques ball mbed WS2812 PixelArray tsi_sensor TSI bloque MMA8451Q

main.cpp

Committer:
aarmdlr
Date:
2021-05-27
Revision:
20:6f5f486bd5c3
Parent:
19:e57116ff4c59
Child:
21:88d30cb63bc1

File content as of revision 20:6f5f486bd5c3:

#include "mbed.h"
#include "WS2812.h"
#include "PixelArray.h"
#include "TSISensor.h"
#include "MMA8451Q.h"
#include "ball.h"
#include "bloques.h"

#define WS2812_BUF 256
#define NUM_COLORS 6
#define NUM_LEDS_PER_COLOR 10
#define NUM_LEDS_BARRA 4
#define ACCEL_ADRESS_I2C (0X1D<<1)


 
PixelArray px(WS2812_BUF);
 
// See the program page for information on the timing numbers
// The given numbers are for the K64F
WS2812 wsLEDS(D9, WS2812_BUF, 0, 5, 5, 0);
MMA8451Q acc(PTE25, PTE24, ACCEL_ADRESS_I2C );

///////
Serial pc(USBTX, USBRX);
//////

TSISensor tsi;
int barra[NUM_LEDS_BARRA]={6,7,8,9};
float tsi_oldRead=0;
int counter_tsi=0;
int posAcelerometerTemp, posAcelerometer=0, posAcelerometerOLD=0, posAcelerometerOLD1=0, contadorReboteA=0;
int posSliderTouchTemp, posSliderTouch=0, posSliderTouchOLD=0, posSliderTouchOLD1=0, contadorRebote=0;
ball m_ball;
bool direct_ball=0;
Ticker refresh_ball;
bloques Bloques;
Ticker refresh_bloques;
Ticker refresh_InfoMode;
int cont_ball_rebote=0;
bool settedMode=false;
int angle=1;
bool lose=false;
int sel_opcio=0;
int contModePrintInfo=0;

void update_barra(int led_apagar, int led_encender, int act_barra );
void tsi_ctr_modeBtn(float tsi_newRead);
void tsi_ctr_modeSlider(float tsi_newRead);
void accel_ctr();
void print_pixel(uint8_t valR, uint8_t valG, uint8_t valB, int numPixelMatrix_i, int numPixelMatrix_j, int numPixelMatrixOLD_i, int numPixelMatrixOLD_j, uint8_t size=1);
void setPixelColor(int numPixelMatrix, int r, int g, int b);
void ctr_ball();
void clear_matrix(int offset);
void angle_rebote();
bool addLineOfBloques();
void printBtnMode();
void printSliderMode();
void printAccelMode();
void cyclePrintModeInfo();


int main()
{   
    
    pc.baud(115200);
    pc.printf("\r\n\r\nHola!\r\ncompilado el " __DATE__ ", " __TIME__ "\r\n");
    
    wsLEDS.useII(WS2812::PER_PIXEL); // use per-pixel intensity scaling
    
    refresh_InfoMode.attach(&cyclePrintModeInfo,4.0);
    
    while(settedMode==false){
        float tsi_readTemp=tsi.readPercentage();
        pc.printf("\r\n Touch %d", tsi_readTemp);
        if(tsi_readTemp!=0.0){
            if(tsi_readTemp>0.01 and tsi_readTemp<0.33){
                sel_opcio=0;
                settedMode=true;
            }else if(tsi_readTemp>=0.33 and tsi_readTemp<=0.66){
                sel_opcio=1;
                settedMode=true;
            }else if(tsi_readTemp>0.66 and tsi_readTemp<=1.00){
                sel_opcio=2;
                settedMode=true;
            }
        }
    }
    
    refresh_InfoMode.detach();
    clear_matrix(0);
    
    
    for(int i=0; i<Bloques.getNumBloques(); i++){
        bloque temp_blq=Bloques.getBloque(i);
        print_pixel(temp_blq.getColR(),temp_blq.getColG(),temp_blq.getColB(), temp_blq.getCoordX(),temp_blq.getCoordY(), -1, -1, temp_blq.getSize());
    }
    
    for(int i=0; i<NUM_LEDS_BARRA; i++){
        px.Set(barra[i], 0x2f0000);
    }

    for(int i=0; i<NUM_LEDS_BARRA; i++){
        px.SetI(barra[i]%WS2812_BUF, 255); //0xff
    }
    
    print_pixel(255, 255, 255, m_ball.getCoordX(), m_ball.getCoordY(),-1,-1);
    wsLEDS.write(px.getBuf());
    
    refresh_ball.attach(&ctr_ball, 0.1);
    //refresh_bloques.attach(&addLineOfBloques, 7);
    
    

    
    while (settedMode==true) {
        if(sel_opcio==0){
            tsi_ctr_modeBtn(tsi.readPercentage());
        }
        else{
            if(sel_opcio==1){
                tsi_ctr_modeSlider(tsi.readPercentage());
            }
            else if(sel_opcio==2){
                accel_ctr();
            }
        }   
        //pc.printf("\r\n Touch %d", (rand()%(9-6 + 1) + 6));
        
    }
    
}

void tsi_ctr_modeBtn(float tsi_newRead){
    
    if(tsi_newRead!=0.0){
        if(tsi_newRead>0.6 and tsi_oldRead>0.6){
            counter_tsi++;
        }
        else {
            if(tsi_newRead<0.4 and tsi_oldRead<0.4){
                counter_tsi++;
            }
            else{
                counter_tsi=0;
            }
        }
        tsi_oldRead=tsi_newRead;
    

        if(counter_tsi == 10450){
            if( (tsi_newRead < 0.4) && tsi_newRead!=0 ){ //if left
                if(barra[0]>0){
                    update_barra((NUM_LEDS_BARRA-1),0, -1 );
                }
            }
            else{
                if(tsi_newRead > 0.6){ //if right
                    if(barra[NUM_LEDS_BARRA-1]<15){
                        update_barra(0,(NUM_LEDS_BARRA-1), 1 );
                    }
                }
            }
            //control_tsi(tsi_newRead);
            wsLEDS.write(px.getBuf());
            counter_tsi=0;
        }
    }
    else{
        counter_tsi=0;
    }
    

    //tsi_oldRead=tsi_newRead;
}

void tsi_ctr_modeSlider(float tsi_newRead){
    //Multiplicamos lo que lee el tsi.readPercentage() por 100 para tener un porcentaje del 0 al 100% en lugar del 0 al 1 que devuelve dicha función tsi.readPercentage().
    //Lo multiplicamos por 1.4 para obtener un ranto de entre 0 y 140.
    //Le restamos 70 para que el 50% leido por el tsi represente el 0, de esta forma ahora el rango es de -70 a +70.
    //Dividimos entre 10 para obtener unos valores entre -7 y +7 que son las posiciones que puede tomar la barra inferior si se trata de una barra de 4 pixeles como es el caso.
    posSliderTouchTemp=(((tsi_newRead*100)*1.4)-70)/10;
     
    //Controlamos que no se salga de las posiciones posibles de la barra inferior.
    if(posSliderTouchTemp>-7 and posSliderTouchTemp<7){
        //pc.printf("\r\n Porcentaje=%d",posSliderTouchTemp);
        
        //Se controla los rebotes del TSI ya que sino da saltos, por eso se incrementa un contador cuando detecta una misma posicion mas de una vez seguida.
        if(posSliderTouchTemp==posSliderTouchOLD1){
            contadorRebote=contadorRebote+1;
        }else{
            contadorRebote=0;
        }
        posSliderTouchOLD1=posSliderTouchTemp;
        
        
        if(contadorRebote>=140){
            posSliderTouch=posSliderTouchTemp;
        }
        
         
    }
    
    if(posSliderTouch!=posSliderTouchOLD){
        //Se suaviza el movimiento de la barra inferior para que de un efecto de scroll mas bonito y no tan brusco, 
        //por eso se realiza un for para que pase por todas las posiciones hasta la posicoon de la barra objetivo.
        if(posSliderTouch>posSliderTouchOLD){
            for(int p=posSliderTouchOLD; p<posSliderTouch; p++){
                update_barra(0,(NUM_LEDS_BARRA-1), 1 ); //if rigth
                wsLEDS.write(px.getBuf());
                //printBar( 249, 0, 0, p);
            }
        }else if(posSliderTouch<posSliderTouchOLD){
            for(int p=posSliderTouchOLD; p>posSliderTouch; p--){
                update_barra((NUM_LEDS_BARRA-1), 0, -1 ); //if left
                wsLEDS.write(px.getBuf());
                //printBar( 249, 0, 0, p);
            }
        }
        posSliderTouchOLD=posSliderTouch;
        //pc.printf("\r\n Touch");
        
    }
    
}


void update_barra(int led_apagar, int led_encender, int act_barra ){
    if(m_ball.getCoordX()!=0){
        px.Set(barra[led_apagar], 0x0);  //apagamos el led
                    
        for(int i=0; i<NUM_LEDS_BARRA; i++){ //actualizamos valor del array
            barra[i]=barra[i]+act_barra;
            //pc.printf("\r\n UPDATEEE ------- =%d", barra[i]);
        }
                
        px.Set(barra[led_encender], 0x2f0000); //encendemos el siguiente led
        px.SetI(barra[led_encender]%WS2812_BUF, 255); //0xff
        //ctr_ball_barra();
    }
}


void accel_ctr(){
    float nearest = floor(abs(((acc.getAccY()+1)*100)/2)); //para obtener un valor 0 y 100 
    posAcelerometerTemp=(((nearest)*2.8)-140)/10;
    //pc.printf("\r\n Porcentaje=%d",posAcelerometerTemp);
    if(posAcelerometerTemp<=-7){
        posAcelerometerTemp=-6;
    }else if(posAcelerometerTemp>=7){
        posAcelerometerTemp=6;
    }
    if(posAcelerometerTemp>-7 and posAcelerometerTemp<7){
        //pc.printf("\r\n Porcentaje=%d",posAcelerometerTemp);
        //pc.printf("\r\n Ha entrat");
        if(posAcelerometerTemp==posAcelerometerOLD1){
            contadorReboteA=contadorReboteA+1;
        }else{
            contadorReboteA=0;
        }
        posAcelerometerOLD1=posAcelerometerTemp;
        if(contadorReboteA>=40){
            posAcelerometer=posAcelerometerTemp;
        }
             
    }
    if(posAcelerometer!=posAcelerometerOLD){
        if(posAcelerometer>posAcelerometerOLD){
            for(int p=posAcelerometerOLD; p<posAcelerometer; p++){ //movemos la barrita hasta la posición actual, mostrando la animación
                update_barra(0,(NUM_LEDS_BARRA-1), 1 ); //if rigth
                wsLEDS.write(px.getBuf());
                //pc.printf("\r\n HOLAAAA DRETA=%d",p);
                
            }
        }else if(posAcelerometer<posAcelerometerOLD){
            //pc.printf("\r\n HOLAAAA ESQUERRA");
            for(int p=posAcelerometerOLD; p>posAcelerometer; p--){
                update_barra((NUM_LEDS_BARRA-1), 0, -1 ); //if left
                wsLEDS.write(px.getBuf());
                //pc.printf("\r\n HOLAAAA ESQUERRA=%d",p);
                
            }
         
        }
            
       posAcelerometerOLD=posAcelerometer;
        
        //pc.printf("\r\n Acelerometer");
    }
}

void print_pixel(uint8_t valR, uint8_t valG, uint8_t valB, int numPixelMatrix_i, int numPixelMatrix_j, int numPixelMatrixOLD_i, int numPixelMatrixOLD_j, uint8_t size) {
    
    //printf ("\r\nRGB=> %ld, %ld, %ld \r\n", valR, valG, valB);
    
    if(numPixelMatrixOLD_i!=-1 and numPixelMatrixOLD_j!=-1){
        for(int j=numPixelMatrixOLD_j; j<(numPixelMatrixOLD_j+size); j++){
            uint8_t numPixelMatrixOLD;
            if(numPixelMatrixOLD_i%2==0){
                numPixelMatrixOLD=(numPixelMatrixOLD_i*16)+j;
            }else{
                numPixelMatrixOLD=((numPixelMatrixOLD_i*16)+15)-j;
            }        
            
            setPixelColor(numPixelMatrixOLD, 0, 0, 0);
                
        }
    }
    if(numPixelMatrix_i!=-1 or numPixelMatrix_j!=-1){
        for(int j=numPixelMatrix_j; j<(numPixelMatrix_j+size); j++){
            uint8_t numPixelMatrix;
            if(numPixelMatrix_i%2==0){
                numPixelMatrix=(numPixelMatrix_i*16)+j;
            }else{
                numPixelMatrix=((numPixelMatrix_i*16)+15)-j;
            }            
            
            setPixelColor(numPixelMatrix, valR, valG, valB);   
        } 
    }
    //wsLEDS.write(px.getBuf());
    
}

void setPixelColor(int numPixelMatrix, int r, int g, int b){
    px.SetI(numPixelMatrix,255);
    px.SetR(numPixelMatrix,r);
    px.SetG(numPixelMatrix,g);
    px.SetB(numPixelMatrix,b);
}

void ctr_ball(){
    int old_i=m_ball.getCoordX();
    int old_j=m_ball.getCoordY();
    
    bool found_barra=false;
    int i=0;
    if(old_i==15){
        //pc.printf("TECHO Angle ANTES REBOTE --> %d \r\n", angle);
        direct_ball=!direct_ball;
        angle_rebote();
        //pc.printf("TECHO Angle DESPUES REBOTE --> %d \r\n", angle);
    }
    else{
        if( (old_j==15 or old_j==0) and (angle!=1)){ //and old_i!=1){
            //pc.printf("PAREEEED Angle ANTES REBOTE --> %d \r\n", angle);
            angle_rebote();
            //pc.printf("PAREEEED Angle DESPUES REBOTE --> %d \r\n", angle);
            
        }//else{
            int predict_Y=m_ball.predict_Y_axis(direct_ball, angle); //sino poner el barra
            pc.printf("\r\n Coord X %d, Coord Y %d y predictY %d, angle %d, direction %d --> ",m_ball.getCoordX(), m_ball.getCoordY() , predict_Y, angle, direct_ball );
            while(!found_barra and i<NUM_LEDS_BARRA){
                if(barra[i]==predict_Y and old_i==1){
                    found_barra=true;
                    direct_ball=!direct_ball;           
                }//else{
                    i++;
                //}
            }
            if(found_barra){
                if(barra[0]==predict_Y){
                    angle=0;
                }else{
                    if(barra[3]==predict_Y){
                        angle=2;
                    }else{
                        angle=1;
                    }
                }
                if(cont_ball_rebote==3){
                    cont_ball_rebote=0;
                    lose=addLineOfBloques();
                    
                }
                cont_ball_rebote++;
            }else if(old_i==0){
                  refresh_ball.detach();  
                  clear_matrix(0);
                  wsLEDS.write(px.getBuf());
                  lose=true;
            }
            
        //}
    }
        
    /*if((barra[0]==old_j or barra[1]==old_j or barra[2]==old_j or barra[3]==old_j) and old_i==1){
        direct_ball=!direct_ball; 
    }*/
    
    if(!lose){
        bool found_blq_i=false;
        int i=0;
        
        
        int next_CoordX;
        if(direct_ball){
            next_CoordX=old_i+1;
        }else if(!direct_ball){
            next_CoordX=old_i-1;
        }
        
        while(!found_blq_i and i<Bloques.getNumBloques() ){
            bloque temp_blq=Bloques.getBloque(i);
            if((temp_blq.getCoordX()==next_CoordX)){
                found_blq_i=true;
            }
            i++;
        }
        
        bool found_blq_j=false;
        int j=0;
        if(found_blq_i){
            int predict_Y=m_ball.predict_Y_axis(direct_ball, angle);
            //pc.printf("\r\n Coord X %d, Coord Y %d y predictY %d, angle %d, direction %d --> ",m_ball.getCoordX(), m_ball.getCoordY() , predict_Y, angle, direct_ball );
            while(!found_blq_j and j<Bloques.getNumBloques() ){
                bloque temp_blq=Bloques.getBloque(j);
                int blq_pos_Y=(temp_blq.getCoordY()+temp_blq.getSize());
                
                if((blq_pos_Y>predict_Y and predict_Y>=temp_blq.getCoordY()) and temp_blq.getCoordX()==next_CoordX){ //and temp_blq.getEnabled()
                    found_blq_j=true;
                    direct_ball=!direct_ball;
                    //angle_rebote();
                    print_pixel(temp_blq.getColR(), temp_blq.getColG(), temp_blq.getColB(), -1, -1, temp_blq.getCoordX(), temp_blq.getCoordY(), temp_blq.getSize());
                    wsLEDS.write(px.getBuf());
                    Bloques.disable_blq(j);
                    //pc.printf("BloqY %d, temp_bloq.CoordY %d y predictY %d --> %d", blq_pos_Y, temp_blq.getCoordY() , predict_Y );
                    
                    if(!direct_ball){
                        angle_rebote();
                    }else{
                        //m_ball.setCoordX(next_CoordX);
                        //m_ball.setCoordY(predict_Y);
                    }
                }
                j++;
            }
        }
        m_ball.movement(direct_ball, angle);   
        print_pixel(255, 255, 255, m_ball.getCoordX(), m_ball.getCoordY(),old_i, old_j);
        wsLEDS.write(px.getBuf());
    }
}

void clear_matrix(int offset){
    for(int i=offset; i<256; i++){
        setPixelColor(i,0,0,0);
    }
       
}

void angle_rebote(){
    if(angle==0){
        angle=2;
    }else if(angle==2){
        angle=0;
    }
}

bool addLineOfBloques(){
    
    bool end_game=Bloques.addLineBloques();
    if(end_game){
        refresh_ball.detach();  
        clear_matrix(0);
        wsLEDS.write(px.getBuf());
    }
    else{
        clear_matrix(32);    
        for(int i=0; i<Bloques.getNumBloques(); i++){
            bloque temp_blq=Bloques.getBloque(i);
            print_pixel(temp_blq.getColR(),temp_blq.getColG(),temp_blq.getColB(), temp_blq.getCoordX(),temp_blq.getCoordY(), -1, -1, temp_blq.getSize());
        }
        wsLEDS.write(px.getBuf());
    }
    return end_game;
    
}

void printBtnMode(){
    
    //Base gris del mando
    for(int f=5; f<10; f++){
        for(int c=3; c<13; c++){
            print_pixel(199,200,205, f,c, -1, -1);
        }    
    }
    
    //Barra inferior posicionamiento a tocar
    for(int f=0; f<3; f++){
        for(int c=0; c<5; c++){
            print_pixel(0,255,0, f,c, -1, -1);
        }
        for(int c=5; c<16; c++){
            print_pixel(255,0,0, f,c, -1, -1);
        }  
    }
    
    //Cruceta del mando (iquierda)
    print_pixel(20,20,20, 6,5, -1, -1);
    print_pixel(20,20,20, 7,5, -1, -1);
    print_pixel(20,20,20, 8,5, -1, -1);
    print_pixel(20,20,20, 7,4, -1, -1);
    print_pixel(20,20,20, 7,6, -1, -1);
    
    //Botones del mando (derecha)
    print_pixel(224,180,44, 6,10, -1, -1);
    print_pixel(32,139,87, 7,9, -1, -1);
    print_pixel(189,26,26, 7,11, -1, -1);
    print_pixel(22,70,177, 8,10, -1, -1);
    
    //Letra L
    print_pixel(200,200,0, 11,3, -1, -1);
    print_pixel(200,200,0, 11,4, -1, -1);
    print_pixel(200,200,0, 11,5, -1, -1);
    print_pixel(200,200,0, 12,3, -1, -1);
    print_pixel(200,200,0, 13,3, -1, -1);
    print_pixel(200,200,0, 14,3, -1, -1);
    
    //Letra R
    print_pixel(200,200,0, 11,10, -1, -1);
    print_pixel(200,200,0, 11,12, -1, -1);
    print_pixel(200,200,0, 12,10, -1, -1);
    print_pixel(200,200,0, 12,11, -1, -1);
    print_pixel(200,200,0, 13,10, -1, -1);
    print_pixel(200,200,0, 13,12, -1, -1);
    print_pixel(200,200,0, 14,10, -1, -1);
    print_pixel(200,200,0, 14,11, -1, -1);
    print_pixel(200,200,0, 14,12, -1, -1);
    
    wsLEDS.write(px.getBuf());
}

void printSliderMode(){
    
    //Base gris del slider
    for(int c=1; c<15; c++){
        print_pixel(255,255,255, 12,c, -1, -1);   
    }
    
    //Parte azul slider
    print_pixel(0,0,205, 11,5, -1, -1); 
    print_pixel(0,0,205, 12,5, -1, -1); 
    print_pixel(0,0,205, 13,5, -1, -1); 
    
    //flecha
    for(int c=1; c<15; c++){
        print_pixel(249,215,28, 7, c, -1, -1);   
    }
    
    print_pixel(249,215,28, 8,2, -1, -1); 
    print_pixel(249,215,28, 9,3, -1, -1); 
    print_pixel(249,215,28, 6,2, -1, -1); 
    print_pixel(249,215,28, 5,3, -1, -1); 
    print_pixel(249,215,28, 8,13, -1, -1); 
    print_pixel(249,215,28, 9,12, -1, -1); 
    print_pixel(249,215,28, 6,13, -1, -1); 
    print_pixel(249,215,28, 5,12, -1, -1); 
    
    
    
    //Barra inferior posicionamiento a tocar
    for(int f=0; f<3; f++){
        for(int c=0; c<5; c++){
            print_pixel(255,0,0, f,c, -1, -1);
        } 
        for(int c=5; c<11; c++){
            print_pixel(0,255,0, f,c, -1, -1);
        }
        for(int c=11; c<16; c++){
            print_pixel(255,0,0, f,c, -1, -1);
        }  
    }
    
    
    wsLEDS.write(px.getBuf());
}

void printAccelMode(){
    
    //Base gris de la placa acelerometro
    for(int f=6; f<14; f++){
        for(int c=11; c<16; c++){
            print_pixel(255,255,255, f,c, -1, -1);
        }    
    }
    
    //Parte interna placa
    for(int f=7; f<9; f++){
        for(int c=12; c<15; c++){
            print_pixel(118,118,109, f,c, -1, -1);
        }    
    }
    
    //flecha
    print_pixel(249,215,28, 6,4, -1, -1, 3); 
    print_pixel(249,215,28, 7,1, -1, -1); 
    print_pixel(249,215,28, 7,3, -1, -1); 
    print_pixel(249,215,28, 7,7, -1, -1); 
    print_pixel(249,215,28, 7,9, -1, -1); 
    print_pixel(249,215,28, 8,1, -1, -1, 2); 
    print_pixel(249,215,28, 8,8, -1, -1, 2); 
    print_pixel(249,215,28, 9,1, -1, -1, 3); 
    print_pixel(249,215,28, 9,7, -1, -1, 3);
    
    
    //Barra inferior posicionamiento a tocar
    for(int f=0; f<3; f++){
        for(int c=0; c<11; c++){
            print_pixel(255,0,0, f,c, -1, -1);
        } 
        for(int c=11; c<16; c++){
            print_pixel(0,255,0, f,c, -1, -1);
        }  
    }
    
    
    wsLEDS.write(px.getBuf());
}

void cyclePrintModeInfo(){
    if(contModePrintInfo==0){
        clear_matrix(0);
        printBtnMode();
        contModePrintInfo++;
    }else if(contModePrintInfo==1){
        clear_matrix(0);
        printSliderMode();
        contModePrintInfo++;
    }else{
        clear_matrix(0);
        printAccelMode();
        contModePrintInfo=0;
    }
}