Programa que lee comandos por el puerto serial y reproduce un tono según el comando recibido. Adicionalmente identifica colores con el sensor TC3200 y envía el color leído a través del puerto serial al PC.

Dependencies:   mbed

main.cpp

Committer:
CCastrop1012
Date:
2021-09-03
Revision:
0:38dbd24805dd

File content as of revision 0:38dbd24805dd:

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


//******************************************************************************
//                          Definicion de Periféricos

/// Puerto Serial
Serial SerialPort(SERIAL_TX, SERIAL_RX, 9600);

/// PWM OUTPUTS
PwmOut Buzzer(LED1);

//  Temporizadores 
Ticker LengthTonoBuzzer;

// SENSOR DE COLOR
scolor_TCS3200 SENSOR_COLOR (PA_8, PB_10, PB_4, PB_5, PB_3); 



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


uint8_t   programa_ejecutar = 0; // Variable que almacena la ORDEN (Telemetria ó Telecomando)
                                 // enviada desde el CoolTerm
                                 

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;

uint8_t coolterm_comand;         // Se almacenan Todos los Caracteres recibidos por el SerialPort.

// No usada por Ahora
uint8_t i = 0;                      // Variable usada como Indice de los vectores,
                                    // indica la posicion del vector en donde se reciben 
                                    // ó se almacenan los datos


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
// siendo 
#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.02 /// Duración del periodo en ms, que se pondrá en el Buzzer.period_ms() PARA ESCUCHAR UN SI 

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

#define iniciar_telemetria      0xFE
#define iniciar_telecomando     0xFF

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

#define CMD_rojo   0x01
#define CMD_azul   0x02
#define CMD_verde  0x03
#define CMD_clear  0x04
#define ColorNoIdentificado 0x05

uint8_t color_identificado = ColorNoIdentificado;

//****************************************************************************
//                      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
                                    
                                    
//****************************************************************************
//                  Funciones



void ReadPort()
{
    if(SerialPort.writable()) SerialPort.abort_write();
    coolterm_comand = SerialPort.getc();
    
    if (coolterm_comand == iniciar_telemetria)  programa_ejecutar = iniciar_telemetria; ///  El programa que se ejecutará será Telemetria
    if (coolterm_comand == iniciar_telecomando)  programa_ejecutar = iniciar_telecomando;
    
    
}
 

