CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Sleep Currents

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Gabriel



Joined: 03 Aug 2009
Posts: 1081
Location: Panama

View user's profile Send private message

Sleep Currents
PostPosted: Sat Jun 27, 2026 9:43 am     Reply with quote

Hi all,

Im developing a Temperature LORA sensor.
I have a custom board with a PIC18F47Q84, EEPROM, and RTC to wake up via EXT INT.
The board is powered by 3x 18650s (paralleled) through a MCP1700 LDO.
Im using the RYLR896 radio and BME280 as the sensor.

I cant get sleep Current under 0.100mA which is absurd - or maybe i hit my boards limit? i refuse to belive this, and battery life obviously sucks when i have such a large bank.

Edit: also ive taken care of checking every pull up on the board, to ensure none are kept low during sleep, this was happening with botht the RTCs interrupt pins... huge current gains obviously.

Edit_2: fuses

Code:
#include <18F47Q84.h>
#device PASS_STRINGS=IN_RAM
#device adc=8
#fuses MCLR
#fuses NOWDT
#fuses NOLVP
#fuses NOXINST
#fuses NODEBUG
#fuses NOBROWNOUT
#fuses NOLPBOR
#fuses NOPROTECT
#fuses HS
#fuses RSTOSC_EXT_PLL
#use delay(clock=64MHz)


CODE:


Code:

disable_interrupts(INT_RDA);
                sleep(SLEEP_FULL|REG_LOW_POWER);
                delay_ms(2);
                setup_oscillator(OSC_EXTOSC_PLL|OSC_CLK_DIV_BY_1|OSC_PLL_ENABLED|OSC_EXTOSC_READY);
                delay_ms(1);


this is my sleep "method".

ive taken particular care to disable everything i can think of. i even have a function called "Disable_Everthing();"
PIN BY PIN!


Code:

void Disable_Everything()
{
    setup_wdt(WDT_OFF);
    setup_ccp1(CCP_OFF);
    setup_ccp2(CCP_OFF);
    setup_ccp3(CCP_OFF);
    setup_counters(RTCC_OFF,RTCC_DIV_1);
    setup_timer_0(T0_OFF);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,0);
    setup_timer_3(T3_DISABLED);
    setup_timer_4(T4_DISABLED,0,0);
    setup_timer_5(T5_DISABLED);
    setup_timer_6(T6_DISABLED,0,0);
    setup_pwm1(PWM_DISABLED);
    setup_pwm2(PWM_DISABLED);
    setup_pwm3(PWM_DISABLED);
    setup_pwm4(PWM_DISABLED);
    setup_spi(SPI_DISABLED);
   
    setup_clc1(CLC_DISABLED);
    setup_clc2(CLC_DISABLED);
    setup_clc3(CLC_DISABLED);
    setup_clc4(CLC_DISABLED);
    setup_clc5(CLC_DISABLED);
    setup_clc6(CLC_DISABLED);
    setup_clc7(CLC_DISABLED);
    setup_clc8(CLC_DISABLED);
   
    setup_smt1(SMT_DISABLED);
    setup_smt2(SMT_DISABLED);
   
    setup_dsm(DSM_DISABLED);
   
           
#ifdef VERSION_1
    input(BAT_SENS); //A0
#endif
   
#ifdef VERSION_2
    setup_comparator(NC_NC_NC_NC);
    setup_vref(VREF_OFF);
    setup_dac(DAC_OFF);
    output_low(PIN_A2);
#endif   
   
  //output_low(PIN_A0);  //LECTURA DE BAT
    output_low(PIN_A1);
  //output_low(PIN_A2);  //OFF EN V.2 y INPUT en V.1
    output_low(PIN_A3);
    output_low(PIN_A4);
    output_low(PIN_A5);
   
  //output_low(PIN_B0);  //INTERRUPT
  //output_low(PIN_B1);  //INTERRUPT
    output_low(PIN_B2);
   output_high(PIN_B3);  //LORA RESET
  //output_low(PIN_B4);  //LORA UART
  //output_low(PIN_B5);  //LORA UART
    output_low(PIN_B6);
    output_low(PIN_B7);
 
    output_low(PIN_C0);  //FTDI   
    output_low(PIN_C1);  //FTDI 
    output_low(PIN_C2);
  //output_low(PIN_C3);  //I2C 
  //output_low(PIN_C4);  //I2C   
    output_low(PIN_C5);
    output_low(PIN_C6);
    output_low(PIN_C7);
   
   
    output_low(PIN_D0);
    output_low(PIN_D1);
   
#ifndef USE_DS
    output_low(PIN_D2);
    output_low(PIN_D3);
#endif
    output_low(PIN_D4);
    output_low(PIN_D5);
    output_low(PIN_D6);
    output_low(PIN_D7);
   
    output_low(BAT_SENS_ENABLE); //E0/enable in V.1
    output_low(PIN_E1);
    output_low(PIN_E2); 
}


im on my second revision of the board, the previous used an opamp and internal DAC to check the 18650 voltage indirectly... that was costing me about 0.400mA! - thats gone now - i managed to get that board revision down to 0.250mA.

