|
|
View previous topic :: View next topic |
Author |
Message |
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
how is the deep sleep? |
Posted: Thu Sep 27, 2018 5:52 pm |
|
|
Hi, I want put mode sleep the micro 18LF26K22.
This is my configuration:
Code: | #fuses HSH, NOWDT, BROWNOUT, PUT, NOPBADEN, NOHFOFST, INTRC_IO, MCLR , NOLVP
//#fuses WDT_SW //No Watch Dog Timer, enabled in Software
#use delay(internal=4MHz) |
The datasheet say the mode sleep consume 100 nA but I make the measure and take 42 uA =42000nA.
On the pcb, only solder the micro and the resistor MCLR no more... and put to sleep the micro and wake up with ext0.
What is the problem? The 100nA is theoretical?
Code: | void main(void)
{
output_toggle(LED_CMD);
delay_ms(2000);
sleep();
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 27, 2018 9:28 pm |
|
|
You can start by disabling Brownout, and set all unused i/o pins to be
low level outputs. Don't leave them as floating input pins. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Fri Sep 28, 2018 12:47 am |
|
|
PCM_programmer has covered the first key points.
If you look at the table giving the 100nA figure, this is with
Quote: |
WDT, BOR, FVR and
SOSC disabled, all
Peripherals inactive
|
You have brownout enabled. This uses 8uA....
Then the critical thing about pins, is that if they 'float' to a voltage that is in the transition region for the input, they will draw unexpected power. They need to either be driven by the PIC to a level that draws no current from the pin, or be externally biased by a resistor to a level outside this region. So assuming they are not actually connected to anything, as PCM says, drive them low.
Then your code should have a 'delay_cycles(1);' after the 'sleep' instruction. This is standard for the PIC. The instruction here is #pre-fetched' when you sleep, and needs to be a NOP. delay_cycles(1) gives this.
Now you don't show anything allowing you to wake on INT_EXT.
To do this needs something like:
Code: |
#include <18LF26K22.H>
#fuses NOWDT, BROWNOUT_NOSL, PUT, NOPBADEN, NOHFOFST, INTRC_IO, MCLR , NOLVP, NOXINST
//HSH.... No. You are using the internal RC, you don't want the HS oscillator
//enabled.
//#fuses WDT_SW //No Watch Dog Timer, enabled in Software
//Brownout now disabled when sleeping
#use delay(internal=4MHz)
#define LED_CMD PIN_B1 //whatever pin your LED is on
#byte ANSELA=getenv("SFR:ANSELA")
#byte ANSELB=getenv("SFR:ANSELB")
#byte ANSELC=getenv("SFR:ANSELC")
void main(void)
{
int ctr;
setup_adc(ADC_OFF); //Otherwise by default this will be controlling B0
setup_adc_ports(NO_ANALOGS);
setup_comparator(NC_NC_NC_NC); //disable comparator
setup_dac(DAC_OFF);
ANSELA=0;
ANSELB=0;
ANSELC=0; //select all pins for digital I/O
output_a(0); //drive all I/O pins low
output_b(0);
output_c(0);
output_high(LED_CMD); //set LED high initially
output_float(PIN_B0); //Set INT0 pin as input
delay_ms(1000); //delay so LED can be seen
while (TRUE)
{
disable_interrupts(GLOBAL);
enable_interrupts(INT_EXT); //allow INT_EXT to trigger an interrupt
//LED will need to be off here. Otherwise will draw power.
//Not sure how driven, so setting low
output_low(LED_CMD);
clear_interrupt(INT_EXT); //ensure clear before trying to sleep
sleep();
delay_cycles(1);
//will get here when INT_EXT triggers
disable_interrupts(INT_EXT);
//do something - flash LED a couple of times to show awake
for (ctr=0;ctr<4;ctr++)
{
output_toggle(LED_CMD);
delay_ms(500);
}
}
}
|
That should be close, unless I have missed something... |
|
|
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
|
Posted: Fri Sep 28, 2018 8:21 am |
|
|
Thanks you so much.. its amazing, now is 0.18uA = 180nA
now if is as said the datasheet (100nA).
Every day is for learn more... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Fri Sep 28, 2018 10:08 am |
|
|
The data sheet figure is only to one decimal. It does change with supply voltage, so is probably something like 80nA at the minimum supply, and rises to perhaps 140+uA at higher supplies. It is also 'typical', so between chips will probably vary by something like +/- 25%. So though your figure is upper end of what I'd expect, it sounds much better.
Glad you have a working figure now. |
|
|
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
|
Posted: Fri Sep 28, 2018 5:04 pm |
|
|
Ttelmah wrote: | The data sheet figure is only to one decimal. It does change with supply voltage, so is probably something like 80nA at the minimum supply, and rises to perhaps 140+uA at higher supplies. It is also 'typical', so between chips will probably vary by something like +/- 25%. So though your figure is upper end of what I'd expect, it sounds much better.
Glad you have a working figure now. |
Well. the example work very good.... my PCB is a device LoRa:
This is my example code:
Code: | #include <18LF26K22.H>
#fuses NOWDT, BROWNOUT_NOSL, PUT, NOPBADEN, NOHFOFST, INTRC_IO, MCLR , NOLVP, NOXINST
//Brownout now disabled when sleeping
#use delay(internal=4MHz)
//////////////////// UARTs ///////////////////////////////
#use rs232(baud=57600,xmit=PIN_c6,rcv=PIN_c7,bits=8,parity=N,ERRORS,stream=lora) /// UART 1 LORA
#use rs232(baud=57600,xmit=PIN_b6,rcv=PIN_b7,bits=8,parity=N,ERRORS,stream=debug) /// UART 2 DEBUG
// MAP
//*********PORTA
//none
//*********PORTB
#DEFINE BOTON1 PIN_B0 // Boton 1, (ext0)
//*********PORTC
#DEFINE RN2903_RST PIN_C4 // RESET RN2903 ( whit drive)
#DEFINE LED_CMD PIN_C5 // LED CMD
#byte ANSELA=getenv("SFR:ANSELA")
#byte ANSELB=getenv("SFR:ANSELB")
#byte ANSELC=getenv("SFR:ANSELC")
static short button_pressed=FALSE;
int8 moduleBufferIndex=0;
short messageReady=0;
unsigned char moduleResonseBuffer[64]="";
char bufferByte=0x00;
void clean_buffer();
void blink_led(int);
void main(void) {
setup_adc(ADC_OFF); //Otherwise by default this will be controlling B0
setup_adc_ports(NO_ANALOGS);
setup_comparator(NC_NC_NC_NC); //disable comparator
setup_dac(DAC_OFF);
ANSELA=0;
ANSELB=0;
ANSELC=0; //select all pins for digital I/O
output_a(0); //drive all I/O pins low
output_b(0);
output_c(0);
output_high(LED_CMD); //set LED high initially
output_float(PIN_B0); //Set INT0 pin as input
delay_ms(1000); //delay so LED can be seen
ext_int_edge(0, L_TO_H); // Set up PIC18
enable_interrupts(GLOBAL);
enable_interrupts(int_ext);
enable_interrupts(int_rda);
while (TRUE)
{
// Wake up module ... PIN MCLR High
delay_ms(1000); // wait to module it ok..
if(button_pressed) blink_led(1);
clean_buffer();
fprintf (lora,"sys sleep 4294967296\r\n"); ///49.8 dias
fprintf (debug,"to sleep\r\n"); ///49.8 dias
sleep();
delay_cycles(1);
}
}
#int_rda
void rda_isr(){
bufferByte = getchar(lora);
// See what we got
if (bufferByte == 0x0D){
moduleResonseBuffer[moduleBufferIndex] = 0x00; // Add Null terminator
messageReady=1;
moduleBufferIndex = 0; // Prepare index for next message
}
else if ( (bufferByte == 0x00) || (bufferByte == 0x0A) )
{
// Do nothing
}
else
{
moduleResonseBuffer[moduleBufferIndex++] = bufferByte; // Add Byte to Buffer
}
}
#int_ext
void ext_isr(void){
button_pressed=TRUE;
}
void clean_buffer(){
memset(moduleResonseBuffer,0x00,sizeof(moduleResonseBuffer));
moduleBufferIndex=0;
}
void blink_led(int times){
int i;
for(i=0;i<=times;i++){
output_toggle(LED_CMD);
delay_ms(10);
}
output_low(LED_CMD);
button_pressed=FALSE;
} |
I want configure all and sleep the module and sleep the pic.. if ext0 is activated, so blink led and sleep again.
But no work...
The data sheet say the pic sleep 100 nA and the module RN2903 0.0032mA... I search sleep all.
The Module only used TX, RX, MCLR for reset ... I think the power is high when use the uart. Because when I solder the module the power go since 0.001 mA to 5mA - 10 mA .... that eat any battery of 3V very soon. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sat Sep 29, 2018 2:30 am |
|
|
First thing, look at how I wake from sleep. You don't need an INT_EXT handler, if INT_GLOBAL is not enabled.
You need to put the LoRa module to sleep before you sleep the PIC. Otherwise it will sit 'idle', not asleep. Difference is idle draws about 3mA....
Look at the sys sleep command in the reference.
You will need to set it for a really long time (millions of seconds), then when the PIC wakes, send a break character followed by 0x55, which will wake it and reset it's UART baud rate automatically.
Code: |
setup_uart(FALSE, LORA); //turn off the UART
output_low(PIN_C6);
delay_us(250); //at 57600 174uSec is required for a break
output_high(PIN_C6);
setup_uart(57600, LORA); //re-enable the UART
fputc(LORA,0x55);
//The lora module will now be awake.
|
|
|
|
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
|
Posted: Sat Sep 29, 2018 7:30 am |
|
|
Thank you, I tried many for wakeup by software but no work... so to end I did with the master clear from module...
When I put fprintf (lora,"sys sleep 4294967296\r\n"); ///49.8 days
The device go to sleep, but the power is 3 to 5 mA.
I try send more command for "look" if its sleep... and not answer... I think its sleep.
Please help me to configure the pic for only sleep the module and wakeup the pic... after the module I wake with Reset Pin.
I solder all less the module on PCB try your code and the power is 0.001mA but once I solder the module even up to 20mA.
Maybe the interruption UART make up the power?
Code: | #include <18LF26K22.H>
#fuses NOWDT, BROWNOUT_NOSL, PUT, NOPBADEN, NOHFOFST, INTRC_IO, MCLR , NOLVP, NOXINST
//Brownout now disabled when sleeping
#use delay(internal=4MHz)
//////////////////// UARTs ///////////////////////////////
#use rs232(baud=57600,xmit=PIN_c6,rcv=PIN_c7,bits=8,parity=N,ERRORS,stream=LORA) /// UART 1 LORA
#use rs232(baud=57600,xmit=PIN_b6,rcv=PIN_b7,bits=8,parity=N,ERRORS,stream=debug) /// UART 2 DEBUG
//!#use standard_io(A)
//!#use standard_io(B)
//!#use standard_io(C)
#define LED_CMD PIN_C5 //whatever pin your LED is on
#byte ANSELA=getenv("SFR:ANSELA")
#byte ANSELB=getenv("SFR:ANSELB")
#byte ANSELC=getenv("SFR:ANSELC")
void wakeup();
void main(void) {
int ctr;
//! //-------------- ConfiguraciĆ³n de TRISx-----------------
//! set_tris_a(0b11111111);
//! set_tris_b(0b10111111);
//! set_tris_c(0b10000000);
setup_adc(ADC_OFF); //Otherwise by default this will be controlling B0
setup_adc_ports(NO_ANALOGS);
setup_comparator(NC_NC_NC_NC); //disable comparator
setup_dac(DAC_OFF);
ANSELA=0;
ANSELB=0;
ANSELC=0; //select all pins for digital I/O
output_a(0); //drive all I/O pins low
output_b(0);
output_c(0);
output_high(LED_CMD); //set LED high initially
output_float(PIN_B0); //Set INT0 pin as input
delay_ms(1000); //delay so LED can be seen
int i=0;
while (TRUE)
{
i++;
disable_interrupts(GLOBAL);
enable_interrupts(INT_EXT); //allow INT_EXT to trigger an interrupt
output_low(LED_CMD); //LED will need to be off here. Otherwise will draw power. //Not sure how driven, so setting low
clear_interrupt(INT_EXT); //ensure clear before trying to sleep
fprintf (LORA,"sys sleep 4294967296\r\n"); /// 49.8 dias
fprintf (debug,"to sleep %i\r\n",i); // 49.8 dias
sleep();
delay_cycles(1);
//will get here when INT_EXT triggers
disable_interrupts(INT_EXT);
//do something - flash LED a couple of times to show awake
for (ctr=0;ctr<4;ctr++){
output_toggle(LED_CMD);
delay_ms(500);
}
wakeup();
}
}
void wakeup(){
setup_uart(FALSE, LORA); //turn off the UART
output_low(PIN_C6); //
delay_us(250); //at 57600 174uSec is required for a break
output_high(PIN_C6); //
setup_uart(57600, LORA); //re-enable the UART
fprintf (LORA,"%c",0x55); // 49.8 dias
//fputc(LORA,0x55);
//The lora module will now be awake.
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sat Sep 29, 2018 10:16 am |
|
|
There is an erratum for the module, having it drawing more power than the data sheet says, but still not the level you are seeing.
You are sleeping fully so all peripherals are off. However all lines will drive to their static levels. So you need to test each I/O line and see if power is drawn when you take each line to it's driven state.
So (for instance) disable uart1, and then drive the TX line high. Does the power go up?. If it does you need to work out what is wrong with the connection. The input to the radio module should not draw any significant current. |
|
|
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
|
Posted: Sat Sep 29, 2018 10:43 am |
|
|
Thanks
I See just when I solder TX and RX to module go to 11mA .
this 2 lines are direct to pic...
How I off the uart, only put to 0 TX? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sat Sep 29, 2018 12:41 pm |
|
|
That's what I do in the wake up code.
Code: |
setup_uart(FALSE, LORA); //turn off the UART
output_low(PIN_C6);
|
This puts TX low. Used here to send a break. |
|
|
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
|
Posted: Sat Sep 29, 2018 1:59 pm |
|
|
Ttelmah wrote: | That's what I do in the wake up code.
Code: |
setup_uart(FALSE, LORA); //turn off the UART
output_low(PIN_C6);
|
This puts TX low. Used here to send a break. |
Thanks you... now if work the wakeup by software... But still all device take 3.2mA I think the module lora the michochip it not good... and that 3mA is the normal energy... Or maybe all GPIO RN2903 should be to GND
Well.. thank you the down was 20mA to 3.2mA its very good but... my wish is max 1mA... its amazing I solder all component less the module and the consume is 0.001mA... all this power it took by TX and RX...
maybe it better turn off the module before to sleep. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Sat Sep 29, 2018 2:13 pm |
|
|
Try setting both RX and TX lines on the PIC to 0 (low level). I wonder if the RF module is partially powering itself from the logic high (idle level) on the PIC's TX pin. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sun Sep 30, 2018 1:14 am |
|
|
If you do a search on the lora module, you will find a lot of threads with people having problems with their low power consumption. Honest answer best thing to do is add a FET, and turn the modules power physically off when you want low power... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Sun Sep 30, 2018 4:59 am |
|
|
and.... use a larger capacity battery.
Sounds obvious but why struggle with using a physically small battery ? All my remote (battery) devices have 'huge' batteries in them good for 5-10 years and are cheaper than a day's R&D costs to 'tweak' code and components. |
|
|
|
|
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
|