Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP.deepSleep(xxxx, WAKE_NO_RFCAL) not working since 2.0.0 #3408

Closed
wb8wka opened this issue Jul 9, 2017 · 99 comments
Closed

ESP.deepSleep(xxxx, WAKE_NO_RFCAL) not working since 2.0.0 #3408

wb8wka opened this issue Jul 9, 2017 · 99 comments
Labels
component: core type: bug waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.

Comments

@wb8wka
Copy link

wb8wka commented Jul 9, 2017

Summary

RF Calibration cannot be turned off after 2.0.0 in wake from deepSleep causing current spike and longer boot

Hardware

Hardware: Wemos D1 mini and ESP-12S, 470uf cap between Vcc and Ground
Core Version: 2.0.0 (works - No RF Calibration current spike), 2.3.0 (Not working, current spike)
Test equipment: Rigol Scope, 1ohm current shunt, "fuzz" is because I didn't do calibration on scope but traces are accurate.

Description

Using identical code function ESP.deepSleep(6000000, WAKE_NO_RFCAL); in 2.0.0 ESP can wakeup without large current spike from RF_CAL, however after 2.0.0 RF_CAL executes causing large current spike and longer run time. Please see attached current traces. Correct data is sent in both instances, only different is current spike, which appears to be RF_CAL executing.

Sketch sends simple beacon using wifi_send_pkt_freedom. GPIO16 connected to reset.

WAKE_RF_DISABLED does behave as expected in both 2.0.0 and 2.3.0

Also

system_deep_sleep_set_option(2);  // Option 2 is WAKE_NO_RFCAL
//system_deep_sleep(6000000);
system_deep_sleep_instant(6000000);  //  Trims 98ms off go to sleep

has same characteristics in that it cannot turn off RF_CAL

Settings in IDE

Module: WeMos D1 Mini & ESP-12S
Flash Size: 4MB
CPU Frequency: 80Mhz
Flash Mode: qio
Upload Using: SERIAL

Images

061517_1ohm_100mvdiv

Version 2.0.0 without RF_CAL current spike at head

060917_1ohm_100mvdiv

Version 2.3.0 with RF_CAL current spike at head

Sketch


#include <ESP8266WiFi.h>
#include <WiFiClient.h> 
extern "C" {
  #include "user_interface.h"
// (Commented out code below for 2.0.0 to expose send_pkt_freedom, not needed in 2,3.0
//  typedef void (*freedom_outside_cb_t)(uint8 status);
//  int wifi_register_send_pkt_freedom_cb(freedom_outside_cb_t cb);
//  void wifi_unregister_send_pkt_freedom_cb(void);
//  int wifi_send_pkt_freedom(uint8 *buf, int len, bool sys_seq);
  void system_deep_sleep_instant(uint32 time_in_us);
}


byte channel;
byte RandomMac = 1; 
byte SequenceLSB = 0;
byte SequenceMSB = 0;
                 

// Packet I am sending
uint8_t packet[128] = { ......   68 bytes,,,,  };      // Obscured for example                                          


void setup() {
  delay(2);   // in this group was all 50
  wifi_set_opmode(STATION_MODE);
  delay(2);
  wifi_promiscuous_enable(1);     // need
  delay(2);
  system_phy_set_max_tpw(20);    //the maximum value of RF Tx Power, unit : 0.25dBm, range [0, 82] 19dBm = 76, 10dBm = 40, 14 dBm = 56
  delay(2);
}



