Help reducing sleep current in PIC10f322 - Page 1
Forum section: electronics / general

author: davekra
author_rank: Contributor
timestamp: November 12, 2015, 02:20:45 pm
content: I'm making a magnetic switch using the PIC10f322 and a Hall sensor. The idea is for one of the outputs of the PIC to power the sensor and a different output to drive a FET.The PIC would poll the sensor every 1/2 second then go to sleep.I'm not having problems with the code to do this or getting the PIC to go to sleep, but I am having trouble with excessive current draw when in sleep.For a test circuit I simply have an LED/resistor connected to the PIC. Nothing else.I've tested pull-up and pull-down of all unused pins and the internal weak pullups but the current remains around 100uA.The program lights the LED for 2 seconds then sleeps for 8.The current draw is 100uA in sleep. I really need this to be 1 - 2uA or less as this will be battery powered.This is my first time working with a PIC and probably should have chosen a basic PIC rather than a mid-range as I'm not using any of the extra features but shouldn't I still be able to get sleep currents in the single digit uA's?I think I'm turning off all the features the datasheet says will affect sleep current but would like some help.ThanksdavidkThe PIC is a 10f322. Using Mplab X IDE3.10. XC8 for the compiler.Code:#include <xc.h>// #pragma config statements should precede project file includes.// Use project enums instead of #define for ON and OFF.// CONFIG#pragma config FOSC = INTOSC // Oscillator Selection bits (INTOSC oscillator: CLKIN function disabled)#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)#pragma config WDTE = ON // Watchdog Timer Enable (WDT enabled)#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT enabled)#pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)#pragma config CP = ON // Code Protection bit (Program memory code protection is enabled)#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)#pragma config LPBOR = OFF // Brown-out Reset Selection bits (BOR disabled)#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), high trip point selected.)#pragma config WRT = ALL // Flash Memory Self-Write Protection (000h to 1FFh write protected, no addresses may be modified by PMCON control)#define _XTAL_FREQ 32000void main(void) {BORCONbits.SBOREN=0; //Software brown-out reset enable - BOR disabledBORCONbits.BORFS=0; //Brown-out reset fast start - Band gap operates normally, may turn offBORCONbits.BORRDY=0; //Brown-out reset circuit ready - reset circuit is inactiveINTCONbits.GIE=0; //Interrupt control - global interrupt disabledINTCONbits.PEIE=0; //Peripheral interrupt disabledINTCONbits.TMR0IE=0; //Timer0 overflow disabledINTCONbits.INTE=0; //External interrupt disabledINTCONbits.IOCIE=0; //Interrupt on change disabledPIE1bits.ADIE=0; //Peripheral interrupt - A/D converter disabledVREGCONbits.VREGPM1=1; //Voltage regulator - power-save modeFVRCONbits.TSEN=0; //Fixed voltage reference - temperature indicator disabledFVRCONbits.FVREN=0; //Fixed voltage reference disabledFVRCONbits.FVRRDY=0; //Fixed voltage ready flag not enabledFVRCONbits.ADFVR0=0; //ADC fixed voltage reference peripheral output offFVRCONbits.ADFVR1=0; //ADC fixed voltage reference peripheral output offADCONbits.ADON=0; //ADC disabledT2CONbits.TMR2ON=0; //Timer2 is offPWM1CONbits.PWM1EN=0; //PWM1 module disabledPWM2CONbits.PWM2EN=0; //PWM2 module disabledCLC1CONbits.LC1EN=0; //Configurable logic cell disabledNCO1CONbits.N1EN=0; //Numerically controlled oscillator disabledCWG1CON0bits.G1EN=0; //Complementary waveform generator disabledOSCCONbits.LFIOFR=1; //Low freq internal oscillator enableOSCCONbits.IRCF=0b000; //Frequency select bitsWDTCONbits.WDTPS=0b01101; //watchdog 8 secondsfor (;;){ANSELA=0; //Set all ports to digitalTRISA=0; //Set all port to output. RA3 input onlyLATA = 0; // start with all output pins lowLATAbits.LATA2=1; //RA2 high__delay_ms(2000); //delay 2 secondsLATAbits.LATA2=0; //RA2 lowSLEEP(); //sleep and wait for WDTNOP(); //do nothing} //repeat}