still crazy sleep currents.

what am i missing? getting down to 0.050mA would be a huge win a this point.

thanks,
G
Code:

_________________
CCS PCM 5.078 & CCS PCH 5.093
Ttelmah



Joined: 11 Mar 2010
Posts: 20097

View user's profile Send private message

PostPosted: Sat Jun 27, 2026 11:11 am     Reply with quote

What commands are you sending to the LoRa module to put it to sleep????
If it is staying awake, it'd explain a lot of this. You need to send the
sleep command to the module.
Also the MCP1700, is a low power regulator, but is a linear regulator. So
will waste you quite a lot of power.
Also you don't show how you are programming the BME. If it is left in
continuous sample mode, as opposed to being put back into sleep mode
it'll draw a lot more current.
How is the PIC being woken up?. What interrupt are you using?.
Remember interrupts need to be cleared before you sleep, or the chip
won't sleep but will awake immediately.
Gabriel



Joined: 03 Aug 2009
Posts: 1081
Location: Panama

View user's profile Send private message

PostPosted: Sat Jun 27, 2026 12:05 pm     Reply with quote

hi Ttelmah!

for the lora im just using the AT command sleep:
Code:
fprintf(LORA,"AT+MODE=%u\r\n",LORA_SLEEP);


LORA_SLEEP is defined as 1 - mode 1 is sleep.

im using EXT and EXT1 to wake up.
for context: the RTC has a Minute alarm, and a seconds alarm.
I wake up every minute, go back to sleep for random amount of seconds, and then transmit... as a transmission overlap avoidance method (i have multiple of these sensors laying around).

ext1 on the minute alarm, ext on the seconds.


for the BME its in single shot mode - however i have this code setup to work with S17021, DS18B20, and BME280 (i like having choices) - same issue across the sensor line - witht the DS18B20 i even go as far a removing power with a dedicated pin - same issue.

I am NOT clearing the interrupts, thank you for that.
i will test and report!

thank you!
G
_________________
CCS PCM 5.078 & CCS PCH 5.093
Ttelmah



Joined: 11 Mar 2010
Posts: 20097

View user's profile Send private message

PostPosted: Mon Jun 29, 2026 12:48 am     Reply with quote

As one extra comment, the instruction after the sleep, should be
delay_cycles(1); not the delay_ms you have. This needs to be a NOP
instruction, and this is what delay_cycles gives. The delay_ms will
probably be putting the wrong code at this point.
The point here is that the following instruction, has been already fetched
when the processor goes to sleep. It must be a 'do nothing' instruction,
or problems can result.
jeremiah



Joined: 20 Jul 2010
Posts: 1418

View user's profile Send private message

PostPosted: Mon Jun 29, 2026 7:41 am     Reply with quote

Besides turning off the registers, have you looked into the PMD (Peripheral Module Disable)? I don't know pic18s well, but on pic24's this disconnects the modules from power (meaning if you enable them, you need to re-init the registers again).

In our low power boards we generally disable everything we can, even stuff we plan to use, then turn off the disable when we are about to use the peripherals and disable them after we are done.

Also, what is the value of your VREGPM register? that has a huge impact on your sleep current (see section 50.3.3 of the data sheet)
asmallri



Joined: 12 Aug 2004
Posts: 1670
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

Re: Sleep Currents
PostPosted: Tue Jun 30, 2026 2:11 am     Reply with quote

Gabriel wrote:
Hi all,

Im developing a Temperature LORA sensor.
I have a custom board with a PIC18F47Q84, EEPROM, and RTC to wake up via EXT INT.
The board is powered by 3x 18650s (paralleled) through a MCP1700 LDO.
Im using the RYLR896 radio and BME280 as the sensor.

I cant get sleep Current under 0.100mA which is absurd - or maybe i hit my boards limit? i refuse to belive this, and battery life obviously sucks when i have such a large bank.

Edit: also ive taken care of checking every pull up on the board, to ensure none are kept low during sleep, this was happening with botht the RTCs interrupt pins... huge current gains obviously.

Edit_2: fuses

Code:
#include <18F47Q84.h>
#device PASS_STRINGS=IN_RAM
#device adc=8
#fuses MCLR
#fuses NOWDT
#fuses NOLVP
#fuses NOXINST
#fuses NODEBUG
#fuses NOBROWNOUT
#fuses NOLPBOR
#fuses NOPROTECT
#fuses HS
#fuses RSTOSC_EXT_PLL
#use delay(clock=64MHz)


CODE:


Code:

disable_interrupts(INT_RDA);
                sleep(SLEEP_FULL|REG_LOW_POWER);
                delay_ms(2);
                setup_oscillator(OSC_EXTOSC_PLL|OSC_CLK_DIV_BY_1|OSC_PLL_ENABLED|OSC_EXTOSC_READY);
                delay_ms(1);


this is my sleep "method".

ive taken particular care to disable everything i can think of. i even have a function called "Disable_Everthing();"
PIN BY PIN!


