RODRIGUEZ STINA OROPEZA 6ºA

Dependencies:   mbed tsi_sensor DHT11

main.cpp

Committer:
matirodriguez
Date:
2019-06-12
Revision:
0:374ae6cd7a56

File content as of revision 0:374ae6cd7a56:

#include "mbed.h"
#include "tsi_sensor.h"
#include "Dht11.h"

#define ELEC0 9
#define ELEC1 10

enum {RESET,    // Funcion enum que uso para establecer los estados de la maquina de estados como una palabra
      LAZO_ABIERTO,
      LAZO_CERRADO
     };
enum { NADA,    // Funcion enum que uso para establecer los estados de la maquina de estados como una palabra
       PULSADO
     };

// Prototipos de funciones

void MAQ_cooler();  // Maquina de estados que maneja al cooler en sus modos de funcionamiento

void set_motor();   // Funcion que cada 1 segundo cambia el valor del PWM del motor, para no hacerlo a la velocidad del clock en el main

void interrupcion();    // Funcion que se realiza cada vez que el pin establecido tenga un flanco. Usado para calcular los RPM

void rpm_segundos();    // Funcion que multiplicará las revoluciones por segundo para obtener las RPM

void MAQ_lecturaTSI();  //Prototipo funcion para solo leer 1 vez que se presiona el TSI

void LEER_TSI();    //Prototipo funcion para guardar el valor analogico del TSI en todo momento

void pulsacion_TSI();   //Prototipo funcion para leer 1 solo valor del TSI cada 2.5mseg

void medir_temperatura();   // Funcion para leer el sensor de temperatura, en el tiempo especificado en datasheet


// Configuracion de puertos

TSIAnalogSlider tsi(ELEC0, ELEC1, 40);  // TSI

InterruptIn velocidad(PTA13);   // Sensor de rpm

PwmOut cooler(PTB3);    // Base del transistor que maneja el cooler

AnalogIn pote(PTB0);    // Potenciometro

Dht11 sensor(PTD4); // Sensor DHT11 (libreria)

DigitalOut ledrojo(LED_RED);    // Led rojo de la placa MBED

DigitalOut ledverde(LED_GREEN); // Led verde de la placa MBED


// Variables globales

int auxiliar_rpm;   // Variable que almacena las revoluciones por segundo
int rpm;    // Variable que guarda los rpm para medirlos periodicamente

int var_pulsacion = 25;     // Variable para contar los 2.5mseg de la funcion pulsacion_TSI()
int teclado = NADA;         // Variable que contiene el valor analogico del TSI en todo momento
int ingreso = NADA;         // Variable que contiene si se presionó el TSI, que se lee y luego se borra

int estado_maq_cooler = RESET;  // Estado de la maquina de estados que maneja el cooler
int estado_maq_tsi = NADA;  // Estado de la maquina de estados que maneja el TSI

int auxiliar_temperatura;   // Variable que contiene el ultimo valor de temperatura que se midio
float auxiliar_velocidad;   // Variable que contiene el numero float (de 0 a 1) para ingresar en el PWM del cooler


// Tickers

Ticker lectura; // Ticker lectura del TSI
Ticker pulsacion;   // Ticker para usar la funcion pulsacion_TSI()
Ticker segundo; // Ticker para contar los RPM a partir de las revoluciones por segundo
Ticker pwm_cooler;  // Ticker para escribir en la salida PWM cada cierto tiempo
Ticker medir;   // Ticker para medir la temperatura

int main(void)
{
    medir_temperatura();    // Mido la temperatura así tengo un valor inicial

    // Junto los ticker con la funcion que deseo usar con él
    lectura.attach(&LEER_TSI,0.1);
    pulsacion.attach(&pulsacion_TSI,0.001);
    segundo.attach(&rpm_segundos,1);
    pwm_cooler.attach(&set_motor,0.3);
    medir.attach(&medir_temperatura,2);

    // Digo que funcion se realiza cuando el pininterrupt se activa
    velocidad.rise(&interrupcion);

    while (true) {

        // LLamo constantemente a las funciones de las maquinas de estados
        MAQ_lecturaTSI();
        MAQ_cooler();


    }
}

void medir_temperatura()
{
    sensor.read();  // Actualizo el valor de temperatura del sensor
    auxiliar_temperatura = sensor.getCelsius(); // Guardo el valor de temperatura en la variable correspondiente
}

