Turned OFF and turned ON at pre-define time the display 7seg runing RTC

saj's picture
saj

Offline

Joined: Sep 28, 2018

Replies: 19
Turned OFF and turned ON at pre-define time the display 7seg runing RTC
June 29, 2019 - 6:22pm

hi,

In software side, it is multiplex, xc8 comp to disp HH:MM:SEC, mcu reading from rtc readng at 24hrs format and then in software it is converted to 12hrs farmat.

H/W, 7seg  CC, RTC1307.

All are working correctly , now I want to add a feature  that is, when the time reach at 2:30 (at night)the disp will be turned OFF and after 2:32 (at night) the disp will turn ON. The code attched here is working all the said time(ie, as every 2.30 start OFF and evert 2.32 start ON), whereas i need only at night, so if 1st time is turned ON and OFF then for 2nd time(which is day time)  no need and vice-versa, and 3rd. time what was in 1st time.

As per code attached here, Once turned OFF at said time at 2.30 & it ON at 2.32, when it ON then i set the time by BUTTON once to keep ON  the disp for this 2nd. time but it going OFF again. 

S, is the code ok or what should i modify either at BUTTON rour or Main routine.

Code is at Main()

// TIME FORMAT 24>>12 HRS

            if (hour <= 12)
            {
                hour = hour;
PowerSave = 1;
            }
            else
            {
                 PowerSave = 0;
                hour = (hour - 12);

                
            }
            
 // For particular time display to be TURNED OFF and Again ON          
 if (PowerSave == 1)
  {
             
    if ((hour == 2 && min >= 30) && (hour == 2 && min <= 31))
        {
            INTCONbits.T0IE = 0;
 

        }
    else 
   
   INTCONbits.T0IE = 1;
            
    }
       

Sub routine for BUTTON

uint8_t edit(uint8_t parameter)
{
  while(debounce());                                // call debounce function (wait for B1 to be released)
 
  while(1) 
        {
            while(!BUTTON2)                         // if button B2 is pressed
                 {
                    parameter++;
                    __delay_ms(300);                //this delay for prevent several count on one press
                    
                    if (i == 0 && parameter <= 12)
                        PowerSave &= 0x01;
          
                    if(i == 0 && parameter > 12)    // if hours > 23 ==> hours = 0
                    parameter = 1;
      
                    if(i == 1 && parameter > 59)    // if minutes > 59 ==> minutes = 0
                    parameter = 0;
      

                    if (i == 0)
                         {
                            hour_1 = (parameter % 10);
                            hour_10 = (parameter / 10); 
                            __delay_ms(10);
                         }
      
                    if (i == 1)
                         {
                            min_1 = (parameter % 10);
                            min_10 = (parameter / 10);   
                            __delay_ms(10);                //delay from 200 to 10 minimize to prevent blink on when update time
      
                         }
    
                 }
    
            if(!BUTTON1)                            // if button B1 is pressed
            if(debounce())                          // call debounce function (make sure if B1 is pressed)
             {
                i++;                                // increment 'i' for the next parameter
                return parameter;                   // return parameter value and exit
              }
 
        }
 
}

 

TNX

Abhiemanyu Pandit's picture

Offline

Joined: Jan 21, 2019

Replies: 42
Set a flag for am and pm
July 1, 2019 - 5:42pm

dear saj, i would suggest to add a boolean flag for am and pm and then first check the flag then check the time. This way u can easily do this. Also if you want to take reference then you can also look the code of Automatic Medicine Reminder Using Arduino

saj's picture
saj

Offline

Joined: Sep 28, 2018

Replies: 19
tnx
July 2, 2019 - 11:01am

tnx

Please tell me where to put bool.

will it be under main() or button()

kindle leave a snap.

tnx

Abhiemanyu Pandit's picture

Offline

Joined: Jan 21, 2019

Replies: 42
Set a flag for am and pm
July 3, 2019 - 11:05am

put in the main function and while checking the condition check the value of flag change. If you want more to help you then post complete code i will try to place the bool wherever necessary according to the application

saj's picture
saj

Offline

Joined: Sep 28, 2018

Replies: 19
Request to review the code attached for auto ON-OFF
July 4, 2019 - 9:03pm

Hi Pandit,

Pl looks the code in .TXT format here.

What is happening::

