Código para el uso del Módulo RTC DS3231 (Pantalla LCD - ENCODER - IRDA) para establecer un sistema de Alarmas en tiempo real.

Dependencies:   mbed QEI ds3231 TextLCD Pulse1

main.cpp

Committer:
Giovani_Cardona
Date:
2019-08-13
Revision:
0:dc639ee44cab

File content as of revision 0:dc639ee44cab:

/*Práctica 4 - Procesadores 2019-1
   Giovani Cardona Sánchez
   Mateo Valencia Diaz
   Verónica Ríos Vargas
   Juan Esteban Rodriguez Oquendo 
   Juan Camilo Pérez Estrada
*/

#include "ds3231.h"
#include "TextLCD.h"
#include <Pulse1.h>
#include "QEI.h"

//--------------------------Puertos---------------------------------//
TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5, TextLCD::LCD20x4); // rs, e, d4-d7
Ds3231 rtc(PTE0, PTE1); //rtc object Ds3231::Ds3231(PinName sda, PinName scl) : I2C(sda, scl)
PulseInOut irda(PTD5);// en este puerto se pone el sensor infrarrojo
QEI wheel (PTD7, PTD6, NC, 624);
Serial pc(USBTX, USBRX);

DigitalOut ledR(LED_RED);                   // led rojo
DigitalOut ledG(LED_GREEN);                 // led verde
DigitalOut ledB(LED_BLUE);                  // led azul

DigitalOut Buzzer(PTD4);
InterruptIn button(PTA17);

//--------------------------Variables---------------------------------//

int day = 0, date = 0, month = 0, year = 0, hours = 0, minutes = 0, seconds = 0;
int modo = 0, pulsos = 0, x = 0, pos = 0, count = 0, n = 0, x_i = -1, f = 0;
int Alarmas[16][6];

//--------IRDA--------//
int header =0; //tiempo de cabecera pulso abajo
const int head_H = 11000; //+20% medida con osciloscopio en microsegundos
const int head_L = 4444 ;//-20%  medida con osciloscopio
int i=0;
const int T_alto=1670;//ponga su tiempo de la prueba
const int T_bajo=847;//ponga su tiempo de la prueba
const int num_bits = 32;//ponga su numero de bits
int num[num_bits];//cadena para almacenar todos los tiempos que conforman los bits de datos
int sec[num_bits];//cadena para almacenar la cadena codificada en binario
int boton1[]= {0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,1,0,0,0,1,0,0,0,0,1,1,1,0,1,1,0};
int boton2[]= {0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,1,0,0,1,0,0,0,1,0,1,1,0,1,1,0};
int boton3[]= {0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,1,1,0,1,1,0};
int boton4[]= {0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,1,1,0};
int boton5[]= {0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,1,0,1,0,1,0,0,0,0,1,0,1,0,1,1,0};
int boton6[]= {0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0};
int boton7[]= {0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0};
int boton8[]= {0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0};
int boton9[]= {0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0};
int boton0[]= {0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,0,0,0,1,0,0,0,1,1,1,1,0,1,1,0};
int OK[]    = {0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0};

int flag1,flag2,flag3,flag_OK; //Banderas de boton presionado
int dato; // tiempo de cada dato que se lee


//----------------------Funciones--------------------------------//
void get_user_input(char* message, uint8_t min, uint8_t max, uint32_t* member);
void get_user_input(char* message, uint8_t min, uint8_t max, bool* member);
void set_RTC(void);
void set_Alarm_encoder(void);
int set_Alarm_IRDA(void);
void print_Alarm(void);
int detect_number(void);
int sel_number(void);


//----------------------Interrupciones---------------------------//
void Button(void) {
    wait(0.1);
    if(button == 1){
        if(n == 0){
            ledG = !ledG; //Se va a ingresar una alarma por IRDA
            modo = 2;
            f = 0;
            count = 0;
        }
        if(modo == 0){
            pos = x;
            //ledR = !ledR;
            printf("\nInterrupcion- Alarma = %d",pos);
            modo = 1; //Cambio de alarma por encoder
            count = 0;
            x = 0;
        }
        else if(modo == 1){
            Alarmas[pos-1][count] = x;
            ledR = !ledR;
            wait(0.05);
            ledR = !ledR;
            count++;
            x = 0;
        }
    }
}


