Se leen comando por el puerto serial realiza las siguientes funciones según el comando: - Genera distintos tonos por un buzzer. - Controla el movimiento de un carro (con 2 motores) con comandos - Controla el movimiento de un carro (con 2 motores) con Joystick. - Lee y envía el color leido por el puerto serial al PC

Dependencies:   mbed

main.cpp

Committer:
CCastrop1012
Date:
2021-09-03
Revision:
0:3a37f6734913

File content as of revision 0:3a37f6734913:

#include "mbed.h"
#include "Motor.h"
#include "scolor_TCS3200.h"

// Puerto de comunicacion Serial
Serial CoolTerm(USBTX, USBRX);

// Motores        m1step
TraccionD Motores(PB_5, PB_3, PB_10, PB_4, 200, 3.75, 15.5) ;

/// PWM OUTPUTS
PwmOut Buzzer(D10); // LED1

//  Temporizadores 
Ticker MuestrearCOLOR;

// SENSOR DE COLOR
scolor_TCS3200 SENSOR_COLOR (PA_9, PC_7, PB_6, PA_7, PA_8); 


// Lecturas Analogas de Joystick 
AnalogIn JEjeX(A0);
AnalogIn JEjeY(A1);

 
// Salidas digitales
DigitalOut LED(PA_5);


//******************************************************************************
///         Declarar Variables Globales 


/// Variables sensor de color
long red;                        //Almacenan el Tiempo que dura el CicloUtil de la frecuencia
long blue;                       //Generada por el Sensor TSC3200, al leer el componente
long green;                      //R, G, B o Clear del color que tenga en Frente
long clear;


/// Constantes Sensor de Color
#define CMD_rojo   0x01
#define CMD_azul   0x02
#define CMD_verde  0x03
#define CMD_clear  0x04
#define ColorNoIdentificado 0x00


uint8_t color_identificado = ColorNoIdentificado;



/// Varialbles Buzzer
uint8_t duracion_tono = 1;       // Variable que almacena el Tiempo que es ESCUCHARÁ el Tono
uint8_t tipo_tono = 1;           // Variable que almacena el Tono que se desee escuchar

/// Constantes Buzzer
#define TONO_DO 0x01 /// si tipo_tono == 0x01, se escuchará un DO
#define TONO_RE 0x02 /// si tipo_tono == 0x02, se escuchará un RE
#define TONO_MI 0x03 /// si tipo_tono == 0x03, se escuchará un MI
#define TONO_SI 0x04 /// si tipo_tono == 0x04, se escuchará un SI

#define DO 3.78 /// Duración del periodo en ms, que se pondrá en el Buzzer.period_ms() PARA ESCUCHAR UN DO
#define RE 3.36 /// Duración del periodo en ms, que se pondrá en el Buzzer.period_ms() PARA ESCUCHAR UN RE
#define MI 3.03 /// Duración del periodo en ms, que se pondrá en el Buzzer.period_ms() PARA ESCUCHAR UN MI
#define SI 2.82 /// Duración del periodo en ms, que se pondrá en el Buzzer.period_ms() PARA ESCUCHAR UN SI 




#define limite 0.727

// variables de control y flujo de programa

uint8_t   programa_ejecutar = 0; // Variable que almacena la ORDEN (Telemetria ó Telecomando)
                                 // enviada desde el CoolTerm
uint8_t   coolterm_data;         // Se almacenan Todos los Caracteres recividos por el CoolTerm.


// Constantes de velocidad

#define VelAlta  300
#define VelMedia 200
#define VelBaja 100


//******************************************************************************
// COMANDOS

#define iniciar_telemetria      0xFE
#define iniciar_telecomando     0xFF

#define telemetria_1            0x01  //
#define telemcomando_1          0x01

#define C_LeerColor  0x00
#define C_Sonido1    0x01
#define C_Sonido2    0x02
#define C_Sonido3    0x03
#define C_Sonido4    0x04
#define C_Adelante   0x05
#define C_Atras      0x06
#define C_Izquierda  0x07
#define C_Derecha    0x08
#define C_Velocidad  0x09
#define C_Joistck    0x0A
int comando_joystick = 0;


// variables y constantes del Joystick

uint8_t estado_x; 
uint8_t estado_y;
#define E_Derecha 1
#define E_Izquier 0
#define E_Adelante 1
#define E_Atras 0
#define E_Centro 3
#define Lim_JKIn 150
#define Lim_JKSup 180

//****************************************************************************
//                      Prototipo de funciones