1) Button is used to set the time(2:29) nearer to predefined OFF stage, some times it is going OFF and ON (at 2:31), and once OFF/ON completed for the first time  

2) Then it should be  keep ON( that means the time is DAY 2:30AM, i set the time nearer to predefined  by button) 

3) Again after set at nearer to predefined time (that means the time is 2:30 PM) - the it should be OFF at this stage. and continue continuously those all three stage one after another.

I have modified under //edit(), and while() at main() function to get this result but irregularity is noticed that means once point 1 is comes then it is coming after some stage latter not interval of one stage.

#include <xc.h>
#include <stdint.h>         
 
// set configuration words
#pragma config CONFIG1 = 0x2CD4
#pragma config CONFIG2 = 0x0700

//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------




//END_Function Prototypes -----------------------------------------------------

#define _XTAL_FREQ 8000000  

#define TRUE            1
#define FALSE           0

#define HOURS_TENS      0
#define HOURS_ONES      1
#define MINUTES_TENS    2
#define MINUTES_ONES    3
#define SECONDS_TENS    4
#define SECONDS_ONES    5
#define DIGIT_ANODE_MASK   0xC0;



                                                                                                                       
#define HRTEN           0b00000001      // control pin A0
#define HRONE           0b00000010      // A1
#define MNTEN           0b00000100      // A2
#define MNONE           0b00001000
#define SCTEN           0b00010000
#define SCONE           0b00100000      //A5

// button definitions
#define BUTTON1          RB0   // button B1 is connected to RB0 pin
#define BUTTON2          RB1   // button B2 is connected to RB1 pin



static uint8_t g_current_digit = 0;
static bit colons;
static bit ampm;
const unsigned char SEGMENT_MAP[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; 

uint8_t  i, sec, min, hour, m_day, month, year;
uint8_t sec_1, sec_10, min_1, min_10, hour_1, hour_10;



//--------------------------------------------------------------------------------------------------------------------------------------------
// I2C FUNCTION
//--------------------------------------------------------------------------------------------------------------------------------------------
 
void I2C_Init(uint32_t i2c_clk_freq)
{
  SSPCON  = 0x28;  // configure MSSP module to work in I2C mode
  SSPADD  = (_XTAL_FREQ/(4 * i2c_clk_freq)) - 1;  // set I2C clock frequency
  SSPSTAT = 0;
}
 
void I2C_Start()
{
  while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));  // wait for MSSP module to be free (not busy)
  SEN = 1;  // initiate start condition
}
 
void I2C_Repeated_Start()
{
  while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));  // wait for MSSP module to be free (not busy)
  RSEN = 1;  // initiate repeated start condition
}
 
void I2C_Stop()
{
  while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));  // wait for MSSP module to be free (not busy)
  PEN = 1;  // initiate stop condition
}
 
void I2C_Write(uint8_t i2c_data)
{
  while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));  // wait for MSSP module to be free (not busy)
  SSPBUF = i2c_data;  // update buffer
}
 
uint8_t I2C_Read(uint8_t ack)
{
  uint8_t _data;
  while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));  // wait for MSSP module to be free (not busy)
  RCEN = 1;
  while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));  // wait for MSSP module to be free (not busy)
  _data = SSPBUF;  // read data from buffer
  while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));  // wait for MSSP module to be free (not busy)
  // send acknowledge pulse ? (depends on ack, if 1 send, otherwise don't send)
  ACKDT = !ack;
  ACKEN = 1;
  return _data;  // return data read
}