//----------------------Ciclo principal---------------------------//
int main(void)
{  
    //DS3231 rtc variables - default, use bit masks in ds3231.h for desired operation
    ds3231_cntl_stat_t rtc_control_status = {0,0}; 
    rtc.set_cntl_stat_reg(rtc_control_status);
    
    //******************************//
    ds3231_time_t time = {12, 0, 0, 0, 1}; 
    ds3231_calendar_t calendar = {1, 1, 1, 0}; 
    ledR = 1; ledB = 1; ledG = 1;//LEDs OFF
    
    //set_RTC(); //Configuración del RTC
    
    //******************************//
    
    while(1)
    {    
        rtc.get_time(&time); // NO se va a usar el modo (1 for 12hr 0 for 24hr) o (0 for AM 1 for PM)
        lcd.locate(0, 0);
        lcd.printf("Time %02d:%02d:%02d - RTC", time.hours, time.minutes, time.seconds);
        
        rtc.get_calendar(&calendar);
        lcd.locate(0, 1);
        lcd.printf("Calendar %02d/%02d/%02d",calendar.date, calendar.month, calendar.year);
        
        //-------Verificación Alarma encendido------//
        for (int i= 0; i<=7;i++){
            if((time.hours == Alarmas[i][0])&& (time.minutes == Alarmas[i][1]) && (time.seconds == Alarmas[i][2]) && (calendar.date == Alarmas[i][3]) && (calendar.month == Alarmas[i][4]) && (calendar.year == Alarmas[i][5])){
                ledB = 0;
                Buzzer = 1;
                lcd.locate(0, 3);
                lcd.printf(" Alarm %d activated", i+1);
                wait(0.5);
                Buzzer = 0;
                lcd.locate(0, 3);
                lcd.printf("                    ");
            }
        }
        //-------------------------//
        
        //-------Verificación Alarma apagado------//
        for (int i= 8; i<=15;i++){
            if((time.hours == Alarmas[i][0])&& (time.minutes == Alarmas[i][1]) && (time.seconds == Alarmas[i][2]) && (calendar.date == Alarmas[i][3]) && (calendar.month == Alarmas[i][4]) && (calendar.year == Alarmas[i][5])){
                ledB = 1;
                Buzzer = 1;
                lcd.locate(0, 3);
                lcd.printf("Alarm %d deactivated", i+1);
                wait(0.5);
                Buzzer = 0;
                lcd.locate(0, 3);
                lcd.printf("                    ");
            }
        }
        //-------------------------//
        
        switch (modo)
        {
            case 0: //Selección de Alarma
            
                //Cambio de estado del Encoder
                x = x - wheel.getPulses();
                wheel.reset();
                button.rise(&Button);
                
                //printf("\nx: %d ",x);
                if ((x != 0) && (modo == 0))
                {   
                    if (x < 1){x = 1;}
                    if (x > 16){x = 16;}
                    
                    lcd.locate(0, 2);
                    lcd.printf("      Alarm %02d", x);  
                    button.rise(&Button);
                    n = 1;
                }
                break;
                
            case 1: //Modo 1 - Encoder
                set_Alarm_encoder();
                if (count == 6){
                    lcd.locate(0, 2);
                    lcd.printf("    Alarm saved!    ");
                    wait(0.8); 
                    lcd.locate(0, 2);
                    lcd.printf("                    ");
                    lcd.locate(0, 3);
                    lcd.printf("                    ");
                    count = 0;
                    modo = 0;
                    print_Alarm();
                    n = 0;
                }
                break;
            
            case 2:
            //Cambio de estado con IRDA
                lcd.locate(0, 0);
                lcd.printf("                    "); 
                lcd.locate(0, 1);
                lcd.printf("                    "); 
                lcd.locate(0, 0);
                lcd.printf("     Alarm IRDA");
                lcd.locate(0, 1);
                lcd.printf(" Select Alarm: ");
                
               
                int x1 = 0, x2 = 0, x3 = 0, c = 0;
                while(1){
                    if (detect_number() == 1){
                        c++;
                        if(c == 1){
                            x1 = sel_number();
                            pc.printf("\nx1: %d c: %d\n",x1,c);
                            x_i = x1;
                        }
                        
                        if(c == 2){
                            x2 = sel_number();
                            pc.printf("\nx2: %d c: %d\n",x2,c);
                            if( x2 == -1){
                                x_i = x1;
                                break;
                            }
                            else{
                                 x_i = x1*10 + x2;
                            }
                        }
                        if (c == 3){
                            x3 = sel_number();
                            pc.printf("\nx3: %d c: %d\n",x3,c);
                            if( x3 == -1){
                                x_i= x1*10 + x2;
                                break;
                            } 
                        }  
                    }   
                }
                x1 = 0; x2 = 0; x3 = 0; c = 0;
            // -------------------- //
                lcd.locate(0, 1);
                lcd.printf(" Select Alarm: %d", x_i);  
                while(f == 0){
                    f = set_Alarm_IRDA();
                    count++;
                    print_Alarm();
                }
                
            break;
        }
      
        
        //wait(0.2);
    }//loop 
}

