Problem in PIC 12F675 in wake from sleep

Thread Starter

yatindeshpande77

Joined Dec 20, 2015
38
I am trying to make a security system at my house. I am using a rid switch at door which is connected to RF tx module.
I want to send the data of door status every time it changes, but I don't want to spend power continuously so I am putting my micro controller in sleep mode. now my main problem is that in my PIC 12F675 I used below code to complete my task but I in practice 99 out of 100 times it wakes up and go to loop but one time it misses that inturupt which I can't afford to happen.

my code is as follows where
OP_TX GP0
IP_REED_SW GP3
IP_PANIC_SW GP1
OP_LED GP2
C:
#include <htc.h>
#include <math.h>
#include "HardwareProfile.h"
#include "delay.h"


// Configuration Bits

__CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & BOREN_OFF & CP_ON & CPD_ON);


const char  Open =   0x31  ;  //1
const char  Close  = 0x32   ; //2

const char First   = 0x41;    // A
const char Second  = 0x31;    // 1
const char Third   = 0x38;    // 8

const char  Header =   0x20;
const char  Stop   =   0x21;

volatile unsigned char i,j;
volatile unsigned int k=0,m=0, var=0;
volatile unsigned char *data;
static bit bit_once1=0,bit_once=0;
unsigned char bit_door_open=0, bit_door_close=0;
unsigned char buff[6];

void sw_open(void);
void sw_close(void);
void InitializeSystem();


void interrupt isr()
{
    if(INTCONbits.GPIF==1)
       {
        INTCONbits.GPIF = 0;
        if((GPIObits.GP3==0)&&(bit_door_open==1))
        {
            sw_close();
            bit_door_close = 1;
            bit_door_open = 0;
        }
        if((GPIObits.GP3==1)&&(bit_door_close==1))
        {
            sw_open();
            bit_door_open = 1;
            bit_door_close = 0;
           }
       }
}


void sw_open()
{
    //-------------------------------

       if(IP_REED_SW==1)         //on
       {
        for(k=0;k<10;k++)    
          {
            DelayMs(15);       
          } 
          if(IP_REED_SW==1)         //on
          { 
            for(k=0;k<10;k++)   
             {
                DelayMs(15);    
             } 
             if(IP_REED_SW==1)         //on
             { 
                OP_LED=1;
       
                //---------------------------
                // 1st
                //------------------------------
k1   :          
                buff[0]=Header;
                buff[1]=First;   // channel 1
                buff[2]=Second;
                buff[3]=Third;
                buff[4]=Open;
                buff[5]=Stop;
                data=&buff;
          
                //------------------------
          
                for (i=0;i<16;i++)        // send preamble 16 times
                {
                       OP_TX=1;
                       DelayBigUs(4890);    // 5 mS  (5.860ms)
             
                       OP_TX=0;
                       DelayBigUs(4890);    // 5 mS
                }
                DelayBigUs(14738);          // syn bit
          
                OP_LED = 0;                 // For less current led is zero early
          
          
                OP_TX=1;   // start bit
                DelayBigUs(4890);    // 5 mS
          
                OP_TX=0;
                DelayBigUs(4890);    // 5 mS
           
                for (j=0;j<6;j++)
                {
                      for(i=0;i<8;i++)
                      {
                           if ((data[j] & 0x80) == 0x80)
                           {
                              OP_TX=1;
                              DelayBigUs(4890);    // 5 mS
       
                              OP_TX=0;
                              DelayBigUs(4890);    // 5 mS
                           }
                           else
                           {
                              OP_TX=0;
                              DelayBigUs(4890);    // 5 mS
                
                              OP_TX=1;
                              DelayBigUs(4890);    // 5 mS
                           }
                           data[j]=data[j]<<1;
                      }
                }

                //------ send stop bit -------
  
                OP_TX=1;   // stop bit    
                DelayBigUs(4890);    // 5 mS
          
                OP_TX=0;    
                DelayBigUs(4890);    // 5 mS   
             
        
                for(k=0;k<30;k++)     
                {
                       DelayMs(15); 
                }
                if(bit_once==0)
                {
                       bit_once=1;
                       goto k1;       
                }
                if(IP_REED_SW==0)         //on
                {
                       OP_LED=0;
                       DelayMs(15);
                             
                       if(IP_REED_SW==0)
                       {
                          OP_LED=1;
                          bit_once=1;
                       }          
                }
                bit_once=0;   
                OP_LED = 0;     
             }
          }
       }
}

