Este programa sirve para configurar un PID y un RTC desde una aplicación en android

Dependencies:   mbed TextLCD

main.cpp

Committer:
nmirandal
Date:
2019-04-19
Revision:
2:ecd33165145b
Parent:
1:8596494b7d9d

File content as of revision 2:ecd33165145b:

/***************


ESTE PROGRAMA PUEDE SER USADO PARA CONFIGURAR UN RELOJ DE TIEMPO REAL DS3231 O 
PARA COFIGURAR UN CONTROL PID PARA UN CIRCUITO RCRC CONECTADO EN EL PIN PTE30.
EL PROGRAMA FUE DISEÑADO PARA APERAR CON UNA APLICACIÓN DE ANDROID CREADA EN
APP INVENTOR QUE PUEDE CONECTARSE CON LA TARJETA FRDM-KL25Z A TRAVÉZ DE UN 
MÓDULO DE BLUETOOTH CONECTADO EN EL PUERTO SERIAL UART2. CUANDO EL CELILAR SE 
CONECTA PARA CONFIGURAR EL CONTROL PID, LA TARJETA ENVÍA LAS MEDIDAS DEL VOLTAJE
DE SALIDA DEL CIRCUITO. TANTO EN EL MODO RTC COMO EN EL MODO PID, LOS DATOS
SE MUESTRAN EN UNA PANTALLA LDC.

NEFER MIRANDA LLORENTE
PROGRAMA DE INGENIERÍA DE CONTROL
UNIVERSIDAD NACIONAL DE COLOMBIA - SEDE MEDELLÍN


***************/




#include "mbed.h"
#include <stdio.h>
#include "ds3231_RTC.h"
#include "TextLCD.h"

Serial master(USBTX,USBRX);// Tx, Rx Computador
Serial GSM(PTE22,PTE23);// Tx, Rx Módulo de bluetooth
Ds3231 rtc(A4, A5); // puerto I2C1 de la frdm-kl25z


int vo, hb, lb;
int  P, I, D,S,AAAA=2000,MM,DD,wd=1,HH,mm,ss,mode,am_pm;
float p,i,d,s,q0,q1,q2,e,e_1,e_2,u,u_1;
char command[16], control='F';
float Kp=12.0, Ki=5.0, Kd=0.02, sp=2.0/3.3, T=0.02;
bool PID,CLK;
uint8_t vo_lb, vo_hb, j, aa;
uint16_t rtn_val;
char chain[40], character;

ds3231_time_t hora = {HH,mm,ss=45,am_pm,mode};//{horas,minutos,segundos,AM/PM,12/24H}
ds3231_calendar_t fecha= {AAAA,MM,DD,wd};//{años,mes,días,dia de semana}


AnalogIn input(PTB1); // puerto para medir el voltaje del circuito
AnalogOut  u_control(PTE30);// puerto a través del cual se aplica una entrada al circuito
DigitalOut LedVerde(LED2); // led indicador de estado del circuito

TextLCD lcd(PTE5, PTE4, PTE3, PTE2, PTB11, PTB10); // conexión ldc (rs, e, d4-d7)

Timer k,t,rtc_t;

//## Esta rutina lee una cadena de caracteres disponible en el puerto serial GSM ######
void get_chain()
{
    j=0;
    k.start();
    while(1) {


        if(GSM.readable()) {
            character=GSM.getc();
            chain[j]=character;

            j++;
        }
        if(k.read()>.2) {
            k.stop();
            k.reset();
            break;
        }
    }
}

//###### Esta función limpia la variable chain ########
void reset_var()
{
    for (int i=0; i<sizeof(chain); i++) {
        chain[i]='\0';
    }
}


//#### Esta función configura el reloj de tiempo real cuando se recibe un nuevo
//#### dato de fecha y hora a través de bluetooth###

void set_rtc()
{
    ds3231_time_t hora = {HH, mm, ss, am_pm, 1};
    ds3231_calendar_t fecha= {AAAA%100,MM,DD,wd};

    if(!rtc.set_calendar(fecha)) { // se ejcuta si la configuración de la fecha es exitosa
    // se imprime en la terminal del pc la fecha y hora a la cual se configuró el RTC

        master.printf("\r\n\r\n         Reloj Configurado el %d / %d / %d ",DD,MM,AAAA);

        if(!rtc.set_time(hora)) { // se ejcuta si la configuración de la hora es exitosa
            if(hora.am_pm)master.printf("a las %d:%d:%d PM\r\n\r\n\r\n",HH,mm,ss);
            else master.printf("a las %d:%d:%d AM\r\n\r\n\r\n",HH,mm,ss);
        }
    }

}