//-----------------------Funciones---------------------------------//
void set_Alarm_encoder(void){
    
    lcd.locate(0, 3);
    lcd.printf(" %02d:%02d:%02d  %02d/%02d/%02d", Alarmas[pos-1][0],Alarmas[pos-1][1],Alarmas[pos-1][2],Alarmas[pos-1][3],Alarmas[pos-1][4],Alarmas[pos-1][5]);  
    
    x = x - wheel.getPulses();
    wheel.reset();      
        
    switch (count) //count representa la posición de la columna en la matriz Alarmas - en este orden HH:MM:SS DD/MM/YY
    {
        case 0:  //Hora     
            if (x < 0){x = 0;}
            if (x > 23){x = 23;}
            Alarmas[pos-1][count] = x;  
            break;
        
        case 1: //Minutos   
            if (x < 0){x = 0;}
            if (x > 59){x = 59;}
            Alarmas[pos-1][count] = x;  
            break;
            
        case 2: //Segundos  
            if (x < 0){x = 0;}
            if (x > 59){x = 59;}    
            Alarmas[pos-1][count] = x;  
            break;
            
        case 3: // Día  
            if (x < 0){x = 0;}
            if (x > 31){x = 31;}    
            Alarmas[pos-1][count] = x;  
            break;
            
        case 4: // Mes  
            if (x < 0){x = 0;}
            if (x > 12){x = 12;}    
            Alarmas[pos-1][count] = x;  
            break;
            
        case 5: // Año  
            if (x < 0){x = 0;}
            if (x > 99){x = 99;}    
            Alarmas[pos-1][count] = x;  
            break;
    }
}

// ---- IRDA ----//
int detect_number(void){
    int y = 0;
    header=0;
    header = irda.read_low_us();    //funcion para leer un pulso de caida o bajo
  
    if (header > head_L && header < head_H){
        wait_us(2000);
        for(int i=0; i<(num_bits-1); ++i) // POR OSCILOSCOPIO se determina que llegan (num_bits),datos
        {
            dato = irda.read_high_us(); //leer un bit de datos que es pulso arriba en este control
            num[i]=dato;
            wait_us(332);
        }
        for(int i=0; i<num_bits; ++i)
        {
            if(num[i] > ((T_alto+T_bajo)/2))
            {
                pc.printf("1");
                sec[i]=1; // guardo la secuancia en binario
            }
            else
            {
                sec[i]=0; //guardo la secuencia en binario
                pc.printf("0");
            }
            pc.printf(",");
        }
        pc.printf("\n");
        y = 1;
    }
    return y;
}

