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

Revision:
0:38dbd24805dd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Sep 03 05:18:41 2021 +0000
@@ -0,0 +1,367 @@
+#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;
+        }
+        
+        
+