author: Maxlor
author_rank: Frequent Contributor
timestamp: November 12, 2015, 02:46:00 pm
content: Sleeping with the watchdog timer should give you around 10uA, not 100uA. The only thing that would require that amount of current in sleep mode is your GPIOs, and the FVR. Are your chance including the power needed to run the hall sensor in those 100uA? If so, try switching it off during sleep. Or maybe you need the FVR for something? You can switch it off too, you just need to wait a bit for it to stabilize before you use it, when you turn it on again.The last reason that comes to mind why you use more power is that you wake up more often than every 0.5 second but don't realize it. Maybe double check that with an oscilloscope.Also, you seem to be running with a 32kHz clock. When using sleep, it's often more efficient overall to run with a fast clock so you can go back to sleep as quickly as possible. The most efficient speed depends on interaction times with other devices (and associated wait times), you'll have to measure if you care about every last uA.Btw, you can't really get to 2uA as long as you have the watchdog timer enabled. If you disable it, you need an external signal to wake up from sleep, and then usually that requires power.

author: bookaboo
author_rank: Frequent Contributor
timestamp: November 12, 2015, 03:23:39 pm
content: No experience with the 10F but the 24F range have peripheral select which are quite handy.For example:Code:PMD1 = 0xFFFF; //PMD2 = 0xFFFF; //PMD3 = 0xFdFF; // RTCC aliveSleep();PMD1 = 0x0000; //PMD2 = 0x0000; //PMD3 = 0x0000; // Peripherals Back OnJust be sure to leave whatever is supposed to wake from sleep running (in my case there the RTCC)Failing that, manually switch off or disable all the peripherals, even ones you didn't enable or even know about.

author: davekra
author_rank: Contributor
timestamp: November 12, 2015, 03:49:40 pm
content: Thanks for the replies.I think I have the FVR shut off with the FVRCONbits section of my code.For this testing I don't have the Hall sensor connected. Only an LED.I also tried setting WDTE=OFF but the current remained the same. I think that turns off the watchdog timer, right?"you can't really get to 2uA.."That's not good news for what I'm trying to do. When I first looked at the datasheet I thought the Standby current of 20nA was what I'd get while sleeping. Looks like that's not going to be the case.Being this is the first time I'm working with PICs 'you don't know what you don't know', and reading through the datasheet was very confusing (and still is) but I'm starting to understand it a bit more.If I can't reduce the current to single digits this isn't going to work and I'll need to find a non-micro-controller way...unless anyone has a recommendation for a particular controller.Thanks again,davidk

author: bookaboo
author_rank: Frequent Contributor
timestamp: November 12, 2015, 04:57:38 pm
content: I'm sure it can be done, I have a 24FJ64GA004running at 8uA sleep with a 32Khz clock. That's below the self discharge rate of my battery so Im sure the 10F range can meet it's specification.

author: hans
author_rank: Super Contributor
timestamp: November 12, 2015, 05:43:56 pm
content: Well it is. Onpage 163it is explained.But the maximum figures at +85C are much much higher.The sleep itself is about 0.06uA typically (not sure how they get at 20nA?).0.5uA for WDT7.5uA for BORThe PIC itself should use about 2.2uA with Fosc=32kHz at 85C.However, this is only true when you also set up the I/O correctly. I believe you don't want any pins floating while set as input, because the transistors for the input buffer will be half-biased and consume current.OTOH you don't want outputs to source/sink current either.MaybeAN1416is worth a read.It is certainly possible to get PICs that low of a sleep current. I have had the PIC16F1509 at <1uA sleep current, however it was tricky to set up the GPIO's correctly for that. I didn't have pull-ups - so instead I went with all outputs instead. I also believe that some pull-ups/downs are basically uA-level current sources, so they may consume extra current versus external resistors.

