Hope RFM95/98 power usage in sleep mode?

I did some measurements on this chip but I cannot get the power usage under 0.5mA in sleep mode.

When I remove the ground wire of the RFM95 the power usage in my setup drops to a few µA so I’m sure it is the RFM95 using power.

This should be much less, about 0.2µA according to the official PDF specs!

I’m using the Arduino-LMIC library and from what I see it really enters sleep mode. All other modes have a power consumption of at least 1.5mA.

Has anyone measured better power usage from this chip?

@tomtor

0,7 µA with “arduino-LMIC” and the command LMIC_shutdown();
Hardware: Arduino DUE 3.3V, LoRasPI V1.2a, RFM95

Without shutdown command: 1,8 mA.

No 5V to 3.3V level shifter is used in my setup.
Nothing changed from normal working conditions, only 3.3V line to RFM95 was interrupted to add a ampere meter.

0,2µA is chip only, that is the value Semtech claims for the bare chip.
RFM95 has additional parts on the breakout module, that could be a reason for the additional 0,5µA.

2 Likes

@dc2mw

Hi, thanks for your feedback.

I assume you mean 0.7 mA and not 0.7 µA?

The LMIC_shutdown() does nothing special, it just sets the chip to sleep mode (the default mode after any transmission), and cancels any callback.

LMIC_shutdown() results for me in the mentioned 0.5mA (not 0.5µA :-/ )

To clarify the way I measure: I do not measure the current through the 3.3V line to the RFM95, but measure the current for the whole setup: microcontroller + RFM95. That’s about 2µA with the RFM95 disconnected from ground (2µA is the current usage from the STM32 in DeepSleep mode) and 0.5mA with the RFM95 connected to ground.

@tomtor

I get 0.7 µA for my RFM95 in sleep mode, not mA.
This value does not include the microcontrollers current, only RF module.

@dc2mw

Thanks, just had to be sure I was not hunting a ghost.

So I’m leaking current somewhere in my setup.

Better post a schematic then :wink: .

Btw, it’s generally bad engineering practice to disconnect the ground of something you want to power off. This makes your device float and can potentially damage still connected in/outputs of the device itself or other connected devices. It also leads to current leaking through this connected I/O.

I’ve also seen power usage in the single-digit and two-digit micro-amp range for my entire node (most of which was taken by the microcontroller, I believe), so it’s definitely something in your setup.

@matthijs @epyon

Might be something SPI related which works differently on the STM32.

I assume that I may have all RFM95 SPI and IO pins floating and RFM95 NSS/RESET high while sleeping?

Have NSS/RESET lines on the RFM95 internal pullup? May I also leave them floating?

The point is that I only added the RFM95 to a working setup which used 2μA in sleep mode. :-/

I will experiment some more…

or the resistors on the i2c maybe ?

@borroz Yes, I expect something related to that. I just editted my last reply…

On most micro’s and all CMOS I/O, leaving input pins to float consumes quite a lot of power (relatively speaking). You need to pull them up to VCC or down to GND. Output pins can safely be left floating.

Pullups do not consume power if the ports or pins they are connected to are tristated or configured as an input while sleeping.

1 Like

Can confirm here. Pulled some hair until discovered DIO ports on RFM while connected to GPIO and left floating (no pulled up) were draining some 0.5mA.

@petekmet The arduino-lmic lib sets the DIO ports to INPUT.

Did you change that to INPUT_PULLUP?

Still pulling my hair :confused:

My case wasn’t with arduino-lmic, just bare SPI to RFM95 on mbed and nRF51, so I was in full control of GPIO and in my responsibility. But in your case, on arduino, something like INPUT PULLUP could be what you need. Give it a try.

If you really want to save every last nanoamp it’s better to use external pullups than internal. Or use something more 21th century than a AVR :smile: .

1 Like

@Epyon

The irony is that currently my Atmega setup works but the 21th century STM32 not :smile:
I discovered that with all pins floating (STM32 Standby mode: 2 μA) the RFM95 uses 0.39mA.

The fundamental problem is that the STM32 uses in STOP mode (GPIOs in last setting, all clocks stopped except wakeup timer) in default GPIO state 0.7 mA.
With all pins programmed to analog input (according to the STM manual the most power efficient state) 0.018 mA in the same STOP mode.

So I am currently trading reduced leakage through the RFM pins for a less efficient STM32 GPIO setting. Pulling NSS low drops the current from 0.7mA to 0.4mA so the SPI configuration is probably the root cause, but I have not found a configuration with lower usage than 0.4mA for the STM32 setup.

Perhaps additional external pull up resistors are indeed the only solution.

You’ve got yourself a real catch-22 there indeed. If you go for the analog input sleep option, using pull-ups will probably leak some current through the ADC input capacitor as well. Did you try setting all pins to digital input with internal pull-up OR digital output written low before going to sleep?

I use Freescale excuse me NXP Kinetis MK20 controllers, which are based on the same Cortex cores as the STM32, together with this excellent library for very satisfying results. The library saves the pin state, then puts all pins to output low and goes to sleep. When it wakes again, pin state is restored and the program continues as if nothing happened. The controller uses around 15µA during sleep.

1 Like

@Epyon

I’m a happy man, the total power consumption is at 12µA !

I discovered that the 5V tolerant pins used as DIO inputs consume a lot of current!
Disconnecting the unused DIO-2 and rewiring DIO-0/1 to 3.3V pins solved that.

Setting the SPI and other pins with the following code did the rest:

digitalWrite(PA5, LOW); // SCK
pinMode(PA5, OUTPUT);

digitalWrite(PA7, LOW); // MOSI
pinMode(PA7, OUTPUT);

pinMode(PA6, INPUT_ANALOG); // MISO

digitalWrite(lmic_pins.nss, LOW); // NSS
pinMode(lmic_pins.nss, OUTPUT);

// DIO Inputs
pinMode(PA3, INPUT_ANALOG);
pinMode(PB5, INPUT_ANALOG);

pinMode(lmic_pins.rst, INPUT_ANALOG);

// Serial
pinMode(PA9, INPUT_ANALOG);
pinMode(PA10, INPUT_ANALOG);
5 Likes

Ah yes, 5V tolerant pins often have an internal level shifter that does draw significant current. Didn’t know the STM32 had those pins. Excellent work!

1 Like

@epyon Another issue was the USB pullup on PA12 which I missed. :wink: It accounted for at least 0.15 mA.

Thanks for all the feedback!

1 Like