Page 1 of 1

Sleep mode with pic18f452 problem

Posted: Tue Oct 05, 2010 11:52 pm
by treefort
Hi all,

I can't get my pic to fall asleep. I have quite a bit of code, so I will only insert the main. I read that all interrupt flags must be cleared before entering sleep. Could this be the problem? Or is it going to sleep and then instantly waking up?

I have tried inserting a breakpoint but mplab keeps complaining that one or more breakpoints could not be resolved :?

Thanks for your help.

Trevor

Code: Select all

//main routine
void main(void)
{

    unsigned char data; //register to hold letter sent and received
    unsigned char control[3];
   unsigned int retry; //counter for for loop
    int i;
    int time = 0;

    Initialize();
    DelayMS(200);
    lcd_init();                           // initialize lcd unit
   
    //main program loop   
    while(1)
   {
      CheckErrorsUSART();
       
      //check UART status register to see if data has been received.  if so, process
      while(1)
      {

            DelayMS(500);

            for(i = 0; i < 7; i++)
            {
               if(i == 6)
                  control[0]=!control[0];
               if(PORTBbits.RB4==0)
                  DelayMS(500);
               else
               break;
            }
             
         nrf24l01_write_tx_payload(control, 3, true); //transmit received char over RF

         //wait until the packet has been sent or the maximum number of retries has been reached
         while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_tx_ds_active()));

            //check to see if the maximum number of retries has been hit. If not, wait for the RX device
            //to send char back. If so, assume the packet is lost and send "*" back to UART
            if(!nrf24l01_irq_max_rt_active())
            {
            nrf24l01_irq_clear_all(); //clear all interrupts in the 24L01
            nrf24l01_set_as_rx(true); //change the device to an RX to get the character back from the other 24L01

               //wait a while to see if we get the data back (change the loop maximum and the lower if
            //  argument (should be loop maximum - 1) to lengthen or shorten this time frame
            for(retry = 0; retry < 30000; retry++)
            {
                //check to see if the data has been received.  if so, get the data and exit the loop.
                //  if the loop is at its last count, assume the packet has been lost and set the data
               //  to go to the UART to "?".  If neither of these is true, keep looping.
               if((nrf24l01_irq_pin_active() && nrf24l01_irq_rx_dr_active()))
                 {
                  nrf24l01_read_rx_payload(temp, 3); //get the payload into data
                    break;
                   }           
               //if loop is on its last iteration, assume packet has been lost.
               if(retry == 29999)
                   {
                      temp[0] = '?';
                      temp[1] = '?';
                      temp[2] = 0;
                   }
            }
            nrf24l01_irq_clear_all(); //clear interrupts again

               //wait a while to see if we get the data back (change the loop maximum and the lower if
            //  argument (should be loop maximum - 1) to lengthen or shorten this time frame
            for(retry = 0; retry < 30000; retry++)
            {
                //check to see if the data has been received.  if so, get the data and exit the loop.
                //  if the loop is at its last count, assume the packet has been lost and set the data
               //  to go to the UART to "?".  If neither of these is true, keep looping.
               if((nrf24l01_irq_pin_active() && nrf24l01_irq_rx_dr_active()))
                 {
                  nrf24l01_read_rx_payload(status, 3); //get the payload into data
                    break;
                   }           
               //if loop is on its last iteration, assume packet has been lost.
               if(retry == 29999)
                   {
                      status[0] = '?';
                   }
            }
            nrf24l01_irq_clear_all(); //clear interrupts again
               
               sauna_status();
             
               display_tempstr();
            display_temp();
               
               DelayUS(130); //wait for receiver to come from standby to RX
            nrf24l01_set_as_tx(); //resume normal operation as a TX

            }
            else
            {
               nrf24l01_flush_tx(); //get the unsent character out of the TX FIFO
               nrf24l01_irq_clear_all(); //clear all interrupts
               printf("*"); //print "*" to the screen to show that the receiver did not receive the packet   
         }
                   
         ToggleLED(); //toggle the on-board LED as visual indication that the loop has complete
         
            nop();
            INTCONbits.INT0IF = 0;         // Clear INT0 Interrupt Flag
            Sleep();
   }

}

Posted: Wed Oct 06, 2010 12:38 am
by treefort
Ok,

I checked the disassembly window and it appears as though my newly created project is using a different .c file than what I was inserting breakpoints on. I have created a new project and will see what I find!

Thanks for looking. Hope I didn't waste too much of anyone's time.

Posted: Wed Oct 06, 2010 3:40 pm
by ThePyroElectro
Hey treefort,

Sounds like you got it under control now, at least a little bit. After you get it working, do you think you could post a snippet of the code that puts the PIC to sleep on the forum here?

I've never actually looked into that functionality and I'm interested to see it.

Posted: Wed Oct 06, 2010 11:30 pm
by treefort
Hi Pyro,

Late last night I got the sleep function working.

Here is my little snippet of code with the sleep command in it:

Code: Select all

 if (overflow >= 2289)   // 15 seconds
            {
               overflow = 0;
               T1CONbits.TMR1ON = 0;   /* Disable the timer */      
               PORTA=0x00;
               PORTB=0x00;
               PORTC=0x00;
               PORTD=0x00;
               PORTE=0x00;
               Sleep();
            }


If you would like to see the code for the interrupt and timer just let me know. What I need to work on now is getting the interrupt on change working so I can press a button and come out of sleep.

The whole idea is if I press a button on the remote it will wake up and if I don't don't touch a button again within 15 seconds it will go to sleep, saving power. I cleared all of the ports and disabled the timer before putting it to sleep to save extra power. The hd44780 lcd only pulls around 10mA so I have it powered through one of the pins on the pic18f452.

I am getting there, and will definitely post the code and pictures when I am done. It is the least I can do.

Posted: Thu Oct 07, 2010 2:33 am
by treefort
Another question...


With my pic and the max323 chip pulled from the pic-p40 board I am drawing 6-7mA!?

I measured the draw at the resistor on the LM317 and it was 3.8mA or something to ground.

Shouldn't I be able to reduce the current draw down to uA???


Thanks,

Posted: Thu Oct 07, 2010 3:41 am
by treefort
I found the culprit. I was measuring and desoldering 2 different boards so somehow I got mixed up.

The LM317 is pulling 3.8mA quiescent current. And my nrf24L01 is pulling the rest...3mA or so.

I am going to have to power the nrf24L01 off of an output and get a MCP1702 regulator which only draws 2uA

* Update: Just ordered 2 samples from Microchip.

Posted: Thu Oct 07, 2010 7:22 pm
by ThePyroElectro
Damn that's really cool. Thanks for sharing.

I've always wanted to delve into that side of things, but I never have applications that need to put PICs to sleep.

I'd love to see your final result.