void loop() {


    wifi_set_channel(1);
    delay(2);     // Delay in MS, was 20
    wifi_send_pkt_freedom(packet, 68, 0);
    //Increment fragment
    //Set fragment
    packet[22] = (SequenceLSB + 1);
    delay(10);     // Delay in MS
    wifi_send_pkt_freedom(packet, 68, 0);
    delay(10);     // Delay in MS
    SequenceLSB = (SequenceLSB & 0xF0);
    packet[22] = SequenceLSB;

    wifi_set_channel(6); 
    delay(2);     // Delay in MS
    wifi_send_pkt_freedom(packet, 68, 0);
    delay(10);     // Delay in MS
    //Increment fragment
    //Set fragment
    packet[22] = (SequenceLSB + 1);
    wifi_send_pkt_freedom(packet, 68, 0);
    delay(10);     // Delay in MS
    SequenceLSB = (SequenceLSB & 0xF0); 
    packet[22] = SequenceLSB;


    wifi_set_channel(11); 
    delay(2);     // Delay in MS
    wifi_send_pkt_freedom(packet, 68, 0);
    delay(10);     // Delay in MS
    //Increment fragment
    packet[22] = (SequenceLSB + 1);
    wifi_send_pkt_freedom(packet, 68, 0);
    delay(2);
   
/// ESP.deepSleep(microseconds, mode) will put the chip into deep sleep. mode is one of WAKE_RF_DEFAULT, WAKE_RFCAL, WAKE_NO_RFCAL, WAKE_RF_DISABLED.

    ESP.deepSleep(6000000, WAKE_NO_RFCAL); // Sleep for 6 seconds,


    //system_deep_sleep_set_option(2);
    //system_deep_sleep(6000000);
    //system_deep_sleep_instant(6000000);
 
}


@wb8wka
Copy link
Author

wb8wka commented Jul 11, 2017

Also tried 2.4.0-rc1, same issue.

@5chufti
Copy link
Contributor

5chufti commented Aug 2, 2017

why didn't you post your results on espressif ESP8266 NON_OS_SDK github? Or make a thread on their BBS
It's their tree to bark up ...

@wb8wka
Copy link
Author

wb8wka commented Aug 2, 2017

Because it works fine on the NON_OS_SDK. It's an Arduino lib issue. Their tree but it appears abandoned at this point. We've now moved onto NON_OS_SDK

thanks for your interest

@5chufti
Copy link
Contributor

5chufti commented Aug 2, 2017

but using the system_ ... calls accesses the sdk libs directly. Especially when using system_deep_sleep_instant(); I can't think of which arduino lib should interfere with the correct execution of deepsleep with wake_no_rfcal ...

edit: did you try to read the rf_cal byte before the deepsleep call and after bootup?

@wb8wka
Copy link
Author

wb8wka commented Aug 2, 2017

I wasn't reporting a issue with the SDK libs being used directly, I was reporting a change in behavior with:

ESP.deepSleep(6000000, WAKE_NO_RFCAL)

Between Arduino 2.0.0 and later versions

The system calls noted were commented out and just my earlier experimenting. The code posted behaved differently between 2.0.0 and 2.3.0 in that you couldn't during off RF Calibration after a wake from a deep sleep, using arduino calls, after 2.0.0

@5chufti
Copy link
Contributor

5chufti commented Aug 3, 2017

according to the starting post

Also

system_deep_sleep_set_option(2); // Option 2 is WAKE_NO_RFCAL
//system_deep_sleep(6000000);
system_deep_sleep_instant(6000000); // Trims 98ms off go to sleep

has same characteristics in that it cannot turn off RF_CAL

you say that the direct use of system_... has the same problem, this is why I suggested to report to espressif directly.

@wb8wka
Copy link
Author

wb8wka commented Aug 3, 2017

I'm not quite sure why you don't understand me

This is the Github site for reporting issues with the Arduino port. The issue is with the Arduino command

ESP.deepSleep(6000000, WAKE_NO_RFCAL)

NOT the system calls even though I had issues calling them from the arduino code. That could just as easily be operator error on my part and I wasn't reporting those.

Howver I have confirmed the system call's (i.e. system_deep_sleep_instant(6000000);) work fine directly under the NON_OS_SDK. There is nothing to report to espressif because the SDK is doing what it is supposed to.

Sometime after 2.0.0 ESP.deepSleep(xxxxx, WAKE_NO_RFCAL) stop turning off the RF calibration on wake.

If you like I can go back and remove all the commented code out of my example. I had just been trying to test various things.

@5chufti
Copy link
Contributor

5chufti commented Aug 3, 2017

with the parts I quoted from your OP you say that the same problem exists calling the system_ ... functions (not having problems calling them) leading to the assumption that this might be the root cause.
Since looking at code for ESP.deep_sleep() you'll see that it does practically the same... and hasn't changed for quite some time.
but believe me, I couldn't care less .....