author: davekra
author_rank: Contributor
timestamp: November 12, 2015, 06:46:22 pm
content: The peripheral library for the 24f..what does that do exactly. Online it says it's a set of functions for controlling peripheral modules...Is it a library of C commands that make it easier to configure the modules?In XC8 when you type something like FVRCONbits. it pops up the register bit names associated with that register. Is that what you're talking about for the 24f?In my code all the pins are configured as outputs except RA3 which is input only. If I tie RA3 to ground (via a 10k resistor) the current spikes up to 290uA.RA3 floating or tied to Vdd current is ~100uA.I saw that table of current consumption last time I re-re-re-read the datasheet. So, what I should do is go through that table and ensure those things are being addressed?Could someone comment on the entries following void (main) in my attached code.Do I have them formatted correctly? Are they doing what I think (turning off those modules)?In particular an entry likeFVRCONbits.ADFVR0=0; //ADC fixed voltage reference peripheral output offFVRCONbits.ADFVR1=0; //ADC fixed voltage reference peripheral output offThat ADFVR is two bits long. Should it be specified like what is above, using ADFVR0 and ADFVR1, or should it be something else? Like ADFVR=0b00 ?Thanks again,davidk

author: bookaboo
author_rank: Frequent Contributor
timestamp: November 12, 2015, 08:32:22 pm
content: Yes the PMD bits just give a quick way of switching off all the peripherals from one command, a quick scan of your datasheet and I don't think that device has them :/I found them really handy for just the same problem you had, looks like you will manually have to make sure all unused peripherals are off, they can be on as default. Also for all port pins I found it best to make them an output and drive them low (unless you have good reason to do otherwise). Floating inputs can draw current, also remember to set as digital not analog.Page by page through the datasheet flipping bits... welcome to PIC development.

author: Maxlor
author_rank: Frequent Contributor
timestamp: November 12, 2015, 08:40:47 pm
content: I just realized I was mistaken. I actually looked at the 85°C values for power consumption, not the "Typical" ones. Whoops, sorry for the confusion.So, the correct numbers are, 4.2uA with WDT if you have the F model of the chip, and 0.8uA with WDT if you have the LF model. That sounds more useful for your application.

author: autobot
author_rank: Regular Contributor
timestamp: November 12, 2015, 08:43:05 pm
content: Davidk:>> unless anyone has a recommendation for a particular controller.silicon labs has an mbed low-power API that's sussposed to make writing low power code easy, without a need to understand the datasheet.Haven't tried it. It runs on their gecko family , which start at somethinglike 80 cents - altough i'm not sure how much memory the low-power API takes.

author: Mr Smiley
author_rank: Frequent Contributor
timestamp: November 12, 2015, 08:52:17 pm
content: Hi,Not part of your problem, but your pic wakes every 8 seconds and sleeps for 6 seconds.

author: davekra
author_rank: Contributor
timestamp: November 13, 2015, 02:27:18 am
content: AAARRRGGG!!!Well, with the register settings as listed in my first post AND using the correct voltage regulator I'm getting 2.3uA in sleep.I'd purchased two SOT23-5 regulators. One had a pin to shut it off and the other didn't. The one without the shutoff draws 1.4uA by its self and the other draws .2uA when shut down...but almost 100uA when running.I made little boards for them so I could plug them in the breadboard and they looked the same. I thought I was using the dumb one.So the pic is drawing less than 1uA while in sleep...just what I was hoping. I realize I didn't mention using a regulator in my initial post..I was concentrating on the PIC and knew I was using the regulator that only drew 14uA (or so I thought).Thanks for all the help and suggestions. It was still helpful thinking through all the stuff and getting confirmation on the way I was setting the register bits.Now to assemble the entire thing and do some more testing.Thanks again guys.davidk

author: westfw
author_rank: Super Contributor
timestamp: November 13, 2015, 06:30:38 am
content: Thanks for the update. Too many people aren't willing to embarrass themselves by admitting to silly mistakes, thereby helping to ensure that the rest of us will have to make the same silly mistakes ourselves... :-)

author: bookaboo
author_rank: Frequent Contributor
timestamp: November 13, 2015, 08:35:14 am
content: Quote from: westfw on November 13, 2015, 06:30:38 am+1

