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.
Revision 0:38dbd24805dd, committed 2021-09-03
- Comitter:
- CCastrop1012
- Date:
- Fri Sep 03 05:18:41 2021 +0000
- Commit message:
- Programa finalizado y funcional.
Changed in this revision
--- /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