///////////////////   SW CLOSE   //////////////////////////

void sw_close()
{
    //-------------------------------
       if(IP_REED_SW==0)         //on
       {
        for(k=0;k<10;k++) 
          {
            DelayMs(15);   
          } 
          if(IP_REED_SW==0)         //on
          { 
            for(k=0;k<10;k++)
             {
                DelayMs(15);
             } 
       
             if(IP_REED_SW==0)         //on
             { 
                OP_LED=1;
          
                //---------------------------
                // 1st
                //------------------------------
k2   :          
                buff[0]=Header;
                buff[1]=First;   // channel 1
                buff[2]=Second;
                buff[3]=Third;
                buff[4]=Close;
                buff[5]=Stop;
                data=&buff;

                //------------------------

                for(i=0;i<16;i++)   // send preamble 16 times
                {
                       OP_TX=1;
                       DelayBigUs(4890);    // 5 mS
          
                       OP_TX=0;
                       DelayBigUs(4890);    // 5 mS
                }
                DelayBigUs(14738); // Delay 15000 uS  // syn bit
          
                OP_LED = 0;                // For less current led is zero early
          
                //-----------------
                OP_TX=1;   // start bit
                DelayBigUs(4890);    // 5 mS
           
                OP_TX=0;
                DelayBigUs(4890);    // 5 mS
           
                //-----------------
          
                for(j=0;j<6;j++)
                {
                      for(i=0;i<8;i++)
                      {
                           if((data[j] & 0x80) == 0x80)
                           {
                              OP_TX=1;
                              DelayBigUs(4890);    // 5 mS
               
                              OP_TX=0;
                              DelayBigUs(4890);    // 5 mS
                           }
                           else
                           {
                              OP_TX=0;
                              DelayBigUs(4890);    // 5 mS
                
                              OP_TX=1;
                              DelayBigUs(4890);    // 5 mS
                           }
                           data[j]=data[j]<<1;
                     }
                }
          
                //------ send stop bit -------
          
                OP_TX=1;   // stop bit    
                DelayBigUs(4890);    // 5 mS
         
                OP_TX=0;    
                DelayBigUs(4890);    // 5 mS
                 
             
                for(k=0;k<30;k++)       
                {
                       DelayMs(15);    
                }
                if(bit_once1==0)
                {
                       bit_once1=1;
                       goto k2;       
                }
                if(IP_REED_SW==1)       
                {
                       OP_LED=0;
                       DelayMs(15);
                             
                       if(IP_REED_SW==1)
                       {
                          OP_LED=1;
                          bit_once1=1;
                       }          
                }
                bit_once1=0;          
                OP_LED=0;
             }
          }
       }
}

void main()
{
    InitializeSystem();

    bit_once=0;
    bit_once1=0;
    OP_LED=0;

    if(IP_REED_SW==1)
    {
        bit_door_open = 1;
    }
    if(IP_REED_SW==0)
    {
        bit_door_close = 1;
    }

    while(1)
    {
        GPIE = 1;
        SLEEP();                    // Controller goes into sleep mode (To reduce current in IDLE MODE)
    }
} 