author: AndyC_772
author_rank: Super Contributor
timestamp: November 13, 2015, 08:45:04 am
content: Just as a footnote, it's probably worth mentioning a few things that can contribute to higher than expected current drain when a PIC is in standby.Any oscillator that's left running, obviously.The BOR circuit can be remarkably power hungry - but there is a 'low power' BOR too.Any pin with a pull-up that's being driven low, or vice versa. Don't forget there's a pull-up on MCLR, so if your PIC is reset by an external signal (eg. a voltage regulator with a 'power good' output), your board's power consumption could increase significantly when the PIC is in reset.By contrast, the core itself is surprisingly low power, and it may be convenient not to go to sleep at all, but instead to leave it running clocked from the internal 32k oscillator. I've done this on a number of projects; "sleep" is actually still running, but 1000x slower than usual.

author: matseng
author_rank: Frequent Contributor
timestamp: November 13, 2015, 09:34:21 am
content: Lowering the VCC will also work wonders for the power consumption. I had a quick peek at a the first datasheet i had in my datasheet forlder - the 10F220. The typical sleep current is reduced by an order of magnitude when going from 5 volts (1uA) down to 2 volts (100nA). So the actual power goes from 5000 nW down to 200 nW!

author: westfw
author_rank: Super Contributor
timestamp: November 13, 2015, 10:07:34 am
content: Is there a convenient way to reduce Vcc for low-power sleep (assuming that you still need full voltage when "on"...)

author: davekra
author_rank: Contributor
timestamp: November 13, 2015, 12:31:38 pm
content: Thanks guys. It was a dumb mistake. You get focused on something and develop tunnel vision so to speak.It's always good to have someone else proofread your important documents for the same reason. Your mind can add words that aren't there or skip ones that shouldn't be.I also think it's good to post all those register bits. In all my searches on how to sleep the examples were very vague.The datasheet has so much information that, for someone just starting in pic's, it's confusing exactly what is required and how to implement it.While some may be 'just give me the solution, I don't want to learn anything more', an example, for me, allows you to correlate it with what's in the datasheet and then start to see other things that you may have glossed over because it was incomprehensible.Reducing voltage while sleeping would be a neat idea.For my circuit I need 3v to fully turn on the FET. I suppose when it's on the code could keep the pic at full power then reduce power when off. The regulator I have has a pin to quiesce the output but not to lower the voltage.Thanks again,davidk

author: KL27x
author_rank: Super Contributor
timestamp: November 13, 2015, 09:37:30 pm
content: I had a look at your configuration, earlier. I didn't post, because AFAIC, you had turned over every single stone I had ever considered, and more. Glad it wasn't related to the PIC.QuoteCurious how you are doing that?You can use a baby NPN transistor down to 1V, I imagine. Use that to switch a PFET on the full voltage rail?Up to about 5.5V power rail, I think it might even be possible to switch a PFET from that particular PIC, even if it is running at 2V. The IO pins on many of these family PICs could do that, I think. (But don't take my word on that.) So long as you switch between digital lo and high impedance, using it like an open drain output and using a pullup to turn off the FET. Using this same principle, you could switch a PFET gate to a nominal -5V, no matter how high the rail voltage and how low the PIC voltage, provided you put a zener between the PIC and the FET that has the right value to subtract the difference?

author: davekra
author_rank: Contributor
timestamp: November 14, 2015, 02:25:01 am
content: I'm gona have to re-read your post a few more times to understand some of the things you're talking about but I do understand the small transistor to switch the FET.My hope with this circuit is to switch the FET with the controller. The FET I chose is an SI3460DVhttp://www.vishay.com/docs/71329/si3460dv.pdfIf I'm reading the datasheet right, at 2.5v it should handle 4.7amps. It will be connected to the controller via a small resistor.The Hall sensor is from Honeywell. SL353LThttp://sensing.honeywell.com/index.php/ci_id/142130/la_id/1/document/1/re_id/0Minimum voltage is 2.2v. It will be powered by one of the controllers output when it wakes from sleep.Power consumption when the FET is on is not a concern and when it's off the only thing drawing power should be the regulator and controller.Based my plan on this document..http://www.ti.com/lit/wp/slyy058/slyy058.pdfThanks,davidk

author: KL27x
author_rank: Super Contributor
timestamp: November 14, 2015, 07:18:27 pm
content: QuoteDont' bother. I am wrong.I recall using PIC at 3ishV to interface directly to 5V logic, so I was thinking the pins could tolerate up to 5V on the pins. But in hindsight, this shouldn't won't work to drive a FET. The clamping diode on the IO would pull the FET gate down to PIC supply + 0.3V, even when turned to input.Yeah, that NFET should work fine.

author: Howardlong
author_rank: Super Contributor
timestamp: November 14, 2015, 08:55:53 pm
content: Quote from: westfw on November 13, 2015, 06:30:38 amAgreed, although I was ever so slightly depressed that I didn't have time to set up a test scenario to reproduce the OP's fault, I quite enjoy doing that kind of thing with PICs, been doing them for way too many years, from PIC10 to PIC32MZ. I already had the OP's part in stock. Invariably I learn something new doing that. There's always a next time. :-)