@wb8wka
Copy link
Author

wb8wka commented Aug 3, 2017

For not "couldn't caring less" you sure seemed to want to argue this

None-the-less it's a real issue and my testing is solid. That it persisted through a few versions before being reported is irrelevant.

Hook your scope up and confirm it yourself if you doubt me

@universam1
Copy link

I can confirm that ESP.deepSleep(x, WAKE_RFCAL) is broken in that sense that it does not restart the mcu at all.

@5chufti
Copy link
Contributor

5chufti commented Nov 7, 2017

@universam1
hmm, working like a clockwork on latest master.
is it only WAKE_RFCAL? also via direct sdk call?
which core/sdk version are you using?
gpio16 - rst are connected?

@igrr
I can now confirm that WAKE_RF_NOCAL is broken, via
ESP.deepSleep();
as well as
system_deep_sleep_set_option();
system_deep_sleep();

#include "user_interface.h"
}
void setup() {
  delay(500);
  ESP.deepSleep(1000000,WAKE_NO_RFCAL);
//  system_deep_sleep_set_option(RF_NO_CAL);
//  system_deep_sleep(1000000);
  delay(10);  
}

void loop() {
}

I can't test on plain sdk to see if its the arduino core or the sdk, most likely some "glue"
It works with core 2.0.0 & sdk 1.3.0_15_08_10_p1
it stops working on core 2.0.0 & sdk 1.5.1_16_01_08
and still won't work on recent master.

here it is ok, no spikes on startup
2 0 0_1 3 0
obvious spikes from RF_CALI at ~200ms longer startup
2 2 0_1 5 1
p.s.: WAKE_RF_DISABLED is still working as expected
master_2 1 0

@universam1
Copy link

I have to revert my statement a bit. So with older SDK a mere reboot did work ESP.deepSleep(1, WAKE_RFCAL) with a 1us delay, this is not working any more, I have to specify >1000us for a reliable restart.

@wb8wka
Copy link
Author

wb8wka commented Jan 5, 2018

Good grief 5chufti, this is what I reported back in July....

@5chufti
Copy link
Contributor

5chufti commented Jan 5, 2018

Good grief 5chufti, this is what I reported back in July....

very helpfull remark ...

you didn't report this
It works with core 2.0.0 & sdk 1.3.0_15_08_10_p1
it stops working on core 2.0.0 & sdk 1.5.1_16_01_08

and I think it is relevant

@wb8wka
Copy link
Author

wb8wka commented Jan 5, 2018 via email

@devyte
Copy link
Collaborator

devyte commented Jan 5, 2018

@wb8wka I assume this is still relevant after 2.4.0 release, and I also assume you erased the whole flash before upload. You said there is no issue with using only the NONOS SDK system calls. Is this true when using pure system calls from within a simple sketch, or did you mean from a NONOS SDK standalone build without the Arduino core? Could you please pist an example?

@wb8wka
Copy link
Author

wb8wka commented Jan 6, 2018

@devyte That would be my guess. 2.4.0rc1 I tried and it the issue was still there, Reviewing the change log for 2.4.0 I see no mention of a fix.

I meant it worked with the NONOS SDK standalone build Here is a little clip

#define CAL_OPT 2

// This function executes before WiFi is set up
void user_rf_pre_init (void)
{
  // Set no RF cal
  system_deep_sleep_set_option (CAL_OPT);
  system_phy_set_powerup_option (CAL_OPT);
  system_phy_set_rfoption (CAL_OPT);
}


    wifi_send_pkt_freedom(packet, PACKET_SIZE, 0);

@igrr
Copy link
Member

igrr commented Jan 6, 2018

I think I have a fix for this, but need some time to set up a current measurement jig...

@5chufti
Copy link
Contributor

5chufti commented Jan 28, 2018

@igrr did you get somewhere with your investigations?

@sysoleg
Copy link

sysoleg commented Apr 5, 2018

@igrr any news on the issue? Maybe some pointers for workaround?

@sysoleg
Copy link

sysoleg commented Apr 5, 2018

