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