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

Revision:
0:dc639ee44cab
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Aug 13 03:24:11 2019 +0000
@@ -0,0 +1,635 @@
+/*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);
+    }    
+    
+}