author: davekra
author_rank: Contributor
timestamp: November 16, 2015, 02:43:16 am
content: My thinking on driving the FET was based on many examples where they connected it directly to the FET via a small resistor. As I understand it the FET input can be like a capacitor and have a large inrush current.Since the PIC drives the pins high or low the FET isn't left flapping so no pull down needed.Setting up a test environment is some work. Thank you for being willing to do that.Ultimately it wan't the PICs fault. Much of my uncertainty and frustration is with the syntax of the programming language as it relates to the PIC.When I was trying to turn off everything and the current wasn't going down I wasn't sure I was formatting something right.I found very few examples.I've got all the components working on a breadboard right now. I need to come up with stuff to test max current capacity on this little FET. I may put a diode on the output just in case someone puts an inductive load on it.Thanks guys.davidk

author: Howardlong
author_rank: Super Contributor
timestamp: November 16, 2015, 08:00:36 am
content: Quote from: davekra on November 16, 2015, 02:43:16 amYou can set up a test environment in a few minutes, although the devices I have in stock are SOT23, but mounting one on a breakout board wouldn't take more than a couple of minutes either. I also have the debug header versions of many of the low pin count PICs, although on the 10F's the debug facilities are limited, but better than nothing at all.

author: davekra
author_rank: Contributor
timestamp: November 17, 2015, 03:20:02 am
content: So I got everything together and it's working!Current draw on average is under 3uA. Not too bad.I tried to make it as small as possible and I think it came out pretty good. This one was put together by flooding the board with solder then placing the components and putting it on a hot plate.The FET has handled 2.1amps so far and more testing still needs to be done. Should handle about 4+amps but we'll see.I'll post the final code when I get back to my main computer but the vital bits for sleep are what was posted earlier.Thanks for the help.davidk