/* La función request() se encarga de interpretar el dato que se ha recibido 
a través del puerto serial GSM, este puede tener la función de configurar el
modulo RTC, configurar un control PID, activar o desactivar la señal de entrada
del circuito RCRC, o notificar si el celular se ha conectado o desconectado a 
través de bluetooth.

*/
void request()
{
    lcd.cls();
    if(chain[0]=='R') {
        control='N';



    } else if (chain[0]=='S') {
        control='F';



    } else if (chain[0]=='P') {
        sscanf (chain,"%*s %d%f%*s %d%f%*s %d%f%*s %d%f",&P,&p,&I,&i,&D,&d,&S,&s);
        master.printf ("P= %d\r\np= %f\r\nI= %d\r\ni= %f\r\nD= %d\r\nd= %f\r\nS= %d\r\ns= %f\r\n",P,p,I,i,D,d,S,s);
        Kp=P+p;
        Ki=I+i;
        Kd=D+d;
        sp=(S+s)/3.3;
        master.printf ("Kp= %f\r\nKi= %f\r\nKd= %f\r\nsp= %f\r\n",Kp,Ki,Kd,3.3*sp);



    } else if (chain[0]=='A') {
        sscanf (chain,"%*s %d%*s %d%*s %d%*s %d%*s %d",&AAAA,&MM,&DD,&HH,&mm);
        master.printf ("AAAA= %d\r\nMM= %d\r\nDD= %d\r\nHH= %d\r\nmm= %d\r\n",AAAA,MM,DD,HH,mm);
        if(HH>12) {
            HH=HH-12;
            am_pm=1;
        } else {
            if(HH==0)HH=12;
            am_pm=0;
        }

        set_rtc();

    } else if (chain[0]=='K') {
        CLK=1;

    } else if (chain[0]=='J') {
        PID=!PID;

    } else if (chain[0]=='k') {
        CLK=0;
        lcd.locate(0,0);
        lcd.printf("No device is");
        lcd.locate(0,1);
        lcd.printf("connected!");
    } else if (chain[0]=='j') {
        PID=0;
        lcd.locate(0,0);
        lcd.printf("No device is");
        lcd.locate(0,1);
        lcd.printf("connected!");
    }
}

/*
Esta función es una ISR para recibir datos a través del puerto serial GSM

*/

void in_data()
{
    get_chain();
    master.printf("\r\n%s\r\n",chain);
    request();
    reset_var();
}













int main(void)
{

    GSM.baud(9600);
    GSM.format(8,Serial::None,1);
    LedVerde=1.0;

    t.start();
    rtc_t.start();

    GSM.attach(&in_data, Serial::RxIrq);
    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("Welcome!");
    lcd.locate(0,1);
    lcd.printf("RTC & PID");
    while(1) {


        vo = input.read_u16();// medición del voltaje de salida del circuito RCRC
        vo_hb=vo/256;       
        vo_lb=vo-vo_hb*256;    
        GSM.putc(vo_hb);
        GSM.putc(vo_hb);   // envío de los datos al celular por bluetooth

        if(t.read()>T && PID) { // PID indica que el celular se ha conectado por bluetooth
                                // en la pantalla de configuración del PID.
            if(control=='N') { // si se recibió el comando para activar la acción de control, se ejecuta esta parte.
                e=sp-1.0*input;

                q0=Kp+Ki*T/2.0+Kd/T;
                q1=-Kp+Ki*T/2.0-2.0*Kd/T;
                q2=Kd/T;

                u=u_1+q0*e+q1*e_1+q2*e_2;

                u_1=u;
                e_1=e;
                e_2=e_1;


                if(u>1.0)u=1.0;
                else if(u<0.0)u=0.0;
                LedVerde=0.0;
            } else {
                u=0.0;
                LedVerde=1.0;
            }

            u_control=u;
            t.stop();
            t.reset();
            t.start();

        } else if (t.read()>T && !PID) {
            u=0.0;
            LedVerde=1.0;
        }// end for  if(t.read()>T && PID)



        if(rtc_t.read()>=1.0 && CLK) {// se muestra la fecha y hora en el lcd se recibió el comando para leer el tiempo desde el RTC

            rtc.get_calendar(&fecha);
            rtc.get_time(&hora);
            if(aa==99 && fecha.year==0) {
                AAAA++;
                lcd.cls();
            }
            aa=fecha.year;
            if(hora.seconds==0)lcd.cls();
            if(hora.am_pm) {
                master.printf("HORA: %d:%d:%d PM  ",hora.hours,hora.minutes,hora.seconds);
                lcd.locate(14,0);
                lcd.printf("PM");
            } else {
                master.printf("HORA: %d:%d:%d AM    ",hora.hours,hora.minutes,hora.seconds);
                lcd.locate(14,0);
                lcd.printf("AM");
            }
            lcd.locate(0,0);
            lcd.printf("HORA %d:%d:%d",hora.hours,hora.minutes,hora.seconds);
            master.printf("FECHA %d / %d / %d \r\n",fecha.date,fecha.month,AAAA);
            lcd.locate(0,1);
            lcd.printf("FECHA %d/%d/%d",fecha.date,fecha.month,AAAA);


            rtc_t.stop();
            rtc_t.reset();
            rtc_t.start();


        } else if (rtc_t.read()>=0.1 && PID) { // se muestra el voltaje medido y el setpoint en el lcd si se recibió el comando de PID

            lcd.locate(0,0);
            lcd.printf("Voltaje: %.2f V",3.3*input.read());
            lcd.locate(0,1);
            lcd.printf("Set_point: %.2f V",3.3*sp);
            rtc_t.stop();
            rtc_t.reset();
            rtc_t.start();
        } else if(rtc_t.read()>=1.0 && !PID && !CLK) { // si no se recibió ningún comando, no se hace nada.
            
        }//end for if(rtc_t.read()>=1.0)




    }//end for while(1)
}//end for void main()