|
|
View previous topic :: View next topic |
Author |
Message |
championx
Joined: 28 Feb 2006 Posts: 151
|
Low power consumption |
Posted: Tue Dec 03, 2019 10:59 am |
|
|
Hi! I'm working on a project of a wireless temperature sensor, i have developed a very simple board that reads temp from a DS18B20 digital sensor, then transmit the readings over 2.4ghz using a NRF24L01.
This board is powered from a CR2032 batt, so i need to achieve the lower current consumption possible.
the thing is that i cant lower it more than 35uA.
here is the code:
Code: | #include <16f1847.h> // Selecciona el PIC
#fuses INTRC_IO,NOPROTECT, PUT, NOMCLR, WDT_SW, BROWNOUT, NOLVP, PLL_SW, NOFCMEN, NOIESO, NOSTVREN
#use delay(clock=8000000)
#use spi(mode = 0, DI=PIN_A7, DO=PIN_B7, CLK=PIN_B6, BITS=8, msb_first)
//#use fast_io(A)
//#use fast_io(B)
#define RF24_CS PIN_B4 //RC1; chipselect nRF24L01+
#define RF24_CE PIN_B3 //RC2; chipEnable nRF24L01+
#define RF24_IRQ PIN_B0 // interrupt pin
#define power_on output_high(PIN_A1)
#define power_off output_low(PIN_A1)
int data[8] = {0,0,0,0,0,0,0,0};
#include "1Wire_simple.c"
#include "DS18B20_SIMPLEc.c"
#include <driver_nrf24l01_9bytes_FAST.c>
/*******************************************************************************/
void transmit_data(int16 ID)
{
RF_TX_DATA[0] = 'Z';
RF_TX_DATA[1] = make8(ID,1);
RF_TX_DATA[2] = make8(ID,0);
RF_TX_DATA[3] = data[0];
RF_TX_DATA[4] = data[1];
RF_TX_DATA[5] = data[2];
RF_TX_DATA[6] = data[3];
RF_TX_DATA[7] = data[4];
RF_TX_DATA[8] = RF_TX_DATA[0] + RF_TX_DATA[1] + RF_TX_DATA[2] + RF_TX_DATA[3] + RF_TX_DATA[4] + RF_TX_DATA[5] + RF_TX_DATA[6]+ RF_TX_DATA[7];
if(send_shock_burst(master_add1,master_add2,master_add3,master_add4,master_add5)==1)
{
//to do
}
delay_ms(10);
flush_tx();
return;
}
/*******************************************************************************/
void main(void)
{
float temperature = 0;
int segundos_sincro = 0;
int1 debug_mode = 0;
unsigned int8 i;
unsigned int8 status;
unsigned int8 count = 0;
//set_tris_a (0b10100001); //Ra7-Ra6-Ra5-Ra4-Ra3-Ra2-Ra1-Ra0
//set_tris_b (0b00100010);
output_low(PIN_A6);
setup_adc(ADC_OFF);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
setup_vref(VREF_OFF);
setup_dac(DAC_OFF);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
init_rf();
flush_rx();
delay_ms(1000);
setup_wdt(WDT_8S);
while (1)
{
restart_wdt();
power_on;
output_high(PIN_A6);
delay_ms(10);
temperature = ds1820_read();
transmit_data(1); //just testing the transceiver
power_off;
output_low(PIN_A6);
nrf_set_power_down();
delay_ms(10);
sleep();
delay_cycles(1);
}
} |
any hint? i really don't know what else to test. I have tested putting resistors to ground or VCC on all of the unused pins.
The weird thing is if i touch the ground pin, the current lowers to 15uA... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Tue Dec 03, 2019 11:44 am |
|
|
General thing, I/O pins should not be left floating.
All the pins your code does not drive _will_ be floating. They should be
driven high or low. A floating pin will draw power whenever the level
floats between high/low. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 03, 2019 11:47 am |
|
|
Quote: | This board is powered from a CR2032 batt |
This is a nominal 3.0v battery, therefore you should be using the "LF"
version of the 16F1847. It is hugely more power-efficient than the "F".
Order a couple of them.
You should set all unused i/o pins to a low level output with:
Code: |
output_low(PIN_X);
.
.
.
output_low(PIN_Z); |
You can turn off Brownout and Watchdog during sleep using the fuses.
You should be able to get sleep current down to less than 1 ua, or
even lower if you turn off brownout and watchdog completely. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Tue Dec 03, 2019 12:01 pm |
|
|
some things to do...
off the top of my head, no particular order..
1) Use fast_IO() and set_tris()... Results in fewer operations, less power used
2) reduce clock speed... Slower clock + less power comsumed
3) delete delay_ms()... PIC 'twiddling thumbs' consumes power
4) get rid of float math... BIG consumer of energy(time+cycles)
5) 'trim' code within included files...possible a lot of unneeded code?
6) transmit temp sensor 12bits NOT a float
7) 'pack' data,to reduce bytes sent = less power used
8) read the uchip ap on saving power(2 decades+ old but real useful)
9) remove ALL LEDs !
10) read chaprt 9 - sleep mode - has some 'todo' items....
if a real project, not just a 'class project'... use a bigger battery.
Jay |
|
|
championx
Joined: 28 Feb 2006 Posts: 151
|
|
Posted: Tue Dec 03, 2019 2:38 pm |
|
|
Thanks for all the answers, i will test it tomorrow and post the results!
temtronic, thanks for the suggestions, sadly, i can't change the battery size, it is not a class project, and i need it to be light and small, so i can't use any other battery.
Thanks!! |
|
|
championx
Joined: 28 Feb 2006 Posts: 151
|
|
Posted: Sat Dec 07, 2019 10:38 pm |
|
|
Hi all! i tested your suggestions and i got 11,2uA its very good, but i think i could go lower...
I used fast_io and tris, all pins as outputs (just for testing purposes) and disconnected everything (no temp sensor, no NRF24, nothing, just the pic, some decoupling caps a resistor with a led and a pullup resistor(4k7) for onewire sensor).
I set the unused pins as output and drive them high. disabled brownout and tested disabling the wdt, but that didnt make any considerable change.
here is the code: Code: | #include <16f1847.h> // Selecciona el PIC
#fuses INTRC_IO,NOPROTECT, PUT, NOMCLR, WDT_SW, NOBROWNOUT, NOLVP, PLL_SW, NOFCMEN, NOIESO, NOSTVREN
#use delay(clock=8000000)
#use fast_io(A)
#use fast_io(B)
int data[8] = {0,0,0,0,0,0,0,0};
void main(void)
{
float temperature = 0;
int segundos_sincro = 0;
int1 debug_mode = 0;
unsigned int8 i;
unsigned int8 status;
unsigned int8 count = 0;
//set_tris_a (0b10100001); //Ra7-Ra6-Ra5-Ra4-Ra3-Ra2-Ra1-Ra0
//set_tris_b (0b00100010);
set_tris_a (0b00000000); //Ra7-Ra6-Ra5-Ra4-Ra3-Ra2-Ra1-Ra0
set_tris_b (0b00000000);
output_low(PIN_A6);
setup_adc(ADC_OFF);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
setup_vref(VREF_OFF);
setup_dac(DAC_OFF);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
delay_ms(1000);
setup_wdt(WDT_8S);
while (1)
{
restart_wdt();
output_high(PIN_A6);
delay_ms(10);
output_b(0xff);
output_a(0xff);
output_low(PIN_A6);
delay_ms(10);
sleep();
delay_cycles(1);
}
}
|
do you have any other suggestion? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Dec 08, 2019 1:33 am |
|
|
Are you using the 16F1847 or the "LF" version ? |
|
|
championx
Joined: 28 Feb 2006 Posts: 151
|
|
Posted: Mon May 18, 2020 2:02 pm |
|
|
Hi! sorry for the delay! I'm using the LF version. The strange thing is that the pic sometimes consume 33uA and if i move it to other side of the desk the current drops to 8uA.....???????? so, i assume some pin is getting "noise"... or some pin is not well drived... i will check the hardware again tonight.
Then i probably use a new board with just the pic and the minimum hardware to power it and test the code to achieve the lowest power consumption...
This thing is really driving me crazy... i have to use a CR2032 because the board has to be wearable and very small...
any suggestion will be welcome!
(sorry for my english) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Tue May 19, 2020 12:07 am |
|
|
What do you have connected to the MCLR pin?.
This does not have an output driver, so _must_ be pulled either
high or low by your hardware. |
|
|
championx
Joined: 28 Feb 2006 Posts: 151
|
|
Posted: Tue May 19, 2020 7:46 pm |
|
|
yes, the MCLR pin is drived high with a 1Mega resistor.
I stripped down the hardware to just the pic, the NRF24l01+ , a led and a tact switch connected to B0 input and a 1M pullup.
Last edited by championx on Tue May 19, 2020 8:14 pm; edited 1 time in total |
|
|
championx
Joined: 28 Feb 2006 Posts: 151
|
|
Posted: Tue May 19, 2020 8:04 pm |
|
|
well... this is really annoying... i manage to make it run using only 0.005mA but, then i move the circuit to another place and the multimeter shows 0.040ma.... |
|
|
championx
Joined: 28 Feb 2006 Posts: 151
|
|
Posted: Tue May 19, 2020 8:14 pm |
|
|
ok, done... before the sleep instruction I added a tris for each port setting all pins as outputs, only B0 (wake up) as input. And that's it... now it consumes 0.002mA everywhere! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Wed May 20, 2020 1:06 am |
|
|
As we said, 'pins must not be left floating'...
It really is vital to ensure that the pins are physically driven either high
or low, by something.
Glad you now have a starting place to making a low power system. |
|
|
championx
Joined: 28 Feb 2006 Posts: 151
|
|
Posted: Wed May 20, 2020 7:41 am |
|
|
Hi Ttelmah, thanks for your help. I thought that pins that are not connected or routed must be driven.. but even the input pins connected to other modules (in this case NRF24L01) should be set as output and drive them to a logical state.
thanks!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Wed May 20, 2020 8:06 am |
|
|
It is alright to leave them as inputs, _provided the other module is driving
them_. The key point is that a lot of 'modules' only turn on their
output pins, when they are selected.
The NRF only drives it's output pins, when the CE pin is high. |
|
|
|
|
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
|