author: davekra
author_rank: Contributor
timestamp: November 17, 2015, 03:09:58 pm
content: So, to close the loop on this thread. (I hate it when OP posts 'figured it out' without posting the end result)The circuit is dead simple. Voltage regulator with a couple caps. The PIC powers the Hall sensor and the FET is driven by the PIC.This mid-range PIC wasn't a good choice because I'm not using any of it's features. A better choice may be the PIC10f200.The code starts by turning off everything not needed.It powers up for a little over 10ms to check the sensor, sleeps for 1/2 second then the watchdog timer wakes it up to check again.If anyone sees any glaring errors or better ways of doing this I'm open to suggestions.Thanks again for the help.davidkCode:/** File: newmain.c* Author: davekra** Created on October 21, 2015, 6:30 PM*/#include <xc.h>// #pragma config statements should precede project file includes.// Use project enums instead of #define for ON and OFF.// CONFIG#pragma config FOSC = INTOSC // Oscillator Selection bits (INTOSC oscillator: CLKIN function disabled)#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)#pragma config WDTE = ON // Watchdog Timer Enable (WDT enabled)#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT enabled)#pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)#pragma config CP = ON // Code Protection bit (Program memory code protection is enabled)#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)#pragma config LPBOR = OFF // Brown-out Reset Selection bits (BOR disabled)#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), high trip point selected.)#pragma config WRT = ALL // Flash Memory Self-Write Protection (000h to 1FFh write protected, no addresses may be modified by PMCON control)#define _XTAL_FREQ 32000int dely; //Declare array for countingvoid turnon(void); //Declare functionvoid turnoff(void); //Declare functionvoid main(){// CONFIGBORCONbits.SBOREN=0; //Software brown-out disabledBORCONbits.BORFS=0; //Brown-out reset fast start bit may turn offBORCONbits.BORRDY=0; //Brown-out reset circuit is inactiveINTCONbits.GIE=0; //Global interrupt disabledINTCONbits.PEIE=0; //Peripheral interrupt disabledINTCONbits.TMR0IE=0; //Timer0 overflow interrupt disabledINTCONbits.INTE=0; //INT external interrupt disabledINTCONbits.IOCIE=0; //Interrupt on change disabledPIE1bits.ADIE=0; //A/D converter interrupt disabledVREGCONbits.VREGPM1=1; //Voltage regulator power save sleep mode enabledFVRCONbits.TSEN=0; //Fixed voltage reference temperature indicator disabledFVRCONbits.FVREN=0; //Fixed voltage reference disabledFVRCONbits.FVRRDY=0; //Fixed voltage regerence output disabledFVRCONbits.ADFVR0=0; //ADC fixed voltage reference peripheral output offFVRCONbits.ADFVR1=0; //ADC fixed voltage reference peripheral output offADCONbits.ADON=0; //ADC disabledT2CONbits.TMR2ON=0; //Timer2 offPWM1CONbits.PWM1EN=0; //PWM module 1 disabledPWM2CONbits.PWM2EN=0; //PWM module 2 disabledCLC1CONbits.LC1EN=0; //Configurable logic cell 1 disabledNCO1CONbits.N1EN=0; //Numerically controlled oscillator 1 disabledCWG1CON0bits.G1EN=0; //Complementary waveform generator 1 disabledOSCCONbits.LFIOFR=1; //Low freq internal oscillator enableOSCCONbits.IRCF=0b000; //Frequency select bitsANSELA=0; //Set all ports to digitalTRISA=0; //Set all port to output. RA3 input onlyLATA = 0; // start with all output pins lowWDTCONbits.WDTPS=0b01001; //Watchdog set to 512ms//*** Main loopfor (;;){LATAbits.LATA0=1; //Turn on power to Hall__delay_ms(10); //Wait for Hall to initializeif ((PORTAbits.RA2==0)&&(PORTAbits.RA3==0)) //if FET is off, go to code to turn it onturnon(); //Call turnon functionif ((PORTAbits.RA2==1)&&(PORTAbits.RA3==0)) //FET must be on, go to code to turn it offturnoff(); //call turnoff functionLATAbits.LATA0=0; //Turn off power to HallSLEEP(); //Sleep, WDT will wake up//NOP();}}void turnon(void) //turn on function{LATAbits.LATA2=1; //Turn FET onfor (dely=0;dely<=20;dely++) //Start loop to test for button release{CLRWDT(); //Clear watchdog timer__delay_ms(20); //Wait 20ms then..if (PORTAbits.RA3==0) //If Hall still low..dely=0; //Reset count and loop again}return; //Return to main and start over}void turnoff(void) //turn off function{for (dely=0;dely<=254;dely++) //Start loop for 'button hold to turn off'{CLRWDT(); //Clear watchdog timer__delay_ms(5); //Wait 5ms then..if (PORTAbits.RA3==1) //If button released before end of loop, cancel 'turnoff'return; //Return to main and start over}LATAbits.LATA2=0; //'Button hold' loop success, turn off FETfor (dely=0;dely<=20;dely++) //Start loop to test for button release{CLRWDT(); //Clear watchdog timer__delay_ms(20); //Wait 20ms then..if (PORTAbits.RA3==0) //If Hall still low..dely=0; //Reset count and loop again}}