void InitializeSystem()
{
    OPTION_REG = 0XC0;
    ANSEL  = 0x00;                             // Configure AN pins as digital I/O
    INTCON = 0X88;
    ADCON0 = 0X00;
    CMCON  = 0X07;
    VRCON  = 0X00;

    TRISIO = 0b00001000;   // Only GP3(REED SW) is input others are output
    IOC    = 0b00001000;
    GPIO   = 0X00;
Any suggestion on my code or any other way to forcefully wake him up? any suggestions will be help full,
Thanks

Mod edit: added 'C' to code tag
 
Last edited by a moderator:

djsfantasi

Joined Apr 11, 2010
5,833
Your ISR routine is very long, due to the call to either sw_open or sw_close. Especially with the for loops therein. I'd just set a flag in the ISR and use it to call sw_open or sw_close in your main function.
 

Thread Starter

yatindeshpande77

Joined Dec 20, 2015
38
Here is my schematic its quite simple nothing big in it! I am not adding tf link in it it is at txx, it is working on every time! when my circuit wont work my led dont get lighted so it means its not coming out of wake up thats what i get!
OK theoretically ISR should be small i will make that change but i dont hope its problem because my whole controller is dedicated for that application only and my all code gets exicuted with 2 sec for each inturupt testing and execution and my door which is connected on that door i want to sence is what i want to sence only if change in position stays for more than 5 sec!
But thanks for your time!
PIC 16F886 in schematic is used for rx but it has no issue right now!
So any other suggestion?
 

Attachments

Thread Starter

yatindeshpande77

Joined Dec 20, 2015
38
Post your code using CODE tags so we can take a look at it.
I added my code in it only I guess in my first post itself!
tell us what compiler/assembler/debugger you are using
I am using MPLAB IDE V8.92, along with proteus!
if you have tried it on actual hardware or just the sim.
Yes I did this at hardware after running it on simulation, and i shred that 1 failure out of 100 attempts after 15 days observation!
 

Thread Starter

yatindeshpande77

Joined Dec 20, 2015
38
In my opinion problem is not in ISR if comes to it then it do everything properly but some times it goes in like deep sleep or something that he don't wake up as my led don't toggle in it too!
  1. Is there is any more registers of controller that i need to set other than this?
  2. IS watchdog timer could help in not letting him go in sleep for long ?(Is keeping controller in sleep for long time could create any problem?)
  3. Do I need to use some other interrupt than one I am using right now to force controller not to miss a single one wake up also?
 

Picbuster

Joined Dec 2, 2013
983
What happens if a door is closed or opend and an interrupt occurs?
This could happen when a pulse arrives at input switch.
to solve this place a input filter resistor + cap 100nF to signal called sw read.
even better is to use a NC contact.

Pwr consumption: how do you generate 5V ( type of chip) if a lm7805 is used then you loose 2-4 mA current.(quiescent current)
More than the pic will draw at 32Khz
I used a mcp1703 -50 3-4 micro amps. (quiescent current)
 

Thread Starter

yatindeshpande77

Joined Dec 20, 2015
38
Thanks for that 5V suggestion I will look for it soon!
Yes I already using reed switch for sensing door and at every time it changes for open to close or opposite it alters the port pin causing interrupt!
so no doubt it is getting switch on his port pin!
is there any concept like deep sleep or something?
If i use watchdog to make my controller wake up after specific interval will that resolve my problem?
I am not understanding at all about why it don't get 100 out if 100 output, I am really stuck at it!
please if any one have any better suggestion it will be appreciated!
 

ErnieM

Joined Apr 24, 2011
8,009
Your schematic may seem simple but you have at least one error: you do not have a limiting resistor on U1 pin 5.
 

Thread Starter

yatindeshpande77

Joined Dec 20, 2015
38
Sorry, I have that resistor too but forgot to put that in schematic!!
And I really don't think it is a hardware problem as it works 99 times in 100!
Really don't understanding where I am doing wrong!
 
Last edited:

Picbuster

Joined Dec 2, 2013
983
Correct me if I am wrong but I think that you made it complicated.
You want a signal when door opens or closed.
the pic used a interrupt on change. ( assume door closed contact closed)
now you do not care, at the first instance, if door goes open or is closing.
an interrupt occurs when open or when closed.==> wake up
door_flag=true;

debounce in a other timer routine
when valid for timer time
door=pin4; // high open closed low
Ready flag=true;

in main test for ready flag. found it clear it and wait for the next one
and door will give status pin4

now you end up with a few lines of programming doing the same.

but again I don't know all the ins and outs from your project.
 

Thread Starter

yatindeshpande77

Joined Dec 20, 2015
38
Yes PICBUSTER you are correct about my door switch and the part of program i am using for it, other than this I am trying to communicate with my RF receiver using RF TX, by which it will send change of staus to rx at different end of my house which will process that signal after it got that on receiver, but as I am using 12F675 which is without USART I am using bit banking to transfer that data serially.
Now the problem is some times even when my door gets open/close my controller don't get wake up and I miss that signal which i want to cover!
 

Picbuster

Joined Dec 2, 2013
983
It might want to wake up but with all delays it might run into a "from stack" return problem.
I had that problem going 3+ deep in the routines. wend wrong so now and than.
Took me one day to find out by reading the xc8 manual. Resulting picbuster = donkey so now and then.
 

Thread Starter

yatindeshpande77

Joined Dec 20, 2015
38
As per suggestion from this link I changed few things in program so is this OK or so I need to change anything else?
I reduced the ISR routine and increase my main routine by setting flag from ISR.
Transmitter code!
Code:
/*
> Program For: Transmitter 1 (Data = "ABC")
> IC Used: PIC 12F675

> Pin no. 1 - +ve (From battery +ve to this through diode-4.7k Resistor-diode)
> Pin no. 2 -
> Pin no. 3 -
> Pin no. 4 - REED SWITCH ( Connect REED SW between pin no. 4 and ground),
              Connect Resistor of 1M-Ohm to +ve(pin no.1)
> Pin no. 5 - LED (Resistor of 22k)
> Pin no. 6 - Connect to DATA pin of TX MODULE
> Pin no. 7 -
> Pin no. 8 - Ground

> This program is Proper working for both Transmitter 1 and Panic in ONE IC. (Checked On Hardware)

*/

/////////////////////   In sleep mode current is 10 uA

#include <htc.h>
#include <math.h>
#include "HardwareProfile.h"
#include "delay.h"


// Configuration Bits

__CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & BOREN_OFF & CP_ON & CPD_ON);