void ReadPort(void);                // Lee el puerto Serial
void MainConfig(void);              // Configuracion Inicial de los Perifericos del uC
void Buzzer_Tone(uint8_t tipo_tono, uint8_t duracion_tono); // configura el tono y la duracion escuchada a travez del Buzzer
void leer_color(void);              // funcion que retorna los componentes
                                    // RGB y Clear del color leido
void leer_Joystick();               // Ejerce control sobre el Movimiento del carro desde el Joistick  

//****************************************************************************
//     
#define valorInicial 0xAA
uint8_t n_interrupcion = 0;
uint8_t ComandoRecivido = valorInicial, Parametro = valorInicial;

void ReadPort()
{
   
    //if(CoolTerm.writable()) CoolTerm.abort_write(); // ELIMINA LO QUE ESTEMOS ESCRIBIENDO AL COOLTERM
    
    if (n_interrupcion == 0) { coolterm_data = CoolTerm.getc(); }
    if (n_interrupcion == 1) { ComandoRecivido = CoolTerm.getc(); n_interrupcion++; }
    if (n_interrupcion == 2) { Parametro       = CoolTerm.getc(); n_interrupcion = 0;}
    if (coolterm_data == iniciar_telecomando) { programa_ejecutar = iniciar_telecomando; n_interrupcion++; }
    if (ComandoRecivido == 0x0A) comando_joystick = 0; // Da valores diferentes al inicial de cada variable
    
}

///******************************************+


void leer_Joystick()
{   

/// Variables Joystick
float EjeX;
float EjeY;
float Vx;
float Vy;

 while (comando_joystick == 1) // 
 {
    
    EjeX = JEjeX.read();
    Vx = EjeX * 3300; 
    wait (0.1);
    EjeY = JEjeY.read();
    Vy = EjeY * 3300;
    
//    CoolTerm.printf ("ejex: %f    ejey: %f  Vx: %f  Vy: %f \n   ", EjeX, EjeY, Vx, Vy);

    if(int(Vx/10) > Lim_JKIn && int(Vx/10) < Lim_JKSup) {estado_x = E_Centro; }//(CoolTerm.printf ("Estado X Centro \n"); }          
    if(int(Vy/10) > Lim_JKIn && int(Vy/10) < Lim_JKSup) {estado_y = E_Centro; }//CoolTerm.printf ("Estado Y Centro \n"); }
    
    if(int(Vx/10) > Lim_JKSup && estado_y == E_Centro){ estado_x = E_Izquier; }// CoolTerm.printf ("Estado X Izquierda\n"); }
    if(int(Vy/10) > Lim_JKSup && estado_x == E_Centro){ estado_y = E_Atras; }//  CoolTerm.printf ("Estado Y Adelante\n"); }
    
    if(int(Vx/10) < Lim_JKIn && estado_y == E_Centro){ estado_x = E_Derecha; } //CoolTerm.printf ("Estado X Derecha\n"); }
    if(int(Vy/10) < Lim_JKIn && estado_x == E_Centro){ estado_y = E_Adelante; } //CoolTerm.printf ("Estado Y Atras\n"); }
 
 
       // CoolTerm.printf ("\n\n X = %d         Y = %d \n",estado_x , estado_y); 
      // wait(2);      
    // Combinacion de estados para STOP
    if( estado_x == E_Centro && estado_y == E_Centro){ Motores.Stop(); CoolTerm.printf ("MOTORES STOP\n"); }
    
    // Combinacion de estados para ADELANTE
    if(estado_x == E_Centro && estado_y == E_Adelante) { Motores.Back(); Motores.Run(1);CoolTerm.printf ("MOTORES BACK\n"); } 
    
    // Combinacion de estados para ATRAS
    if(estado_x == E_Centro && estado_y == E_Atras) { Motores.Forward(); Motores.Run(1);CoolTerm.printf ("MOTORES FORWARD\n"); } 
    
    
    // Combinacion de estados para DERECHA
    if(estado_y == E_Centro && estado_x == E_Derecha) {  Motores.Giro(15, false); Motores.Run(1); CoolTerm.printf ("MOTORES DERECHA\n"); } 
    
    // Combinacion de estados para IZQUIERDA
    if(estado_y == E_Centro && estado_x == E_Izquier) { Motores.Giro(15, true); Motores.Run(1); CoolTerm.printf ("MOTORES IZQUIERDA\n"); } 
    //wait(1.5);
}
    comando_joystick = 0;

}