void MAQ_cooler()
{
    int revoluciones;   // Variable que usaré para calcular los RPM a partir del valor del PWM


    switch(estado_maq_cooler) {

        case RESET: // No empiezo en ningun modo asi no se consume corriente recien prendo el micro
            if(ingreso == PULSADO) {    // Si se tocó el pulsador:
                ingreso=NADA;   // Limpio la variable
                estado_maq_cooler = LAZO_ABIERTO;   // Cambio de estado
            }
            break;
        case LAZO_ABIERTO:

            auxiliar_velocidad = pote + 0.065;  // El valor del PWM será el valor del pote, sumado al valor minimo para que prenda
            //                                      el cooler. No uso 200 RPM porque el ventilador no enciende de esa forma.

            // Corrigo el valor que hay en la salida si se detecta que bajaron los RPM
            if(rpm < (auxiliar_velocidad * 8000)) {
                auxiliar_velocidad=auxiliar_velocidad+0.1;
            } else {
                auxiliar_velocidad=auxiliar_velocidad-0.005;
            }

            if(auxiliar_velocidad>(float)1) {
                auxiliar_velocidad=(float)1;
            }

            // Transicion de la maquina de estados
            if(ingreso == PULSADO) {
                ingreso=NADA;
                estado_maq_cooler = LAZO_CERRADO;
            }

            break;

        case LAZO_CERRADO:

            revoluciones = (auxiliar_temperatura * 8000) / 45;  // Regla de 3 para calcular las revoluciones por minuto
            //                                                      que corresponden para la temperatura medida


            if(auxiliar_temperatura<20) {  // Cuando la temperatura es mas baja que 20, seteo en el valor minimo del ventilador
                auxiliar_velocidad = 0.065;

                // Corrigo el valor que hay en la salida si se detecta que bajaron los RPM
                if(rpm < (auxiliar_velocidad * 8000)) {
                    auxiliar_velocidad=auxiliar_velocidad+0.05;
                } else {
                    auxiliar_velocidad=auxiliar_velocidad-0.005;
                }
            }


            if((auxiliar_temperatura>=20)&&(auxiliar_temperatura<45)) { // Dentro de este rango de temperatura, las RPM estan dadas
                //                                                              por una regla de 3 simple
                auxiliar_velocidad = (revoluciones * 1) / (float)8000;

                // Corrigo el valor que hay en la salida si se detecta que bajaron los RPM
                if(rpm < (auxiliar_velocidad * 8000)) {
                    auxiliar_velocidad=auxiliar_velocidad+0.075;
                } else {
                    auxiliar_velocidad=auxiliar_velocidad-0.0005;
                }

                if(auxiliar_velocidad>(float)1) {
                    auxiliar_velocidad=(float)1;
                }

            }

            if(auxiliar_temperatura >= 45) { // Si la temperatura es mas alta que la maxima, el cooler se encuentra al maximo de potencia
                auxiliar_velocidad = 1;
            }

            // Transicion de la maquina de estados
            if(ingreso == PULSADO) {
                ingreso=NADA;
                estado_maq_cooler = LAZO_ABIERTO;
            }
            break;
    }
}

void interrupcion()
{
    auxiliar_rpm++; // Valor para calcular los RPM, contiene las revoluciones por segundo que luego se multiplicarán por 60
}

void rpm_segundos()
{

    rpm = auxiliar_rpm * 60;    // Las RPM son igual a las revoluciones por segundo * 60 segundos

    auxiliar_rpm = 0;   // Reseteo la variable para una nueva medicion

// Imprimo en pantalla el valor actual de RPM, la temperatura actual y el modo en el que se está trabajando. Este mismo
// depende del estado de la maquina de estados, asi que aplico ese metodo para imprimir en pantalla. Tambien, prendo un
// led distinto para cada modo de trabajo.

    printf("RPM: %i , ",rpm);
    printf("T: %i\n",auxiliar_temperatura);

    switch(estado_maq_cooler) {
        case LAZO_ABIERTO:
            printf("Lazo abierto\n");
            ledverde = 0;
            ledrojo = 1;
            break;
        case LAZO_CERRADO:
            printf("Lazo cerrado\n");
            ledverde = 1;
            ledrojo = 0;
            break;
    }

}

void set_motor()
{
    // Seteo en la salida PWM el valor que corresponde, que ya se guardó en la maquina de estados
    cooler.period(0.5f);
    cooler.write(auxiliar_velocidad);
    
}

void LEER_TSI()
{
    float auxiliar = 0;
    auxiliar = tsi.readPercentage();    //Guardo de manera auxiliar el valor entre 0 y 1 del TSI

// Asocio el valor del tsi numerico con un color, dividiendo en 4 valores posibles (0, <0.33, <0.66, <1)
    if(auxiliar >= 0) {
        teclado = NADA;
    }
    if((auxiliar > 0.05)&&(auxiliar <= 1)) {
        teclado = PULSADO;
    }
}

void pulsacion_TSI()
{
    if(var_pulsacion > 0) {
        var_pulsacion--;
    }
}

void MAQ_lecturaTSI()
{
    if(var_pulsacion < 1) { // Si se llegaron a los 2.5ms:

        var_pulsacion = 25; // Vuelvo a establecer 2.5ms para el proximo ciclo

        switch(estado_maq_tsi) {
            case NADA:
                ingreso = NADA; // La variable ingreso, salvo en el caso especifico, siempre se encontrará en NADA

                if(teclado==PULSADO) {
                    estado_maq_tsi = PULSADO;
                    ingreso = PULSADO;  // El valor del TSI lo cambio en la transicion entre estados para asegurarme que solo se pueda leer 1 vez
                }
                break;

            case PULSADO:
                if(teclado == NADA) {
                    estado_maq_tsi = NADA;
                }
                break;
        }
    }
}