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

Files at this revision

API Documentation at this revision

Comitter:
CCastrop1012
Date:
Fri Sep 03 05:18:41 2021 +0000
Commit message:
Programa finalizado y funcional.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
scolor_TCS3200.cpp Show annotated file Show diff for this revision Revisions of this file
scolor_TCS3200.h Show annotated file Show diff for this revision Revisions of this file
--- /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;
+        }
+        
+        
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Sep 03 05:18:41 2021 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scolor_TCS3200.cpp	Fri Sep 03 05:18:41 2021 +0000
@@ -0,0 +1,37 @@
+#include "mbed.h"
+#include "scolor_TCS3200.h"
+
+
+scolor_TCS3200::scolor_TCS3200(PinName s0, PinName s1, PinName s2, PinName s3, PinName s_in) : 
+_s0(s0), _s1(s1), _s2(s2), _s3(s3), _s_in(s_in) 
+{
+    SetMode(SCALE_100);
+
+};
+ 
+
+long scolor_TCS3200::ReadRed()   { _s2=0;  _s3=0; return pulsewidth();}
+long scolor_TCS3200::ReadBlue()  { _s2=0;  _s3=1; return pulsewidth();}
+long scolor_TCS3200::ReadClear() { _s2=1;  _s3=0; return pulsewidth();}
+long scolor_TCS3200::ReadGreen() { _s2=1;  _s3=1; return pulsewidth();}
+
+void scolor_TCS3200::SetMode(uint8_t mode) {
+    switch (mode){
+        case SCALE_100:  _s0= 1; _s1=1; break;
+        case SCALE_20:   _s0=1 ; _s1=0; break;
+        case SCALE_2:    _s0=0 ; _s1=1; break;
+        case POWER_DOWN: _s0=0 ; _s1=0; break;
+    } 
+};
+ 
+long  scolor_TCS3200::pulsewidth() {
+    while(!_s_in);
+    timer.start();
+    while(_s_in);
+    timer.stop();
+    float pulsewidth_v = timer.read_us();
+    timer.reset();
+    return pulsewidth_v;
+};
+            
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scolor_TCS3200.h	Fri Sep 03 05:18:41 2021 +0000
@@ -0,0 +1,63 @@
+#ifndef SCOLOR_TCS3200_H
+#define SCOLOR_TCS3200_H
+#include "mbed.h"
+ /* **************************************************************************
+ 
+@fabeltranm 2019
+fbeltranm@ecci.edu.co
+
+
+   datasheet https://www.mouser.com/catalog/specsheets/TCS3200-E11.pdf
+
+
+    S0      Frequency scaling 
+    S1      Frequency scaling 
+    S2      Photo diode selection 
+    S3      Photo diode selection 
+    OutFreq Frequency
+
+       -----------------------------------
+      |   ____________     ____________   |
+----> |  |            |   |            |  |                ___     ___ 
+Light |  | Photodiode |   |   Current  |--|---OUTPUT_FREQ |   |___|   |___
+----> |  |   Array    |---|     to     |  |
+      |  |            |   |  Frequency |  |
+      |  |____________|   |____________|  |
+      |       ^  ^             ^  ^       |
+       -------|--|-------------|--|-------
+              |  |             |  |
+             S2 S3            S0  S1
+             
+SO | S1 | OUTPUT FREQUENCY SCALING |        | S2 | S3 |   PHOTODIODE TYPE   |
+ 0 | 0  |        power down        |        |  0 | 0  |         Red         |
+ 0 | 1  |           2%             |        |  0 | 1  |         Blue        |
+ 1 | 0  |           20%            |        |  1 | 0  |  Clear (no filter)  |
+ 1 | 1  |           100%           |        |  1 | 1  |         Green       | 
+             
+******************************************************************************/
+
+
+#define SCALE_100   1
+#define SCALE_20    2
+#define SCALE_2     3    
+#define POWER_DOWN  4
+
+class scolor_TCS3200 {
+  public:
+    scolor_TCS3200(PinName s0, PinName s1, PinName s2, PinName s3, PinName s_in);
+    long ReadRed();     // retorno el tiempo en alto de OutFreq para Rojo en ns
+    long ReadGreen();   // retorno el tiempo en alto de OutFreq para verde en ns
+    long ReadBlue();    // retorno el tiempo en alto de OutFreq color azul en ns
+    long ReadClear();   // retorno el tiempo en alto de OutFreq sin filtro en ns
+    void SetMode(uint8_t mode);
+  private:
+    DigitalOut _s0;
+    DigitalOut _s1;
+    DigitalOut _s2;
+    DigitalOut _s3;
+    DigitalIn _s_in;
+    Timer timer;
+    long pulsewidth();
+
+};
+#endif
\ No newline at end of file