int main()
 {
    Buzzer.write(0);        ///configura el ciclo util
    SerialPort.attach(&ReadPort, Serial::RxIrq);    ////  se Habilita la interrupcion serial o recepcion de datos
    //SerialPort.printf("Hello World, System Run !!\n"); // mensaje inicial
    
    
    while(1)
    {
     // Esperamos hasta que se GENERE una INTERUPCION y  
     // coolterm_comand reciba un comando ya sea iniciar_telemetria ó iniciar_telecomandos
     // Por lo que generará que programa_ejecutar sea igual al comando recivido
     
     // AHORA:   
     // SI EL PROGRAMA ESCOGIDO ES INICIAR_TELEMETRIA    
        if (programa_ejecutar == iniciar_telemetria)
        {            
            // ESPERAMOS A RECBIR UN COMANDO DESDE EL COOLTERM DIFERENTE AL que YA hemos RECIBIDO
            while(coolterm_comand == iniciar_telemetria)    wait_ms(1); // esperamos mientras se recibe otro dato
            
            ////  Desactivamos la interrupcion serial o recepcion de datos PORQUE NO NECESITAMOS recibir mas datos por AHORA
            SerialPort.attach(NULL, Serial::RxIrq);
            
            // SEGÚN LA TELEMETRIA SELECCIONADA (0X01, 0X02 .... 0XN) ENTONCES SE EJECUTA UNA FUNCIÓN
            switch (coolterm_comand)
            {
                    
                    case telemetria_1:  
                                        // Ejecutamos la Funcion LeerColor();
                                        leer_color();
                                        
                                        break; // salimos del SWITCH
                                        
                    // si no fue ninguno de los valores anteriores entonces:                    
                    default:            SerialPort.printf("telemetria desconocida, inicie nuevamente !!\n");
                                        
                                        break; // salimos del SWITCH

            }
            
            
            // Re inicializamos nuestras variables de control a sus valores iniciales
            // Para no seguir entrando a las sentencias IF
            programa_ejecutar = 0; coolterm_comand = 0; 
                                        
                                        
            ////  HABILITAMOS NUEVAMENTE la interrupcion serial o recepcion de datos
            SerialPort.attach(&ReadPort, Serial::RxIrq);          
        }
        
              
        
        //// SI EL PROGRAMA ESCOGIDO ES INICIAR_TELECOMANDO    
        if (programa_ejecutar == iniciar_telecomando)
        {        
            // ESPERAMOS A RECBIR UN COMANDO DESDE EL COOLTERM DIFERENTE AL que YA hemos RECIBIDO
            while(coolterm_comand == iniciar_telecomando)    wait_ms(1); // esperamos mientras se recibe otro dato
                    
            
            // SEGÚN EL TELECOMANDO SELECCIONADO (0X01, 0X02 .... 0XN) ENTONCES SE EJECUTA UNA FUNCIÓN
            switch (coolterm_comand)
            {
                    
                    case telemcomando_1:  
                                                  
                                            // ESPERAMOS A RECBIR UN COMANDO DESDE EL COOLTERM DIFERENTE AL ULTIMO RECIBIDO
                                            while(coolterm_comand == telemcomando_1)     wait_ms(1);
                                                    duracion_tono = coolterm_comand;  // lo almacenamos en:  duracion_tono
                                                    
                                            // ESPERAMOS A RECBIR UN COMANDO DESDE EL COOLTERM DIFERENTE AL ULTIMO RECIBIDO
                                            while(coolterm_comand == duracion_tono)     wait_ms(1);
                                                    tipo_tono = coolterm_comand;  // lo almacenamos en:  tipo_tono 
                                                    
                                            ////  Desactivamos la interrupcion serial o recepcion de datos PORQUE NO NECESITAMOS recibir mas datos por AHORA
                                            SerialPort.attach(0, Serial::RxIrq);
                                            // Ejecutamos la Funcion LeerColor();
                                            Buzzer_Tone(tipo_tono, duracion_tono);
                                        
                                        break; // salimos del SWITCH
                                        
                    // si no fue ninguno de los valores anteriores entonces:                    
                    default:            SerialPort.abort_read();
                                        SerialPort.printf("TeleComando desconocido, inicie nuevamente !!\n");
                                        
                                        break; // salimos del SWITCH

            }
            
            
            // Re inicializamos nuestras variables de control a sus valores iniciales
            // Para no seguir entrando a las sentencias IF
            programa_ejecutar = 0; coolterm_comand = 0; 
                                        
                                        
            ////  HABILITAMOS NUEVAMENTE la interrupcion serial o recepcion de datos
            SerialPort.attach(&ReadPort, Serial::RxIrq);  
            
        } // Finaliza el IF
         
        
    
    
    }// Finaliza el WHILE
    
    
} // Finaliza el main

void Buzzer_Tone(uint8_t tipo_tono, uint8_t duracion_tono)
    {
        
            
                switch (tipo_tono)
            {
                    
                    case TONO_DO:       Buzzer.period_ms(DO);
                                       //SerialPort.printf("Tono Seleccionado DO!!\n");                                        
                                        
                                        break; // salimos del SWITCH
                                        
                    case TONO_RE:       Buzzer.period_ms(RE);
                                        //SerialPort.printf("Tono Seleccionado RE!!\n");
                                        
                                        break; // salimos del SWITCH
                                        
                    case TONO_MI:       Buzzer.period_ms(MI);
                                        //SerialPort.printf("Tono Seleccionado MI!!\n");
                                        
                                        break; // salimos del SWITCH
                                        
                    case TONO_SI:       Buzzer.period_ms(SI);
                                        //SerialPort.printf("Tono Seleccionado SI!!\n");
                                        
                                        break; // salimos del SWITCH
                                                            
                    // si no fue ninguno de los valores anteriores entonces:                    
                    default:            SerialPort.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;
                        printf ( "0x0%1x\n ", 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;
                            printf ( "0x0%1x\n ", 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;
                            printf ( "0x0%1x \n ", 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;
                        printf ( "0x0%1x \n ", CMD_verde );
                            Buzzer.period_ms(SI);
                            Buzzer.write(0.5);
                            wait(4);
                            Buzzer.write(0); 
                        
                    
                }
            } 
            
            if  (color_identificado == ColorNoIdentificado)
            {
                
                 
                        printf ( "0x0%1x \n ", ColorNoIdentificado);
                            Buzzer.period_ms(10);
                            Buzzer.write(0.5);
                            wait(4);
                            Buzzer.write(0); 
                        
                
            }
                
            color_identificado = ColorNoIdentificado;
        }