const char  Open =   0x31  ;  //1
const char  Close  = 0x32   ; //2

const char First   = 0x41;    // A
const char Second  = 0x33;    // 3
const char Third   = 0x38;    // 8

const char  Header =   0x20;
const char  Stop   =   0x21;

volatile unsigned char i,j;
volatile unsigned int k=0,m=0, var=0,flag1=0,flag2=0;
volatile unsigned char *data;
static bit bit_once1=0,bit_once=0;
unsigned char bit_door_open=0, bit_door_close=0;
unsigned char buff[6];

void sw_open(void);
void sw_close(void);
void InitializeSystem();


void interrupt isr()
{
    if(INTCONbits.GPIF==1)
       {
        INTCONbits.GPIF = 0;
        if((GPIObits.GP3==0)&&(bit_door_open==1))
        {
            flag1 = 1;//switch close routine call flag
           
        }
        if((GPIObits.GP3==1)&&(bit_door_close==1))
        {   
            flag2 = 1;//switch open routine call flag
           
           }
       }
}


void sw_open()
{
    //-------------------------------

       if(IP_REED_SW==1)         //on
       {
        for(k=0;k<10;k++)     
          {
            DelayMs(15);        
          }  
          if(IP_REED_SW==1)         //on
          {  
            for(k=0;k<10;k++)    
             {
                DelayMs(15);     
             } 
             if(IP_REED_SW==1)         //on
             {  
                OP_LED=1;
        
                //---------------------------
                // 1st
                //------------------------------
k1   :           
                buff[0]=Header;
                buff[1]=First;   // channel 1
                buff[2]=Second;
                buff[3]=Third;
                buff[4]=Open;
                buff[5]=Stop;
                data=&buff;
           
                //------------------------
           
                for (i=0;i<16;i++)        // send preamble 16 times
                {
                       OP_TX=1;
                       DelayBigUs(4890);    // 5 mS  (5.860ms)
              
                       OP_TX=0;
                       DelayBigUs(4890);    // 5 mS
                }
                DelayBigUs(14738);          // syn bit
                OP_LED = 0;                 // For less current led is zero early
           
           
                OP_TX=1;   // start bit
                DelayBigUs(4890);    // 5 mS
           
                OP_TX=0;
                DelayBigUs(4890);    // 5 mS
            
                for (j=0;j<6;j++)
                {
                      for(i=0;i<8;i++)
                      {
                           if ((data[j] & 0x80) == 0x80)
                           {
                              OP_TX=1;
                              DelayBigUs(4890);    // 5 mS
        
                              OP_TX=0;
                              DelayBigUs(4890);    // 5 mS
                           }
                           else
                           {
                              OP_TX=0;
                              DelayBigUs(4890);    // 5 mS
                 
                              OP_TX=1;
                              DelayBigUs(4890);    // 5 mS
                           }
                           data[j]=data[j]<<1;
                      }
                }

                //------ send stop bit -------
   
                OP_TX=1;   // stop bit     
                DelayBigUs(4890);    // 5 mS
           
                OP_TX=0;     
                DelayBigUs(4890);    // 5 mS    
              
         
                for(k=0;k<30;k++)      
                {
                       DelayMs(15);  
                }
                if(bit_once==0)
                {
                       bit_once=1;
                       goto k1;        
                }
                if(IP_REED_SW==0)         //on
                {
                       OP_LED=0;
                       DelayMs(15); 
                              
                       if(IP_REED_SW==0)
                       {
                          OP_LED=1;
                          bit_once=1;
                       }           
                }
                bit_once=0;    
                OP_LED = 0;      
             }
          }
       }
}