@wb8wka have you tried something like this?

extern "C" void __run_user_rf_pre_init(void) {
    system_phy_set_rfoption(2);
}

@torntrousers
Copy link
Contributor

torntrousers commented Apr 26, 2018

It would be great to get a fix for this @igrr , could we help by testing out the fix you think you have?
Or do you even need a current measurement jig - it should be much faster starting up with WAKE_NO_RFCAL so a sketch like this shows if its working or not (for me at 2.0.0 it shows setup starts in 43 milliseconds compared to about 200 in later releases):

#include <ESP8266WiFi.h>

void setup() {
    unsigned long ms = millis();
    Serial.begin(115200); Serial.println();
    Serial.print("Setup time:"); Serial.println(ms);

//    ESP.deepSleep(3000000); 
    ESP.deepSleep(3000000, WAKE_NO_RFCAL); 
}

void loop() {
}

@torntrousers
Copy link
Contributor

or even any hints at what the possible fix mentioned here - #3408 (comment) - could be so we could try to implement the fix ourselves?

@torntrousers
Copy link
Contributor

I'd so much like to find a fix for this. Could anyone give any hints on where abouts in the code I could be looking for the problem?

@ludiazv
Copy link

ludiazv commented May 23, 2018

Any news on this issue? This is critical for battery power applications.

Regards,

@torntrousers
Copy link
Contributor

@igrr sorry to keep pestering I know you must be busy on things but you did say earlier you thought you might know the cause of this so could you give any hints so we could try to find some fix?

@ludiazv
Copy link

ludiazv commented May 31, 2018

A hint on the root cause will be very usefull.

On the other hand a possible work arround would be to modify the 108th byte of the init data (defined in core_esp8266_phy.c) and set it to 255. In principle this will make a call woth WAKE_RF_DEFAULT to calibrate the radio only once every 255 reboots from sleep.

Is there any way to change this byte without patching the core? If not it could included with a similar macro to ADC_MODE/RF_MODE.

@torntrousers
Copy link
Contributor

It seems difficult to work this out with out any doc on what the rtc reg 24 and 30 are supposed to be for.
Adding this to an sketch:

RF_PRE_INIT() {
    volatile uint32_t* rtc_reg = (volatile uint32_t*) 0x60001000;
    rtc_reg[24] &= 0xFFFF;
}

Appears to get RF_CAL to run again. But both rtc_reg[24] and rtc_reg[30] are xFFFFFFFF on wake up no matter what sleep mode was used to put the ESP to deepSleep.

@Ivoatme
Copy link

Ivoatme commented Aug 20, 2018

I came late to the party and so I am having a hard time replicating what is ben reported. It would be helpful to have one common set of code against everyone is testing. This way if there are different results for some reason it can be nailed down why that is.
For example, there is set up time during the ESP boot for a state of GPIO to change, so timing the GPIO externally may not show the full story about the boot time. Same with the timers, there is a set up time and it is not a constant. I am set up with hardware to take accurate measurements if anyone if interested to put up the test bed code and more info what version of SDK I should run it with.
Next as a curiosity... when running ESPNOW it looks like the #include <ESP8266WiFi.h> is not necessary for the ESPNOW to work. Can anyone test or give an opinion on that? It works fine for me w/o and as a result I get faster boot up albeit only little. @torntrousers ?

@torntrousers
Copy link
Contributor

torntrousers commented Aug 21, 2018

@Ivoatme the sketch I use for timing an esp-now sensor is here: https://github.com/HarringayMakerSpace/ESP-Now/blob/master/espnow-sensor-timing/espnow-sensor-timing.ino

For me that outputs:

send_cb, send done, status = 0
Boot: 24 ms, setup: 28 ms, send: 28 ms, now 29 ms, going to sleep for 35 secs...

with slight variability in the 'now' time going to 30 or 31 ms sometimes.

Would be interesting to have someone with a scope do a complete plot of the power usage and timing of the entire wake-send-sleep cycle. Or also see if there are any other savings somewhere, maybe removing all the use of Serial?

@ludiazv
Copy link

ludiazv commented Aug 21, 2018