int main() {

    Buzzer.write(0);        ///configura el ciclo util
    Motores.StepFreq(VelMedia);
    CoolTerm.attach(&ReadPort, Serial::RxIrq);    ////  se Habilita la interrupcion serial o recepcion de datos
    //MuestrearCOLOR.attach(&leer_color, 0.6);
    
    //CoolTerm.printf("Hello World, System Run !!\n"); // mensaje inicial
    //leer_Joystick ();
      
    while(1) 
    {
        
      
       /// Espera hasta recivir OxFF
        while(programa_ejecutar != iniciar_telecomando)wait(0.01);
         
       /// Espera hasta que reciva algo diferente de 0xAA 
        while(ComandoRecivido == valorInicial)wait(0.01);
        
       /// Espera hasta que reciva algo diferente de 0xAA 
        while(Parametro == valorInicial)wait(0.01);
        
        
        ////  Desactivamos la interrupcion serial o recepcion de datos PORQUE NO NECESITAMOS recibir mas datos por AHORA
         CoolTerm.attach(NULL, Serial::RxIrq);
            
        switch(ComandoRecivido)
        {
            
            //case C_LeerColor:   // Ejecutamos la Funcion LeerColor();
              //                  leer_color();
                    //break;
            case C_Sonido1:     //CoolTerm.printf("SONIDO 1\n");
                                duracion_tono = Parametro;  // lo almacenamos en:  duracion_tono
                                tipo_tono     = TONO_DO;
                                Buzzer_Tone(tipo_tono, duracion_tono);         
                    break;
            case C_Sonido2:     //CoolTerm.printf("SONIDO 2\n");
                                duracion_tono = Parametro;  // lo almacenamos en:  duracion_tono
                                tipo_tono     = TONO_RE;
                                Buzzer_Tone(tipo_tono, duracion_tono);         
                    break;
            case C_Sonido3:     //CoolTerm.printf("SONIDO 3\n");
                                duracion_tono = Parametro;  // lo almacenamos en:  duracion_tono
                                tipo_tono     = TONO_MI;
                                Buzzer_Tone(tipo_tono, duracion_tono);         
                    break;
            case C_Sonido4:     //CoolTerm.printf("SONIDO 4\n");
                                duracion_tono = Parametro;  // lo almacenamos en:  duracion_tono
                                tipo_tono     = TONO_SI;
                                Buzzer_Tone(tipo_tono, duracion_tono);         
                    break;
            case C_Adelante:    Motores.Forward(); Motores.RunRound(Parametro);
                    break;
            case C_Atras:       Motores.Back(); Motores.RunRound(Parametro);
                    break;
            case C_Izquierda:   Motores.Giro(65, true);
                    break;
            case C_Derecha:     Motores.Giro(65, false);
                    break;
            case C_Velocidad:   if(Parametro == 0x01)Motores.StepFreq(VelBaja);
                                if(Parametro == 0x02)Motores.StepFreq(VelMedia);
                                if(Parametro == 0x03)Motores.StepFreq(VelAlta);                                
                    break;
            case C_Joistck:     comando_joystick = 1; leer_Joystick();     
                    break;
            default: break;    
                    
            
        }
            
            //CoolTerm.printf("ProgramaFinalizado!!\n"); 
            
         // Re inicializamos nuestras variables de control a sus valores iniciales
            // Para no seguir entrando a las sentencias IF
            programa_ejecutar = 0; coolterm_data = 0; 
            ComandoRecivido = valorInicial; Parametro  = valorInicial;
            ////  HABILITAMOS NUEVAMENTE la interrupcion serial o recepcion de datos
            CoolTerm.attach(&ReadPort, Serial::RxIrq);  
        
    }
    
}



void Buzzer_Tone(uint8_t tipo_tono, uint8_t duracion_tono)
    {
        
            
                switch (tipo_tono)
            {
                    
                    case TONO_DO:       Buzzer.period_ms(DO);
                                       //CoolTerm.printf("Tono Seleccionado DO!!\n");                                        
                                        
                                        break; // salimos del SWITCH
                                        
                    case TONO_RE:       Buzzer.period_ms(RE);
                                        //CoolTerm.printf("Tono Seleccionado RE!!\n");
                                        
                                        break; // salimos del SWITCH
                                        
                    case TONO_MI:       Buzzer.period_ms(MI);
                                        //CoolTerm.printf("Tono Seleccionado MI!!\n");
                                        
                                        break; // salimos del SWITCH
                                        
                    case TONO_SI:       Buzzer.period_ms(SI);
                                        //CoolTerm.printf("Tono Seleccionado SI!!\n");
                                        
                                        break; // salimos del SWITCH
                                                            
                    // si no fue ninguno de los valores anteriores entonces:                    
                    default:            //CoolTerm.printf("teleComando desconocido, inicie nuevamente !!\n");
                                        
                                        break; // salimos del SWITCH

            }
                // COMO EL CICLO UTIL DEL BUZZER ESTABA EN 0, POR LO CUAL NO SONABA
                // SE PONE AL 50% DEL PERIODO
                Buzzer.write(0.5);
                // SE ESPERA DURANTE EN TIEMPO INGRESADO (EN SEGUNDOS )
                wait(duracion_tono);
                
                // Se Reinicializa el Periodo y el Ciclo útil de la señal PWM 
                // que va al Buzzer
                Buzzer.period_ms(1);
                Buzzer.write(0);
              
    
    
    }