//------------------------------------------------------------------------------------------------------------------------
// Interrupt
//------------------------------------------------------------------------------------------------------------------------
void interrupt Timer0_ISR(void)
{
    if(INTCONbits.T0IF && INTCONbits.T0IE)          
    {                                               
        TMR0 = 2;                                   
        INTCONbits.T0IF  =  0;                      
        PORTA    &=  DIGIT_ANODE_MASK;             
        PORTD    =   0x00;                                                                            

        switch(g_current_digit)
        {
            case HOURS_TENS:
            {
                PORTD    =   SEGMENT_MAP[hour_10];  
                PORTA    =  HRTEN;                  
                g_current_digit = HOURS_ONES;
                
            }

            }
            break;
            case HOURS_ONES:
            {
                PORTD    =   SEGMENT_MAP[hour_1];   
                PORTA    =  HRONE;                  
                //LATCbits.LATC5 = 0b0;             
                g_current_digit = MINUTES_TENS;
            }
            break;
            case MINUTES_TENS:
            {
                PORTD    =   SEGMENT_MAP[min_10];   
                PORTA    =  MNTEN;                  
                g_current_digit = MINUTES_ONES;
            }
            break;
            case MINUTES_ONES:
            {
                PORTD    =   SEGMENT_MAP[min_1];    
                PORTA    =  MNONE;                  
                g_current_digit = SECONDS_TENS;
            }
            break;
            case SECONDS_TENS:
            {
                PORTD    =   SEGMENT_MAP[sec_10];   
                PORTA    =  SCTEN;                  
                g_current_digit = SECONDS_ONES;
            }
            break;
            case SECONDS_ONES:
            {
                PORTD    =   SEGMENT_MAP[sec_1];    
                PORTA    =  SCONE;                  
                g_current_digit = HOURS_TENS;
            }
            break;
            default:
            {
                g_current_digit = HOURS_TENS;
            }
        }

    }


//------------------------------------------------------------------------------------------------------------------------
// DEBOUNCE OF BUTTON
//------------------------------------------------------------------------------------------------------------------------


__bit debounce ()
{
  uint8_t count = 0;
  for(uint8_t i = 0; i < 5; i++) {
    if (BUTTON1 == 0)
      count++;
    __delay_ms(10);
  }
  if(count > 2)  return 1;
  else           return 0;
}

 
//------------------------------------------------------------------------------------------------------------------------
// START OF BUTTON ROUTINE PARAMETER
//------------------------------------------------------------------------------------------------------------------------


uint8_t edit(uint8_t parameter)
{
  while(debounce());                                // call debounce function (wait for B1 to be released)
 
  while(1) 
        {
            while(!BUTTON2)                         // if button B2 is pressed
                 {
                    parameter++;
                    __delay_ms(300);                //this delay for prevent several count on one press
                    
                   // if (i == 0 && parameter <= 12)
                        //PowerSave &= 0x01;
          
                    if(i == 0 && parameter > 23 )    // if hours > 23 ==> hours = 0
                    parameter = 0;

      
                    if(i == 1 && parameter > 59)    // if minutes > 59 ==> minutes = 0
                    parameter = 0;
      

                    if (i == 0)
                        { 
                        if (parameter == 0)//24
                            {
                            hour_1 = ((12 - parameter) % 10);
                            hour_10 = ((12 - parameter) / 10); 
                            __delay_ms(10);
                            ampm = TRUE;
                            
                            }
                            
                        else if (parameter >= 1   &&   parameter <= 12 )
                            {
                            hour_1 = (parameter % 10);
                            hour_10 = (parameter / 10); 
                            __delay_ms(10);
                            ampm = FALSE;                            
                            }
                        
                        else   
                            {
                            hour_1 = ((parameter - 12) % 10);
                            hour_10 = ((parameter - 12) / 10); 
                            __delay_ms(10);
                            ampm = TRUE;
                            }
                            
                        }
            
      
                    if (i == 1)
                         {
                            min_1 = (parameter % 10);
                            min_10 = (parameter / 10);   
                            __delay_ms(10);                //delay from 200 to 10 minimize to prevent blink on when update time
      
                         }
                    
                 }
    
            if(!BUTTON1)                            // if button B1 is pressed
            if(debounce())                          // call debounce function (make sure if B1 is pressed)
             {
                i++;                                // increment 'i' for the next parameter
                return parameter;                   // return parameter value and exit
              }
 
        }
 
}


//------------------------------------------------------------------------------------------------------------------------
// BCD>> <<DCIMAL
//------------------------------------------------------------------------------------------------------------------------

uint8_t bcd_to_decimal(uint8_t number) {
  return((number >> 4) * 10 + (number & 0x0F));
}


uint8_t decimal_to_bcd(uint8_t number) {
  return(((number / 10) << 4) + (number % 10));
}


//------------------------------------------------------------------------------------------------------------------------
// TIMER0 INITIALIZATION
//------------------------------------------------------------------------------------------------------------------------

