 |
 |
| View previous topic :: View next topic |
| Author |
Message |
Gabriel
Joined: 03 Aug 2009 Posts: 1081 Location: Panama
|
| Sleep Currents |
Posted: Sat Jun 27, 2026 9:43 am |
|
|
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 _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 20097
|
|
Posted: Sat Jun 27, 2026 11:11 am |
|
|
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
|
|
Posted: Sat Jun 27, 2026 12:05 pm |
|
|
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
|
|
Posted: Mon Jun 29, 2026 12:48 am |
|
|
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
|
|
Posted: Mon Jun 29, 2026 7:41 am |
|
|
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
|
| Re: Sleep Currents |
Posted: Tue Jun 30, 2026 2:11 am |
|
|
| 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 |
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
|
|
Posted: Tue Jun 30, 2026 12:55 pm |
|
|
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
|
|
Posted: Tue Jun 30, 2026 4:57 pm |
|
|
| 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
|
|
Posted: Tue Jun 30, 2026 6:23 pm |
|
|
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!! |
|
 |
|
|
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
|