Great example @torntrousers! One caveat, running at 160Mhz has no point here as the task is mainly IO waiting time. Have in mind that a esp (with RF disabled consume 20mA at 80Mhz but about 35mA at 160Mhz). To ilustrate the net effect, lets say that the gain of executing at full speed is 10m less time that running at 80Mhz. Then it would be detrimental for the battery life;

  1. 80Mhz -> 20mA* (30+10) / 1000 = 0,8 mA/sec
  2. 160Mhz -> 35mA* 30/1000 = 1.05 mA/sec
    (using second scale for readability)

as you can see the extra power consumed at 160 Mhz will offet the speed gain of 10ms.

The same argument affects the flash chip, it will consume more at 80Mhz. Here will depend on the actual chip and mesurement will be needed on your specific board. Also there cheap versions of the ESP12 that have trouble with 80Hz as they use low quality. I suposse that using QIO will be power neutral it only using a pair of addtional datalines to speak with the flash. The problem is that not all ESP boards out there implement QIO.

@torntrousers
Copy link
Contributor

Good point @ludiazv . And trying now the faster speeds don't actually make much of a difference now anyway, i think when I tried them before it was with bigger sketch and rf_cal running.

@Ivoatme
Copy link

Ivoatme commented Aug 21, 2018

@Ivoatme
Copy link

Ivoatme commented Aug 21, 2018

Several observations here...

  1. the power "cost" in the above is ~ 8 mA/s
  2. with this version this solution can not be used when gating the power because only the subsequent transmissions (after the first power up) "behave" this way, so if you are transmitting only one reading per sleep cycle and the power is interrupted the power cost is significantly greater.
    Perhaps there is a way to save and retain the registers settings on power-up.

@mailgpa
Copy link

mailgpa commented Aug 21, 2018

RF_CAL seems to be working fine if any changes to rtc_reg are disabled completely. That's how user_rf_pre_init() looks in my setup:

void user_rf_pre_init()
{
    // *((volatile uint32_t*) 0x60000710) = 0;
    spoof_init_data = false;
    /*
    volatile uint32_t* rtc_reg = (volatile uint32_t*) 0x60001000;
    if((rtc_reg[24] >> 16) > 4) {
        rtc_reg[24] &= 0xFFFF;
        rtc_reg[30] = 0;
    }
    */

    system_set_os_print(0);
    int rf_mode = __get_rf_mode();
    if (rf_mode >= 0) {
        system_phy_set_rfoption(rf_mode);
    }
    __run_user_rf_pre_init();
}

@devyte
Copy link
Collaborator

devyte commented Aug 22, 2018

All, I'm now a bit lost with regard to which code is best for low power, or which set up is best, etc. At this time I'd like to ask you for a PR with an example sketch for lowest power, so that we can include it as part of the repo, and use it as basis for enhancements to the core api. We can continue to discuss what works better, or in which cases, in that PR, adding comments to the sketch as appropriate, including why certain inits are needed.
Who can make the PR?

@torntrousers
Copy link
Contributor

@devyte I'm happy to do a PR with an example sketch but not sure what type of thing you'd like? There's a short sketch up in this issue here that shows the time for getting to setup which shows if rf calibration is happening or not, is that the type of thing you'd like?

@5chufti
Copy link
Contributor

5chufti commented Aug 23, 2018

@mailgpa just tested your suggestion with @ludiazv s sketch using ESP.deepSleep(2000000, WAKE_RFCAL)
and NO, it doesn't do correct RF_CAL at boot

⸮Started:[Deep-Sleep Wake]
Info: 00000000/2.2.1(cfd48f3)/rf_time:27,boot_time:67,W_time:238
IP:192.168.1.5
RSSI:-48
⸮⸮

unfortunately even using the diverse api functions in RF_PRE_INIT() does not affect the RF_CAL behaviour at startup in current 2.4.2

@devyte
Copy link
Collaborator

devyte commented Nov 9, 2018

@torntrousers right now we have nothing, so any example you can add would help. More than one example, if there's more than one use case.

@devyte
Copy link
Collaborator

devyte commented Nov 9, 2018