int sel_number(void){
    int flag1=1,flag2=1,flag3=1,flag4=1,flag5=1,flag6=1,flag7=1,flag8=1,flag9=1,flag0=1,flag_OK=1;
    int x_irda;
    
    for(i=0; i<32; ++i)
        {
            if(sec[i]!=boton1[i]) //en caso de que un bit no coincida se descarta el boton 1
            {
                flag1=0;
            }
            if(sec[i]!=boton2[i]) //en caso de que un bit no coincida se descarta el boton 2
            {
                flag2=0;
            }
            if(sec[i]!=boton3[i]) //en caso de que un bit no coincida se descarta el boton 3
            {
                flag3=0;
            }
             if(sec[i]!=boton4[i]) //en caso de que un bit no coincida se descarta el boton 1
            {
                flag4=0;
            }
            if(sec[i]!=boton5[i]) //en caso de que un bit no coincida se descarta el boton 2
            {
                flag5=0;
            }
            if(sec[i]!=boton6[i]) //en caso de que un bit no coincida se descarta el boton 3
            {
                flag6=0;
            }
             if(sec[i]!=boton7[i]) //en caso de que un bit no coincida se descarta el boton 1
            {
                flag7=0;
            }
            if(sec[i]!=boton8[i]) //en caso de que un bit no coincida se descarta el boton 2
            {
                flag8=0;
            }
            if(sec[i]!=boton9[i]) //en caso de que un bit no coincida se descarta el boton 3
            {
                flag9=0;
            }
            if(sec[i]!=boton0[i]) //en caso de que un bit no coincida se descarta el boton 3
            {
                flag0=0;
            }
            if(sec[i]!=OK[i]) //en caso de que un bit no coincida se descarta el boton 3
            {
                flag_OK=0;
            }
        }
        
        if(flag1 == 1) {x_irda =1;}
        if(flag2 == 1) {x_irda =2;}
        if(flag3 == 1) {x_irda =3;}
        if(flag4 == 1) {x_irda =4;}
        if(flag5 == 1) {x_irda =5;}
        if(flag6 == 1) {x_irda =6;}
        if(flag7 == 1) {x_irda =7;}
        if(flag8 == 1) {x_irda =8;}
        if(flag9 == 1) {x_irda =9;}
        if(flag0 == 1) {x_irda =0;}
        if(flag_OK == 1) {x_irda =-1;}
    
    return x_irda;
}

int set_Alarm_IRDA(void){
    lcd.locate(0, 3);
    int x1 = 0, x2 = 0, x3 = 0, c = 0;
    pos = x_i;
    f = 0;
    lcd.printf(" %02d:%02d:%02d  %02d/%02d/%02d", Alarmas[pos-1][0],Alarmas[pos-1][1],Alarmas[pos-1][2],Alarmas[pos-1][3],Alarmas[pos-1][4],Alarmas[pos-1][5]);  
    
    while(1){
        if (detect_number() == 1){
            c++;
            if(c == 1){
                x1 = sel_number();
                pc.printf("\nx1: %d c: %d\n",x1,c);
                x = x1;
            }
            
            if(c == 2){
                x2 = sel_number();
                pc.printf("\nx2: %d c: %d\n",x2,c);
                if( x2 == -1){
                    x = x1;
                    break;
                }
                else{
                     x = x1*10 + x2;
                }
            }
            if (c == 3){
                x3 = sel_number();
                pc.printf("\nx3: %d c: %d\n",x3,c);
                if( x3 == -1){
                    x = x1*10 + x2;
                    break;
                } 
            }  
        }   
    }
    
    switch (count) //count representa la posición de la columna en la matriz Alarmas - en este orden HH:MM:SS DD/MM/YY
    {
        case 0:  //Hora     
            if (x < 0){x = 0;}
            if (x > 23){x = 23;}
            Alarmas[pos-1][count] = x;  
            break;
        
        case 1: //Minutos   
            if (x < 0){x = 0;}
            if (x > 59){x = 59;}
            Alarmas[pos-1][count] = x;  
            break;
            
        case 2: //Segundos  
            if (x < 0){x = 0;}
            if (x > 59){x = 59;}    
            Alarmas[pos-1][count] = x;  
            break;
            
        case 3: // Día  
            if (x < 0){x = 0;}
            if (x > 31){x = 31;}    
            Alarmas[pos-1][count] = x;  
            break;
            
        case 4: // Mes  
            if (x < 0){x = 0;}
            if (x > 12){x = 12;}    
            Alarmas[pos-1][count] = x;  
            break;
            
        case 5: // Año  
            if (x < 0){x = 0;}
            if (x > 99){x = 99;}    
            Alarmas[pos-1][count] = x; 
            break;
    }    
    
    if (count == 5){
        modo = 0;
        count = 0;
        f = 1; 
        lcd.locate(0, 2);
        lcd.printf("    Alarm saved!    ");
        lcd.locate(0, 3);
        lcd.printf(" %02d:%02d:%02d  %02d/%02d/%02d", Alarmas[pos-1][0],Alarmas[pos-1][1],Alarmas[pos-1][2],Alarmas[pos-1][3],Alarmas[pos-1][4],Alarmas[pos-1][5]);  
        wait(0.8); 
        lcd.locate(0, 2);
        lcd.printf("                    ");
        lcd.locate(0, 3);
        lcd.printf("                    ");
        x = 0;
    }
    return f;
}

