Skip to main content

You are here

Please help testing improved RFM12 driver

47 posts / 0 new
Last post

This was a small change…

Attached the new sketch requesting ack's. Power usage is about the same except for a longer duty-cicle because of the enabled receiver.

#include <JeeLib.h> #include <avr/sleep.h> #define BODS 7 //BOD Sleep bit in MCUCR #define BODSE 2 //BOD Sleep enable bit in MCUCR #define NODE_ID 20 #define RADIO_SYNC_MODE 3 #define ACK_TIME 50 #define RETRY_LIMIT 3 int data = 0xcccc; // wait a few milliseconds for proper ACK to me, return true if indeed received static byte waitForAck() { MilliTimer ackTimer; while (!ackTimer.poll(ACK_TIME)) { if (rf12_recvDone() && rf12_crc == 0 && // see rf12_hdr == (RF12_HDR_DST | RF12_HDR_CTL | NODE_ID)) return 1; set_sleep_mode(SLEEP_MODE_IDLE); // Wait a while for the reply? sleep_mode(); } return 0; } void setup() { // init RF12 and go to sleep rf12_initialize(NODE_ID, RF12_868MHZ, 212); rf12_setBitrate(0x40); // using low data rate rf12_sleep(RF12_SLEEP); ADCSRA &= ~(1<<ADEN); // turn off ADC ACSR |= _BV(ACD); // disable the analog comparator MCUCR |= _BV(BODS) | _BV(BODSE); // turn off the brown-out detector } void loop () { // going low-power rf12_sleep(RF12_SLEEP); // sleeping here rf12_setWatchdog(1000); set_sleep_mode(SLEEP_MODE_PWR_DOWN); // set the type of sleep mode to use sleep_enable(); // enable sleep mode while (! rf12_watchdogFired()) { sleep_cpu(); // nighty-night } sleep_disable(); // just woke up, disable sleep mode for safety // powering up stuff rf12_sleep(RF12_WAKEUP); // send a packet for (byte i = 0; i < RETRY_LIMIT; ++i) { while (!rf12_canSend()) rf12_recvDone(); rf12_sendStart(RF12_HDR_ACK, &data, sizeof data, RADIO_SYNC_MODE); if (waitForAck()) { break; } } ++data; }  

Could you please test this sketch?


I am away from home for a few days so things will take longer.

Where has the value (almost 50µA, as reported earlier) I thought I had reported 4.5 micro amps after the second packet went out. 3 micro amps is my de-bounce chip.

I have dug out a very poor quality meter and will do your test when I am set up here. However, ignoring absolute values as we orders of magnitude difference with stable reading.


It was my last measurement (using the scope) where I got these 50µA. So this is not accurate at all.

There is no need to hurry. I'll continue testing power consumption and also compare it with jcw's original code.


I've checked my poor quality meter and its appears reasonably accurate. With my multimeter in current mode I'm not seeing any volt drop on the 3v3 line.


With my original sketch the new RFM12.cpp/h code drops my excess consumption down to 249.1 microamps. A 0.3 microamp reduction. Now for your sketch - its easier for me if you post attachments as getting code out of web ages is a pain.


I had to tweak your 1 second to 60 seconds because my meter is rather slow.

// sleeping here rf12_setWatchdog(60000); set_sleep_mode(SLEEP_MODE_PWR_DOWN); // set the type of sleep mode to use sleep_enable(); // enable sleep mode

It idles at 1.6 - 1.5 micro-amps.

It looks like my original sketch is the problem...

I will adjust my ack routine to be the same as yours.


Good option is to get the µCurrent from - it has a very low burden voltage.

I often use a 10 Ω resistor in the ground return path and the scope in a sensitive setting (sometimes even with a 1x probe). Note that 25 mA over 10 Ω is 0.25V, which is often still acceptable.

This was another approach I've used in the past:


I have a µCurrent but haven't used it here yet.


I'm using a µCurrent too. I assume it's the µCurrent which is just too slow for these fast changing currents. Most likely it's also the µCurrent which generates this "noise" (overshooting) at the end.


@tht, although I have a µCurrent I haven't used it yet on this project. I have only used my slow auto-ranging multimeter.


If the µCurrent is causing noise I think eevblog would be interested to know about it.


Umh, I think I have found the issue. I'm not sure if I am using sleep_mode() improperly but when I replace it with your sleep_cpu my power problem goes away. My first packet goes out and I drop to my expected 4.5 micro-amps. When I create a pin change interrupt the current blips and then I settle down again to 4.5 micro-amps.

So, is it my understanding that is broken or the sleep library - be gentle.

rf12_setWatchdog(RestTime); // after ~10 s setPrescaler(8); // div 256, i.e. 1 or 8 MHz div 256 (8) = 32kHz // Sleep at slow speed set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); // Expecting to sleep for 8 seconds or any other interrupt! // sleep_mode(); sleep_cpu(); // nighty-night ///// Wake up here? /////////

Glad you found it. I actually don't know much about these sleep states. The above code is copied from an old Sketch written by jcw. It's possible that there is an even better way to power down the components.


sleep_mode(); does sleep_enable() and sleep_cpu() I think; the reference mentions that this can cause race conditions when interrupts occur. They suggest doing cli(); sleep_enable(); sei(); sleep_cpu();

Why John's sketch doesn't work with sleep_mode() I don't know; maybe it's because he issued sleep_enable() and sleep_mode(), where the first one is redundant?

Anyway: good it works now.


I'm not sure you spotted it but the first time through gives a excess power problem but the second pass through the loop process to sleep does NOT cause the power problem. Repeated loops with unacknowledged packets don't cause the problem. BUT when the time for an acknowledge packet comes around the power problem presents again as the SAME loop process sleeps.

Very odd!


The adjustments to the RFM12B code appear rock solid to me. Might we consider upgrading the Jeelib library with this version?


Premium Drupal Themes by Adaptivethemes