void leer_color()
    {
    
        red    = SENSOR_COLOR.ReadRed(); // OBTENEMOS EL TIEMPO DEL CICLO UTIL DE LA FRECUENCIA DE SALIDA 
        green  = SENSOR_COLOR.ReadGreen();
        blue   = SENSOR_COLOR.ReadBlue();
        clear  = SENSOR_COLOR.ReadClear();
        
        //printf("RED: %5d     GREEN: %5d     BLUE: %5d     CLEAR: %5d    \n ", red, green, blue, clear);
         
        red     *= 2;   // Calculamos EL PERIODO de la frecuencia generada por la lectura del fotodiodo rojo         
        blue    *= 2;   // Calculamos EL PERIODO de la frecuencia generada por la lectura del fotodiodo rojo
        green   *= 2;   // Calculamos EL PERIODO  de la frecuencia generada por la lectura del fotodiodo rojo
        clear   *= 2;   // Calculamos EL PERIODO  de la frecuencia generada por la lectura del fotodiodo rojo
        
        //printf("RED: %5d     GREEN: %5d     BLUE: %5d     CLEAR: %5d    \n ", red, green, blue, clear);
       
        
       //////////////////////////////////////////////////////////////     
       ////         identificar azul
       
       
       if(red <=42 && red >=24)
        {
            if(green >= 20 && green <= 28 )
            {
                if(blue >= 10 && blue <= 16)
                {
                        color_identificado = CMD_azul;
                        CoolTerm.putc( iniciar_telemetria);
                        CoolTerm.putc( CMD_azul ); 
                        //Buzzer.period_ms(DO);
                        //Buzzer.write(0.5);
                        //wait(4);
                        //Buzzer.write(0);
                       
                }
            }
         }   
                 
        
        
        
        /////////////////////////////////////////////////////////////
        ///         identificar rojo
        if(red <= 12 )
        {
            if(green >= 10 && green <= 28 ) 
                {
                    if(blue >= 18 && blue <= 24)
                    {
                            color_identificado = CMD_rojo;
                            CoolTerm.putc( iniciar_telemetria);
                            CoolTerm.putc( CMD_rojo ); 
                            //Buzzer.period_ms(RE);
                            //Buzzer.write(0.5);  //PERIODO UTIL
                            //wait(4);            //TIEMPO ACTIVO DEL BUZZER
                            //Buzzer.write(0.0);
                    }
                }
                
            if(green < 10 && green >= 6 )
                {
                    if(blue <= 12  )
                    {
                            color_identificado = CMD_clear;
                            CoolTerm.putc( iniciar_telemetria);
                            CoolTerm.putc( CMD_clear );
                            //Buzzer.period_ms(MI);
                            //Buzzer.write(0.5);
                            //wait(4);
                            //Buzzer.write(0);
                    }
                    
                }
            
         }   
         
         
             if(green >= 36 && green <= 44 )
            {
                if(red >= 40 && red <= 50 )
            
                {
                        color_identificado = CMD_verde;
                        CoolTerm.putc( iniciar_telemetria);
                        CoolTerm.putc( CMD_verde );
                            //Buzzer.period_ms(SI);
                            //Buzzer.write(0.5);
                            //wait(4);
                            //Buzzer.write(0); 
                        
                    
                }
            } 
            
            if  (color_identificado == ColorNoIdentificado)
            {
                
                 
                        CoolTerm.putc( iniciar_telemetria);
                        CoolTerm.putc( ColorNoIdentificado);
                            //Buzzer.period_ms(10);
                            //Buzzer.write(0.5);
                            //wait(4);
                            //Buzzer.write(0); 
                        
                
            }
                
            color_identificado = ColorNoIdentificado;
        }