Version Final

Dependencies:   mbed DS1820

Revision:
5:f12c0d64518f
Parent:
3:f483abe4bc57
Child:
6:75b0f24dad9b
--- a/main.cpp	Fri Jan 13 18:30:37 2017 +0000
+++ b/main.cpp	Wed Jun 05 01:27:43 2019 +0000
@@ -1,49 +1,645 @@
-#define MULTIPLE_PROBES
-#define DATA_PIN        A0
+/*
+FERNANDEZ-CLERICI
+EJER01 - TP01
 
+PTB0 -- Habilitacion Cooler
+PTB1 -- DS18B20 (Data) (4K7 PullUp)
+D3   -- Sensor Efecto de Hall          --> PullUp 4k7
+PTB3 -- Pulsador                       --> 0 = Nada || 1 = Pulsado
+PTC2 -- Preset
+A3   -- Pin Para Probar que el programa no retiene
 
-#ifdef MULTIPLE_PROBES
+*/
 
+/*Librerias*/
 #include "mbed.h"
 #include "DS1820.h"
 
-#define MAX_PROBES      16
- 
-DS1820* probe[MAX_PROBES];
- 
-int main() {  
-    // Initialize the probe array to DS1820 objects
-    int num_devices = 0;
-    while(DS1820::unassignedProbe(DATA_PIN)) {
-        probe[num_devices] = new DS1820(DATA_PIN);
-        num_devices++;
-        if (num_devices == MAX_PROBES)
+
+/*Definicion Pines*/
+#define EN_COOLER          PTB0
+#define DS18B20_PIN        PTB1
+#define VELOCIDAD          D3
+#define PULSADOR           A5
+#define PRESET             PTC2
+
+/*Definicion de Elementos*/
+DS1820 probe(DS18B20_PIN);
+
+DigitalOut Rojo(LED1);
+DigitalOut Verde(LED2);
+DigitalOut Azul(LED3);
+
+DigitalOut RET(A3);
+
+PwmOut      Cooler(EN_COOLER);
+InterruptIn velocidad(VELOCIDAD);
+AnalogIn    Preset(PRESET);
+DigitalIn   P(PULSADOR);
+
+
+/*MAQUINA DE ESTADOS CENTRAL*/
+
+#define InicioSistema 0
+#define LazoAbierto 1
+#define LazoCerrado 2
+#define VelocidadMaxima 3
+
+/*Variables maquina de estado lazos*/
+int Modo = 0; //Me avisa en que modo estoy : Lazo Abierto , Lazo Cerrado, Inicio Sistema y Velocidad maxima
+int ta   = 0; //Acumulador de tiempo del Inicio Sistema
+void medicion_velocidad(void);
+int VMAX = 0; //Velocidad maxima del Cooler
+
+
+/*MAQUINA DE ESTADOS ANTI REBOTE*/
+
+#define INICIO_P 0
+#define RISING_P 1
+#define RETENCION_P 2
+
+bool antirrebote(bool lectura);
+int estado = 0;//Variable que guaarda el estado de la maquina de estados
+int tp     = 0;//Acumulador de tiempo de la maquina
+void CambioDeModo(); //Funcion que me sirve para switchear entre los dos modos
+
+
+/*MAQUINA DE ESTADOS MEDICION VELOCIDAD*/
+
+#define INCIO_V 0
+#define RISE_1 1
+#define FALL_1 2
+#define ESPERA_V 3
+
+//Interrupciones de deteccion de cambios en pin de medicion de valocidad
+void R_ton(); //Funcion relacionada a la interrupcion de deteccion de flancos ascendentes
+void F_ton();    //Funcion relacionada a la interrupcion de deteccion de flancos descendentes
+
+//Flags medicion de ancho de pulso
+bool em = 0;      //Estoy midiendo
+bool tmv = 0;     //Termine de medir
+int tv = 0;       //Acumulacion de tiempo maquina control velocidad
+int EMV = 0;      //Guardar estado medicion de velocidad
+float RPM = 0;    //Guardo la velocidad
+
+
+
+/*MAQUINA DE ESTADOS CAMBIO DE DUTY (LAZO ABIERTO)*/
+
+#define INICIO_CM 0
+#define CAMBIO_MAYOR 1
+#define CAMBIO_MENOR 2
+#define INICIO_CAMBIO_MENOR 5
+#define ESPERA_DECREMENTO 3
+#define ESPERA_FINAL      4
+
+int tcd = 0;     //Acumulador de tiempo
+int ECM = 0;     //Guardo el estado de la maquina
+float cantv = 0; //Cantidad de veces que debo modificar el duty (funciona como entero)
+char jv = 0;     //Cantidad de veces que modifique el duty
+float D = 1.00f; //Duty Actual
+float DAN = 0.5f;//Duty Anterior
+
+void cambio_duty_pwm(float nuevoDuty); //Funcion que engloa la maquina
+
+
+/*MAQUINA DE ESTADOS LAZO CERRADO (DUTY EN FUNCION DE TEMPERATURA)*/
+
+#define INCIO_LAZOCERRADO 0
+#define MEDICION_TEMPERATURA 1
+#define MEDICION_RPM 2
+#define CAMBIO_PWM 3
+#define ESPERA_CAMBIOS_PWM 4
+#define ESPERA_ENTRE_MODIFICACIONES 5
+
+void control_PWM_Temp(void); //Funcion que engloba la maquina de estados
+
+int CPT = 0;    //Guardo el estado de la maquina
+int IM = 0;     //Acumulador de tiempo base
+float duty = 0; //Guardo el duty actual
+
+/*SubMaquina utilizada para modificar el duty*/
+int   FTR  = 0;     //Control de estados de la submaquina
+bool  tdm = 0;      //Flag que me notifica cuando termine de cambiar el duty..
+
+float NuevoDuty = 0;                //Duty que voy enviando a forma de prueba y error..
+
+/*VALORES DE CONFIGURACION LAZO CERRADO*/
+#define DEFINICION_CAMBIO_PWM 0.02f //Resolucion de barrido, valores altos agilizan el cambio pero pueden hacer que nunca se alcance lo pedido..
+#define MinRPM 500.0f               //Minima velocidad establecida por el Cooler
+#define ToleranciaRPM 100.0f        //Tolerancia de calculos en torno a la velocidad (Cuanto me puedo desviar de la regla de tres simple y considerarlo verdadero)
+
+/*RELACION DE REVOLUCIONES POR MINUTO EN FUNCION DE LA TEMPERATURA*/
+/*
+                    20ºC ==> 500rpm
+                    x ºC ==> x  rpm
+*/
+
+void cambio_gradual_duty(float obj);//Funcion que engloba la maquina de modificacion del duty , en especial la zona que no puedo enviar directamente..
+
+int ty = 0;                         //Acumulador de tiempo
+
+
+/*ELEMENTOS GENERALES DEL SISTEMA*/
+void leds(int num);
+/*Tickers*/
+Ticker TiempoBase;
+Ticker TiempoRapido;
+void base_de_tiempo();
+void tiempo_rapido();
+/*Timmers*/
+Timer ap;
+
+int main()
+{
+    /*Apago Todos los LEDS*/
+    leds(0);
+    printf("TRABAJO PRACTICO 1 : MAQUINAS DE ESTADO\r\n EJERCICIO 1\r\n ALUMNOS: FERNANDEZ SANZ Y CLERICI \r\n INICIANDO.............\r\n");
+    /*Attach Timmers*/
+    TiempoBase.attach(&base_de_tiempo, 0.5f);
+    TiempoRapido.attach(&tiempo_rapido, 0.05f);
+    /*Inicio PWM*/
+    Cooler.period(0.01f);   //Establezco un periodo de 100mS para el PWM
+
+    while(1) {
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        /*Maquina de Estados Central del Sistema*/
+        switch(Modo) {
+
+            //La primera vez arranco el motor al maximo y inicializo la medicion de velocidad..
+            case InicioSistema:
+                Cooler.write(1);
+                //Espero un tiempo para q arranque el motor
+                if(ta > 5) {
+                    ta = 0;
+                    /*Attach Pin Interrupt del medidor de velocidad*/
+                    velocidad.rise(&R_ton);
+                    velocidad.fall(&F_ton);
+                    printf("Termine de incializar....\r\n");
+                    Modo = VelocidadMaxima;
+                }
+
+                break;
+
+            //Mido la velocidad maxima del Cooler.. Lo setie al meximo en "InicioSistema"
+            case VelocidadMaxima:
+                medicion_velocidad();
+                break;
+
+            //Mido el Preset y seteo el duty del Cooler en funcion de la lectura
+            case  LazoAbierto:
+                float lec = Preset;
+                cambio_duty_pwm(lec);
+                break;
+
+            //Mido la temperatura y establezco la velocidad del Cooler
+            case  LazoCerrado:
+                control_PWM_Temp();
+                break;
+        }
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+        //Actualizo el pulsador...
+        CambioDeModo();
+        
+        RET = !RET; //Cambio el estado del pin de verificacion..
+
+    }
+}
+
+//Funcion utilizada para controlar los Leds On Board
+//IN ==> Combinacion Binaria de estados || OUT ==> Actualizacion estado de leds
+
+void leds(int num)
+{
+    switch(num) {
+        case 0:
+            Rojo = 1;
+            Verde = 1;
+            Azul = 1;
+            break;
+        case 4:
+            Rojo = 0;
+            Verde = 1;
+            Azul = 1;
+            break;
+        case 2:
+            Rojo = 1;
+            Verde = 0;
+            Azul = 1;
+            break;
+        case 1:
+            Rojo = 1;
+            Verde = 1;
+            Azul = 0;
+            break;
+        case 7:
+            Rojo = 0;
+            Verde = 0;
+            Azul = 0;
             break;
     }
-    
-    printf("Found %d device(s)\r\n\n", num_devices);
-    while(1) {
-        probe[0]->convertTemperature(true, DS1820::all_devices);         //Start temperature conversion, wait until ready
-        for (int i = 0; i<num_devices; i++)
-            printf("Device %d returns %3.1foC\r\n", i, probe[i]->temperature());
-        printf("\r\n");
-        wait(1);
+}
+
+//Maquina de estados que elimina el Rebote de los pulsadores
+//IN ==> DigitalIn || OUT ==> Detector de flancos ascendentes del pulsador
+bool antirrebote(bool lectura)
+{
+    static bool lecant = 0;
+
+    switch(estado) {
+        case INICIO_P:
+            //Si tengo un flanco ascendente
+            if((lectura == 1) && (lecant == 0)) {
+                estado = RISING_P;
+            }
+            tp = 0;
+            break;
+        case RISING_P:
+            estado = RETENCION_P;
+            tp = 0;
+            return 1;
+        case RETENCION_P:
+            if((tp >= 2) && (lectura == 0)) {
+                estado = INICIO_P;
+            }
+            break;
     }
-    
+    lecant = lectura;
+    return 0;
+}
+
+//Funcion relacionada al timmer , es llamada cada 0.5 segundos
+void base_de_tiempo()
+{
+    tp ++; //Acumulador Antirebote
+    tv ++; //Acumulador Mediciond de velocidad
+    ta ++; //Acumulador Inicio del sistema..
+    IM++;  //Acumulador Lazo Cerrado
 }
 
-#else
-#include "mbed.h"
-#include "DS1820.h"
- 
-DS1820 probe(DATA_PIN);
- 
-int main() {
-    while(1) {
-        probe.convertTemperature(true, DS1820::all_devices);         //Start temperature conversion, wait until ready
-        printf("It is %3.1foC\r\n", probe.temperature());
-        wait(1);
+//Funcion del timmer dos, es llamada cada 0.05 segundos
+void tiempo_rapido()
+{
+    tcd ++;//Acumulador Cambio de Duty(Lazo Abierto)
+    ty ++; //Acumulador Cambio de Duty(Lazo Cerrado)
+}
+
+//Funcion dedicada a controlar el pulsador y analizar los cambios de modo..
+void CambioDeModo()
+{
+    if(antirrebote(P)) {
+        Modo ++;
+        if(Modo > 2) {
+            Modo = 1;
+            printf("Lazo Abierto!!\r\n");
+        }
+    }
+}
+
+//Inicio la medicion del tiempo de On del pulso
+void R_ton()
+{
+    switch(EMV) {
+        case INCIO_V:
+            ap.reset();
+            ap.start();
+            em = 1;
+            tmv = 0;
+            EMV = RISE_1;
+            break;
+
+        case RISE_1:
+            printf("ERROR MIDIENDO VELOCIDAD, EMV = %d!!\r\n", EMV);
+            break;
+
+        case FALL_1:
+            ap.stop();
+            tmv = 1;
+            em = 0;
+            tv = 0;
+            EMV = ESPERA_V;
+            break;
+
     }
 }
 
-#endif
\ No newline at end of file
+void F_ton()
+{
+    if(em) {
+        switch(EMV) {
+            case INCIO_V:
+                printf("ERROR MIDIENDO VELOCIDAD, EMV = %d!!\r\n", EMV);
+                break;
+            case RISE_1:
+                EMV = FALL_1;
+                break;
+            case FALL_1:
+                printf("ERROR MIDIENDO VELOCIDAD, EMV = %d!!\r\n", EMV);
+                break;
+        }
+    }
+
+}
+
+void cambio_duty_pwm(float nuevoDuty)
+{
+    static float ND = 0;
+
+    switch(ECM) {
+        case INICIO_CM:
+
+            ND = nuevoDuty;
+            Azul = 1;               //Apago el indicador de LazoCerrado
+
+            //Me fijo si estoy por poner mas o menos el mismo duty para evitar el proceso
+            if(abs(ND * 100.00f - DAN * 100.00f ) < 2) {
+                //printf("El duty es el mismo del ciclo previo...\r\n");
+                tcd = 0;
+                ECM = ESPERA_FINAL;
+                break;
+            }
+
+            printf("Inicio el cambio de duty....\r\n");
+            Rojo = 0;
+            tcd = 0;
+            if(ND < 0.07f) {
+                Cooler.write(0);
+                duty = 0;
+                printf("Cooler APAGADO!\r\n");
+                tcd = 0;
+                DAN = 0.5f;
+                ECM = ESPERA_FINAL;
+                Rojo = 1;
+                break;
+            }
+            if(ND >= 0.5f) {
+                ECM = CAMBIO_MAYOR;
+            } else
+                ECM = INICIO_CAMBIO_MENOR;
+            break;
+        case CAMBIO_MAYOR:
+            Cooler.write(ND);
+            printf("\tNuevo Duty = %f%\r\n", ND* 100);
+            DAN = ND;
+            tcd = 0;
+            ECM = ESPERA_FINAL;
+            break;
+        case INICIO_CAMBIO_MENOR:
+            cantv = abs( (int(DAN*100)) - (int(ND*100)));
+            printf("\tVoy a hacer %.0f pasos intermedios desde %.0f para llegar a %.0f%\r\n", cantv, DAN*100, ND * 100);
+            ECM = CAMBIO_MENOR;
+            jv = 0;
+            D = DAN;
+            break;
+        case CAMBIO_MENOR:
+            if(cantv >= jv) {
+                Cooler.write(D);
+                printf("\t\tEtapa intermedia en %.0f%\r\n", D * 100.00f);
+                /*Si quiero alcanzar un duty inferior*/
+                if(ND < DAN)
+                    D -= 0.01f;                                             //Decremeto 1%
+                /*Si quiero alcanzar un duty superior*/
+                if(ND > DAN)
+                    D += 0.01f;                                             //Incremento 1%
+                tcd = 0;
+                ECM = ESPERA_DECREMENTO;
+                jv++;
+                break;
+            } else {
+                tcd = 0;
+                ECM = ESPERA_FINAL;
+                printf("\t\tNuevo Duty = %.0f\r\n", floor(ND*100.00f));
+                DAN = ND;
+            }
+            break;
+        case ESPERA_DECREMENTO:
+            if(tcd >= 2) {
+                ECM = CAMBIO_MENOR;
+                tcd = 0;
+            }
+            break;
+        case ESPERA_FINAL:
+            Rojo = 1;
+            if(tcd >= 100) {
+                ECM = INICIO_CM;
+                tcd = 0;
+            }
+            break;
+    }
+
+}
+
+//Maquina LazoCerrado
+void control_PWM_Temp(void)
+{
+    static float temperatura = 0;
+    float val = 0;
+    switch(CPT) {
+        case INCIO_LAZOCERRADO:
+            ECM = 0; //Reincio la maquina de cambio de duty de lazo abierto..
+            Rojo = 1;//Apago el Led rojo..
+            Azul = 0;//Prendo el Led azuil...
+            /*Fijo el duty en 50%*/
+            Cooler.write(0.5f);
+            duty = 0.5f;
+            printf("Lazo Cerrado!!\r\n");
+            CPT = MEDICION_TEMPERATURA;
+            break;
+
+        case MEDICION_TEMPERATURA:
+            probe.convertTemperature(false, DS1820::all_devices);
+            temperatura = probe.temperature();
+            printf("La temperatura es de %3.1foC\r\n",temperatura );
+            /*Reinicio la medicion de RPM*/
+            CPT = MEDICION_RPM;
+            tv = 0;
+            EMV = INCIO_V;  //Pongo en el estado inicial la maquina de medicion de velocidad
+            IM = 0; //Pongo en cero el acumulador para darle un TimeOut a la medicion de velocidad
+            break;
+
+        case MEDICION_RPM:
+            /*Si termine de medir la velocidad...*/
+            if(EMV == ESPERA_V) {
+                if(tv >= 1) {
+                    RPM = 60.00 / (ap.read() * 2);
+                    printf("Velocidad = %f RPM\r\n",RPM);
+                    tv = 0;
+                    EMV = INCIO_V;
+
+                    val = floor(temperatura * MinRPM / 20);
+                    printf("Deberia tener %f RPM y tengo %f RPM\r\n", val, RPM);
+
+                    /*Aca me fijo si debo modificar el duty*/
+                    if(abs(RPM - val) > ToleranciaRPM) {
+
+                        /*Miro que duty debo enviar...*/
+                        if(val < RPM)
+                            NuevoDuty = duty - DEFINICION_CAMBIO_PWM;
+                        if(val > RPM)
+                            NuevoDuty = duty + DEFINICION_CAMBIO_PWM;
+
+                        IM = 0;
+                        CPT = CAMBIO_PWM;
+                        break;
+                    } else {
+                        printf("EL duty es correcto! Estoy en %0.1f% :D\r\n", floor(duty * 100.0f));
+                        IM = 0;
+                        CPT = ESPERA_ENTRE_MODIFICACIONES;
+                        break;
+
+                    }
+
+                }
+            }
+            /*Verifico que no se me apago el motor...*/
+            if(IM > 10) {
+                printf("El cooler estaba apagadoo!!..Reiniciando Lazo cerrado..\r\n");
+                EMV = INCIO_LAZOCERRADO;
+                IM = 0;
+            }
+
+            break;
+
+        case CAMBIO_PWM:
+            cambio_gradual_duty(NuevoDuty);
+            /*Si termine de modificar el duty*/
+            if(tdm) {
+                IM = 0;
+                CPT = ESPERA_CAMBIOS_PWM;
+            }
+            break;
+
+        case ESPERA_CAMBIOS_PWM:
+            /*Si se cumplio un tiempo prudencial.. El motor se debe adecuar a la nueva velocidad*/
+            if(IM >= 2) {
+                tdm = 0;            //Reinicio el flag de cambio de duty
+                EMV = 0;            //Reinico la maquina de medicion de velocidad..
+                IM  = 0;            //Reinicio el acumulador de tiempo
+                CPT = MEDICION_RPM; //Mido nuevamente la velocidad y me fijo si debo modificar denuevo
+                break;
+            }
+
+            break;
+
+        case ESPERA_ENTRE_MODIFICACIONES:
+            if(IM >= 1)
+                CPT = MEDICION_TEMPERATURA;
+            break;
+    }
+}
+
+//Maquina de cambio de duty gradual....
+
+void cambio_gradual_duty(float obj)
+{
+    static float dtf = 0;   //Variable que va a guardar durante todo el proceso el objetivo, es estatico... lo modifico en el estado inicial solamente..
+
+    switch(FTR) {
+        case INICIO_CM:
+            dtf = obj; //Fijo el nuevo objetivo...
+            tdm = 0;                //Aviso que estoy modificando el duty...
+            printf("Inicio el cambio de duty....\r\n");
+            Rojo = 0;
+
+            /*Si estoy por debajo del minimo del Cooler directamente lo apago...*/
+            if(dtf < 0.07f) {
+                /*Apago el PWM*/
+                Cooler.write(0);
+                duty = 0;
+                printf("Cooler APAGADO!\r\n");
+                /*Voy al final de la maquina*/
+                ty = 0;                 //Reinicio el acumulador de tiempo final...
+                FTR = ESPERA_FINAL;
+                Rojo = 1;
+                break;
+            }
+            if(dtf >= 0.5f) {
+                FTR = CAMBIO_MAYOR;
+            } else
+                FTR = INICIO_CAMBIO_MENOR;
+            break;
+
+        case CAMBIO_MAYOR:
+            Cooler.write(dtf);   //Coloco el nuevo valor en el PWM de una..
+            //printf("\tNuevo Duty = %f%\r\n", dtf * 100);
+            duty = dtf;         //Actualizo el duty actual..
+            ty = 0;             //Reinicio el acumulador de tiempo base
+            FTR = ESPERA_FINAL;
+            break;
+
+        case INICIO_CAMBIO_MENOR:
+            cantv = abs( (int(duty*100)) - (int(dtf*100))); //Me fijo cuantos pasos intermedios voy a dar...
+            //printf("\tVoy a hacer %.0f pasos intermedios desde %.0f para llegar a %.0f%\r\n", cantv, duty*100, dtf * 100);
+            D = duty;                                       //Parto desde el PWM actual
+            jv = 0;                                         //Reinico el acumulador de veces
+            FTR = CAMBIO_MENOR;
+            break;
+
+        case CAMBIO_MENOR:
+            /*La cantidad de pasos intermedios calculados en el estado anterior...*/
+            if(cantv >= jv) {
+                Cooler.write(D);                                            //Pongo el duty
+                //printf("\t\tEtapa intermedia en %.0f%\r\n", D * 100.00f);
+                /*Si quiero alcanzar un duty inferior*/
+                if(dtf < duty)
+                    D -= 0.01f;                                             //Decremeto 1%
+                /*Si quiero alcanzar un duty superior*/
+                if(dtf > duty)
+                    D += 0.01f;                                             //Incremento 1%
+
+                if(D < 0 || D > 1) {                                         //Si estoy en valores no logicos...
+                    //printf("Valores de duty no logicos... ERORR!!!! D:\r\n");
+                    FTR = INICIO_CM;
+                    break;
+                }
+
+                jv++;                                                       //Acumulo el paso realizo en la variable(Lo cuento)..
+                ty = 0;                                                     //Reinicio el acumulador de tiempo
+                FTR = ESPERA_DECREMENTO;                                    //Espero un tiempo para que se ajuste la salida..
+                break;
+            }
+            /*Si termine con las modificaciones de duty..*/
+            else {
+                //printf("\t\tNuevo Duty = %.0f\r\n", (D+0.01f)*100);
+                duty = dtf;                                                 //Guardo el nuevo valor de duty
+                ty = 0;                                                     //Reinicio el acumulador de tiempo base
+                FTR = ESPERA_FINAL;                                         //Paso a la espera final...
+            }
+            break;
+
+        case ESPERA_DECREMENTO:
+            /*Si se cumplio el tiempo*/
+            if(ty >= 1) {
+                ty = 0;            //Reinico el acumulador de tiempo
+                FTR = CAMBIO_MENOR;//Paso al nuevo paso
+            }
+            break;
+        case ESPERA_FINAL:
+            /*Termine el proceso de cambio de duty*/
+            Rojo = 1;             //Apago el led modificador..
+            tdm  = 1;             //Notifico a las otras maquinas de estado que termine de modificar el duty..
+            /*Si se cumplio el tiempo*/
+            if(ty >= 1) {
+                ty = 0;          //Reinicio el acumulador de tiempo
+                FTR = INICIO_CM; //Vuelvo al estado inicial del proceso..
+            }
+            break;
+    }
+}
+
+void medicion_velocidad(void)
+{
+    if(EMV == ESPERA_V) {
+        if(tv >= 1) {
+            RPM = 60.00 / (ap.read() * 2);
+            printf("Velocidad maxima = %f RPM\r\n",RPM);
+            VMAX = RPM;
+            tv = 0;
+            EMV = INCIO_V;
+            Modo = LazoAbierto;
+            printf("Modo Lazo Abierto...!\r\n");
+        }
+    }
+}
\ No newline at end of file