Code:

void Disable_Everything()
{
    setup_wdt(WDT_OFF);
    setup_ccp1(CCP_OFF);
    setup_ccp2(CCP_OFF);
    setup_ccp3(CCP_OFF);
    setup_counters(RTCC_OFF,RTCC_DIV_1);
    setup_timer_0(T0_OFF);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,0);
    setup_timer_3(T3_DISABLED);
    setup_timer_4(T4_DISABLED,0,0);
    setup_timer_5(T5_DISABLED);
    setup_timer_6(T6_DISABLED,0,0);
    setup_pwm1(PWM_DISABLED);
    setup_pwm2(PWM_DISABLED);
    setup_pwm3(PWM_DISABLED);
    setup_pwm4(PWM_DISABLED);
    setup_spi(SPI_DISABLED);
   
    setup_clc1(CLC_DISABLED);
    setup_clc2(CLC_DISABLED);
    setup_clc3(CLC_DISABLED);
    setup_clc4(CLC_DISABLED);
    setup_clc5(CLC_DISABLED);
    setup_clc6(CLC_DISABLED);
    setup_clc7(CLC_DISABLED);
    setup_clc8(CLC_DISABLED);
   
    setup_smt1(SMT_DISABLED);
    setup_smt2(SMT_DISABLED);
   
    setup_dsm(DSM_DISABLED);
   
           
#ifdef VERSION_1
    input(BAT_SENS); //A0
#endif
   
#ifdef VERSION_2
    setup_comparator(NC_NC_NC_NC);
    setup_vref(VREF_OFF);
    setup_dac(DAC_OFF);
    output_low(PIN_A2);
#endif   
   
  //output_low(PIN_A0);  //LECTURA DE BAT
    output_low(PIN_A1);
  //output_low(PIN_A2);  //OFF EN V.2 y INPUT en V.1
    output_low(PIN_A3);
    output_low(PIN_A4);
    output_low(PIN_A5);
   
  //output_low(PIN_B0);  //INTERRUPT
  //output_low(PIN_B1);  //INTERRUPT
    output_low(PIN_B2);
   output_high(PIN_B3);  //LORA RESET
  //output_low(PIN_B4);  //LORA UART
  //output_low(PIN_B5);  //LORA UART
    output_low(PIN_B6);
    output_low(PIN_B7);
 
    output_low(PIN_C0);  //FTDI   
    output_low(PIN_C1);  //FTDI 
    output_low(PIN_C2);
  //output_low(PIN_C3);  //I2C 
  //output_low(PIN_C4);  //I2C   
    output_low(PIN_C5);
    output_low(PIN_C6);
    output_low(PIN_C7);
   
   
    output_low(PIN_D0);
    output_low(PIN_D1);
   
#ifndef USE_DS
    output_low(PIN_D2);
    output_low(PIN_D3);
#endif
    output_low(PIN_D4);
    output_low(PIN_D5);
    output_low(PIN_D6);
    output_low(PIN_D7);
   
    output_low(BAT_SENS_ENABLE); //E0/enable in V.1
    output_low(PIN_E1);
    output_low(PIN_E2); 
}


im on my second revision of the board, the previous used an opamp and internal DAC to check the 18650 voltage indirectly... that was costing me about 0.400mA! - thats gone now - i managed to get that board revision down to 0.250mA.

still crazy sleep currents.

what am i missing? getting down to 0.050mA would be a huge win a this point.

thanks,
G
Code:


A have done a lot of work in this area building a Wildland Fire (Bush Fire) warning system as detailed here -> www.thingy-iot.au. If you would like to share your schematic I will review it for you.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Gabriel



Joined: 03 Aug 2009
Posts: 1081
Location: Panama

View user's profile Send private message

PostPosted: Tue Jun 30, 2026 12:55 pm     Reply with quote

Hi,

Clearing the interrupts, both inside the ISR and again right before the sleep instruction did not change anything.

Ive also added the delay_cycles(1); right after the sleep instrucction but i still at 0.110ish mA.

I read the comment about the VREGPM and i belive this is addressed by the ORed option here:
Code:
sleep(SLEEP_FULL|REG_LOW_POWER);
specifically the REG_LO_POWER - am i wrong to assume this?

I frankly do not know how to operate the PMD.
does CCS have any instructions for this? i searched the manual, no mention of PMD
_________________
CCS PCM 5.078 & CCS PCH 5.093
newguy



Joined: 24 Jun 2004
Posts: 1942

View user's profile Send private message

PostPosted: Tue Jun 30, 2026 4:57 pm     Reply with quote

Look in the data sheet of your processor. If it has peripheral module disable capability, it will be detailed there.
asmallri



Joined: 12 Aug 2004
Posts: 1670
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Jun 30, 2026 6:23 pm     Reply with quote

I realise you want to reduce the sleep current. But aside from that, for a very low power device, why are you running the clock so fast?

From the code snippet, there are lots of I/O lines that are not initialised because they are commented out. By default, non initialised I/O are inputs and if they are left floating, can result in higher currents.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group