void Timer0_start()
{
    
    INTCONbits.T0IE = 1;          
    INTCONbits.T0IF = 0;
    OPTION_REGbits.T0CS = 0;     
    OPTION_REGbits.PSA = 0;
    OPTION_REGbits.PS = 2;         
    TMR0 = 2;                      
    PEIE=1;                        
    GIE=1;                         
    
}

// Write data to DS3231 RTC
void Write_Data()
{
I2C_Start();               
I2C_Write(0xD0);           
I2C_Write(0);              
I2C_Write(0);              


I2C_Write(min);            
I2C_Write(hour);           
I2C_Write(1);              
I2C_Write(m_day);          
I2C_Write(month);          
I2C_Write(year);           
I2C_Stop();             
}

// Read current time and date from the RTC chip
void Read_Data()
{
I2C_Start();                    
I2C_Write(0xD0);                
I2C_Write(0);                   
I2C_Repeated_Start();           
I2C_Write(0xD1);                
sec = I2C_Read(1);              
min = I2C_Read(1);              
hour   = I2C_Read(1);           
I2C_Read(1);                    
m_day  = I2C_Read(1);           
month  = I2C_Read(1);           
year   = I2C_Read(0);           
I2C_Stop();                     
}


//--------------------------------------------------------------------------------------------------------------------------------------------
// MAIN START HERE
//--------------------------------------------------------------------------------------------------------------------------------------------

void main(void)
{
    OSCCON = 0X70;                  
    I2C_Init(100000);               
    Timer0_start();
    g_current_digit = 0; 
    ANSEL = 0;

    TRISA = 0x00;                   
    TRISC = 0x18;                   
    TRISD = 0x00;                  


    // Enable RB0 and RB1 internal pull ups
    nRBPU  = 0;                     
    //OPTION_REGbits.nRBPU = 0;     
    WPUB   = 0x03;                  
   
    
  while(1) 
    {

            if(!BUTTON1)                 // if button B1 is pressed
            if(debounce())               // call debounce function (make sure if B1 is pressed)
                {
                i = 0;
                hour   = edit(hour);
                min = edit(min);
                while(debounce());        // call debounce function (wait for button B1 to be released)
 
                // convert decimal to BCD
                min = decimal_to_bcd(min);
                hour   = decimal_to_bcd(hour);
                
                // Write data to RTC
                Write_Data(); 
                }

            // read current time from the RTC chip
            Read_Data();

            
    // Start of conversion to DECIMAL
            sec = bcd_to_decimal(sec);
            min = bcd_to_decimal(min);
            hour   = bcd_to_decimal(hour);
            m_day  = bcd_to_decimal(m_day);
            month  = bcd_to_decimal(month);
            year   = bcd_to_decimal(year);
            

// WHEN TIME ADJUSTED THROUGH BUTTON, TRYING TO CHECK WHETHER WORKING OR NOT AM/PM.
            PORTAbits.RA7 = ampm; 
             
            
//CHANGE TO 12HRS FORMAT FROM 24HRS TO DISP IN SEGMENS           
            if (hour <= 12)
                hour = hour;
            else hour = (hour - 12);

// 2.29AM IS ADJUSTED BY THE BUTTON, WHEN 2.30AM WILL REACH THE DISP IS TO BE OFF AND AT 2.30AM WILL ON THE DISPLAY, and this will continue once in a day at this said time.
            if ((hour == 2 && min >= 30) && (hour == 2 && min <= 31))
                INTCONbits.T0IE = 0;
            else 
                INTCONbits.T0IE = 1;
            
                            
         
  
     
    //Split the into DIGIT to display on 7-SEGMENT
            sec_1 = (sec%10);
            sec_10 = (sec/10); 
     
            min_1 = (min%10);
            min_10 = (min/10); 
     
            hour_1 = (hour%10);
            hour_10 = (hour/10); 
            
     
            
                
 
            
 
     }
 
 }
Abhiemanyu Pandit's picture

Offline

Joined: Jan 21, 2019

Replies: 42
Request to review the code attached for auto ON-OFF
July 5, 2019 - 5:04pm

i will review the code and get back to you. 

lara's picture

Offline

Joined: Oct 05, 2018

Replies: 8
Request to review the code attached for auto ON-OFF
July 10, 2019 - 12:52pm

HI Abhiemanyu Pandit,

Did you go through the code ??

tnx