///////////////////   SW CLOSE   //////////////////////////

void sw_close()
{
    //-------------------------------
       if(IP_REED_SW==0)         //on
       {
        for(k=0;k<10;k++)  
          {
            DelayMs(15);    
          }
          if(IP_REED_SW==0)         //on
          {  
            //for(k=0;k<10;k++) 
             {
                //DelayMs(15); 
             }  
        
             if(IP_REED_SW==0)         //on
             {  
                OP_LED=1;
           
                //---------------------------
                // 1st
                //------------------------------
k2   :           
                buff[0]=Header;
                buff[1]=First;   // channel 1
                buff[2]=Second;
                buff[3]=Third;
                buff[4]=Close;
                buff[5]=Stop;
                data=&buff;

                //------------------------

                for(i=0;i<16;i++)   // send preamble 16 times
                {
                       OP_TX=1;
                       DelayBigUs(4890);    // 5 mS
           
                       OP_TX=0;
                       DelayBigUs(4890);    // 5 mS
                }
                DelayBigUs(14738); // Delay 15000 uS  // syn bit
           
                OP_LED = 0;                // For less current led is zero early
           
                //-----------------
                OP_TX=1;   // start bit
                DelayBigUs(4890);    // 5 mS
            
                OP_TX=0;
                DelayBigUs(4890);    // 5 mS
            
                //----------------
                for(j=0;j<6;j++)
                {
                      for(i=0;i<8;i++)
                      {
                           if((data[j] & 0x80) == 0x80)
                           {
                              OP_TX=1;
                              DelayBigUs(4890);    // 5 mS
                
                              OP_TX=0;
                              DelayBigUs(4890);    // 5 mS
                           }
                           else
                           {
                              OP_TX=0;
                              DelayBigUs(4890);    // 5 mS
                 
                              OP_TX=1;
                              DelayBigUs(4890);    // 5 mS
                           }
                           data[j]=data[j]<<1;
                     }
                }
           
                //------ send stop bit -------
           
                OP_TX=1;   // stop bit     
                DelayBigUs(4890);    // 5 mS
          
                OP_TX=0;     
                DelayBigUs(4890);    // 5 mS 
                  
              
                for(k=0;k<30;k++)        
                {
                       DelayMs(15);     
                }
                if(bit_once1==0)
                {
                       bit_once1=1;
                       goto k2;        
                }
                if(IP_REED_SW==1)        
                {
                       OP_LED=0;
                       DelayMs(15); 
                              
                       if(IP_REED_SW==1)
                       {
                          OP_LED=1;
                          bit_once1=1;
                       }           
                }
                bit_once1=0;           
                OP_LED=0;
             }
          }
       }
}

void main()
{
    InitializeSystem();
 
    bit_once=0;
    bit_once1=0;
    OP_LED=0;

    if(IP_REED_SW==1)
    {
        bit_door_open = 1;
    }
    if(IP_REED_SW==0)
    {
        bit_door_close = 1;
    }

    while(1)
    {
        GPIE = 1;
        if(flag1==1)
        {   
            sw_close();
            bit_door_close = 1;
            bit_door_open = 0;
            flag1 = 0;
        }
        if(flag2==1)
        {
            sw_open();
            bit_door_open = 1;
            bit_door_close = 0;
            flag2 = 0;
        }
        SLEEP();                    // Controller goes into sleep mode (To reduce current in IDLE MODE)
       
    }
}  

void InitializeSystem()
{
    OPTION_REG = 0XC0;
    ANSEL  = 0x00;                             // Configure AN pins as digital I/O
    INTCON = 0X88;
    ADCON0 = 0X00;
    CMCON  = 0X07;
    VRCON  = 0X00;

    TRISIO = 0b00001000;   // Only GP3(REED SW) is input others are output
    IOC    = 0b00001000;
    GPIO   = 0X00;
}
 

Picbuster

Joined Dec 2, 2013
983
To send a byte you can do this easy
Msg the byte you want to send
int Msg=0bxxxxxyyddddddddS; // x don't care yy stopbits S startbit.

for ( i=0;i<10;i++)
{
RC5=(Msg & (1 << i)) != 0; // get one bit and send it out to port
__delay_ms(5); // bit time
}
 
Top