void print_Alarm(void){
    printf("\n");
    for (int i=0; i<=15;i++){
        for (int j= 0; j<=5;j++){
            printf("%d ",Alarmas[i][j]);
        }
        printf("\n");
    }
}

/**********************************************************************
* Function: get_user_input() 
* Parameters: message - user prompt
*             min - minimum value of input
*             max - maximum value of input
*             member - pointer to struct member              
* Returns: none
*
* Description: get time/date input from user
*
**********************************************************************/
void get_user_input(char* message, uint8_t min, uint8_t max, uint32_t* member)
{
    uint32_t temp;

    do
    {
        printf("\n%s", message);
        
        //for some reason mbed doesn't like a pointer to a member in scanf
        //term.scanf("%d", member); works with gcc on RPi
        scanf("%d", &temp);
        
        *member = temp;
       
        if((*(member)< min) || (*(member) > max))
        {
            printf("\nERROR-RTI");
        }
    }
    while((*(member) < min) || (*(member) > max));
}


void get_user_input(char* message, uint8_t min, uint8_t max, bool* member)
{
    uint32_t temp;

    do
    {
        printf("\n%s", message);
        
        //for some reason mbed doesn't like a pointer to a member in scanf
        //term.scanf("%d", member); works with gcc on RPi
        scanf("%d", &temp);
        
        *member = temp;
       
        if((*(member)< min) || (*(member) > max))
        {
            printf("\nERROR-RTI");
        }
    }
    while((*(member) < min) || (*(member) > max));
}

void set_RTC(void){

//Cambio de la configuración del RTC DS3231
    ds3231_time_t rtc_time;
    ds3231_calendar_t rtc_calendar;
    
    //get day from user
    get_user_input("\nPlease enter day of week, 1 for Sunday (1-7): ", 1,
                    7, &rtc_calendar.day);

    //get day of month from user
    get_user_input("\nPlease enter day of month (1-31): ", 1, 31, 
                    &rtc_calendar.date);

    //get month from user
    get_user_input("\nPlease enter the month, 1 for January (1-12): ", 1, 
                    12, &rtc_calendar.month);

    //get year from user
    get_user_input("\nPlease enter the year (0-99): ",0, 99, 
                    &rtc_calendar.year);
      
    //Get time mode
    get_user_input("\nWhat time mode? 1 for 12hr 0 for 24hr: ", 0, 1, 
                   &rtc_time.mode);  
    
    if(rtc_time.mode)
    {
        //Get AM/PM status
        get_user_input("\nIs it AM or PM? 0 for AM 1 for PM: ", 0, 1, 
                       &rtc_time.am_pm);  
        //Get hour from user
        get_user_input("\nPlease enter the hour (1-12): ", 1, 12, 
                       &rtc_time.hours);
    }
    else
    {
        //Get hour from user
        get_user_input("\nPlease enter the hour (0-23): ", 0, 23, 
                       &rtc_time.hours);
    }
     
    //Get minutes from user
    get_user_input("\nPlease enter the minute (0-59): ", 0, 59, 
                   &rtc_time.minutes);
    
    
    //Get seconds from user
    get_user_input("\nPlease enter the second (0-59): ", 0, 59, 
                   &rtc_time.seconds);
    
    
    
    //Set the time, uses inverted logic for return value
    if(rtc.set_time(rtc_time))
    {
        printf("\nrtc.set_time failed!!\n");
        exit(0);
    }
    
    //Set the calendar, uses inverted logic for return value
    if(rtc.set_calendar(rtc_calendar))
    {
        printf("\nrtc.set_calendar failed!!\n");
        exit(0);
    }    
    
}