All, what is the status here? Leaving the requested examples aside, are there any code changes needed here?

@devyte devyte added waiting for feedback Waiting on additional info. If it's not received, the issue may be closed. and removed staged-for-release labels Nov 9, 2018
@torntrousers
Copy link
Contributor

Ok let me have a look over the weekend.

@devyte
Copy link
Collaborator

devyte commented Nov 27, 2018

I think further investigation and discussion is needed here.
Removing milestone for now until the path forward is clarified.

@JamesNewton
Copy link

Ran into this today. Arduino IDE 1.8.5 (I don't like being on the bleeding edge) and board file version 2.4.1. The following DOES work for me (with the affected ESP.deepSleep calls removed)

//If we get to here, we want to wake up and talk, but the radio might not be on. Only way to turn it on is to set a flag and go back to sleep.
  if (!rtcmem.RFon) {
    debugln("Reset for RF","");
    rtcmem.RFon = true;
    ESP.rtcUserMemoryWrite(0, (uint32_t*) &rtcmem, sizeof(rtcmem)); //write data to RTC memory so we don't loose it.
    //ESP.deepSleep(1, WAKE_NO_RFCAL); //deep sleep, wake right away with RF on, assume calibration not needed
    //ESP.deepSleep(1000 * MICROSECONDS, WAKE_RFCAL); //deep sleep, wake ASAP with RF on, assume calibration not needed
    //Can't use ESP.deepSleep call, see https://github.com/esp8266/Arduino/issues/3408
    system_deep_sleep_set_option(RF_NO_CAL);
    system_deep_sleep(1000000);
    }
//we are up and radio should be on.

@devyte
Copy link
Collaborator

devyte commented Jun 8, 2019

@JamesNewton To confirm: you're saying it doesn't work with the ESP. deepSleep() call, but it does work with the direct sdk system_deep_sleep*() calls?

@JamesNewton
Copy link

Yes... "The following DOES work for me (with the affected ESP.deepSleep calls removed)"

@5chufti
Copy link
Contributor

5chufti commented Jun 8, 2019

can you elaborate on what exactly is working?

//ESP.deepSleep(1000 * MICROSECONDS, WAKE_RFCAL); //deep sleep, wake ASAP with RF on, assume calibration not needed

as both of these lines may not be working for a reason:

  1. deep sleep for 1µs is not working on newer sdk, a minimum of ??? is needed, I use 100.
  2. "WAKE_RFCAL" IS doing a rfcal, so not what is expected from comment

@JamesNewton
Copy link

How on earth is it not clear? The lines commented out do NOT work, the lines in the program that are not commented out DO work.

@Tech-TX
Copy link
Contributor

Tech-TX commented Jan 5, 2020

The ORIGINAL issue must have been corrected some time in the last year. It's hard to tell from this tangled mess of comments since the original issue (WAKE_NO_RF_CAL not working) seems to have been utterly ignored since ~August 2018, and everyone took off in other directions. I just tested the original issue with the code scrap from well above, and RF_NO_CAL is working fine. Some of you folks that have OTHER issues than WAKE_NO_RF_CAL not working, kindly untangle yourself from this particular issue and post your own, as it's a right mess of multiple issues at the moment.

Here's proof that the ORIGINAL issue is closed:
Deep Sleep WAKE_NO_RFCAL

Deep Sleep WAKE_RFCAL

(the top trace is the TX output)

and the code chunk posted about half-way up this thread * that I tested with:

#include <ESP8266WiFi.h>

void setup() {
  unsigned long ms = millis();
  Serial.begin(115200); Serial.println();
  Serial.print("Setup time:"); Serial.println(ms);
  delay(300);
//  ESP.deepSleep(1E3, WAKE_NO_RFCAL);
  ESP.deepSleep(1E3, WAKE_RFCAL);

}

void loop() {
}
  • 'thread' is being polite; this issue's 'thread' looks like a ball of yarn that a cat has had fun with.

@devyte
Copy link
Collaborator

devyte commented Jan 5, 2020

@Tech-TX nice work untangling this.
Closing per previous comment due to original issue already fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: core type: bug waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.
Projects
None yet
Development

No branches or pull requests