Another ESP8266 weird-o tidbit of knowledge

mrburnette
Wed Apr 13, 2016 1:12 pm
Using:
OS Linux Mint 17.3 16-bit
ArduinoIDE Linux port 1.6.8 from the “.cc” guys

I read a lots; probably do not retain a great deal of what I read unless I come across one of those red-flag or contradictory statements… and, that is just what happened the other day. I read that if a “virgin” ESP8266 is programmed via ArduinoIDE and if that sketch does not use any of the WiFi library functions, then the ESP8266 will be running in RF-disabled mode, or significantly lower DC power because the RF section is not on.

Conversely, if you use the ArduinoIDE to turn on the RF section of the ESP8266, it will stay on even if the next sketch does not use WiFi… thus, the RF section is sucking power for no reason whatsoever. Ummmm.

Testing here confirms the above behavior. And, whenever we get a new toy in from China, most of us put it through it paces using readily available sketches … therefore, most ESP8266’s that are just lying around outside of their antistatic bag are prone to waste as much as 50mA if you use them in a non-RF project. Would anyone actually use an ESP8266 in a non-wireless project? Yea, at the low price per unit, it is possible.

There are likely significantly better ways to disable the RF section; I found some direct “system_” calls but I need to dig deeper to pass the correct variable types. Therefore, very easy is going to be left open for the moment… likely, Martin has already worked through this behavior, but I have not read such as yet.

So, The 2nd easy way that works is to construct a sketch to turn off the RF, download the sketch, then edit the sketch to not use any WiFi and download it again. I have done this and the ESP8266 went from 80mA to 20mA and the LED with the LED behavior and the serial behavior unchanged!

Here is the sketch that will run with the RF section active or the RF section non-active – our baseline sketch:
/*
BlinkNcount for ESP8266 NodeMCU by m. ray burnette
Compiled on Linux Mint 17.3 32-bit
Arduino 1.6.8 tested on 20160409 http://esp8266.github.io/Arduino/versions/2.1.0/
Sketch uses 231,213 bytes (22%) of program storage space. Maximum is 1,044,464 bytes.
Global variables use 31,596 bytes (38%) of dynamic memory, leaving 50,340 bytes for local variables.
Turns on an LED on for one second, then off for one second, repeatedly.
Counts and displays the count on the attached serial monitor
This example code is in the public domain.
*/

#define BOARD_LED_PIN 2
int n = 0;

void setup() {
// initialize the digital pin as an output.
pinMode(BOARD_LED_PIN, OUTPUT);
// Initialize COM
Serial.begin(115200);
digitalWrite(BOARD_LED_PIN,!digitalRead(BOARD_LED_PIN));// Turn the LED from off to on, or on to off
Serial.println("Blink LED & count Demo");
}

void loop() {
long uSeconds = micros();
digitalWrite(BOARD_LED_PIN, HIGH); // set the LED on
delay(500); // wait for half-second
digitalWrite(BOARD_LED_PIN, LOW); // set the LED off
Serial.print("Loop #: ");
n++;
Serial.print(n);
Serial.print(" uS=");
Serial.println(micros()-uSeconds);

delay(500); // wait another half-second
}


RogerClark
Wed Apr 13, 2016 8:59 pm
Thanks Ray

I did briefly look into turning off the WIFi on the ESP8266 a while ago, as I though I had an issue with it interfering with a Bluetooth device, but in the end I found the problem was not related to the WiFi signals.

This is really interesting, as although I am not to concerned with the power usage (80mA), I suspect that if the WiFi is completely off, then the ESP8266 RTOS will not be spending so much time servicing the WiFi side of the hardware, leaving more cpu cycles for the user program ( sketch )


mrburnette
Wed Apr 13, 2016 9:34 pm
@Roger,
I was thinking the same, but have been hampered because while I have been able to turn off the RF section and to turn it back on, the procedure does not appear to be consistent and I cannot repeat it at will.

When I turned off the WiFi on the blink sketch, the current fell from 80mA to 20mA. When I turned on the RF, the ESP8266 worked but current went from 20mA to 90-100mA. Reprogramming with the Tardis Time UDP receiver, the current was again at 80mA. However, the disable sketch no longer works!

At the point, things became inconsistent, I had run out if coffee and decided it would be best it I put this aside until another day!

Ray


ahull
Wed Apr 13, 2016 9:37 pm
If you can make this work consistently, it opens up some interesting low power options, for example you could theoretically log data in short bursts of activity and thus at very low power, over many days and then say once per week, upload it over wifi to a web server. This potentially vastly extend battery life since the ESP8266 documentation suggests it is capable of fairly frugal low power modes.

RogerClark
Wed Apr 13, 2016 10:44 pm
The esp8266 also has its standby mode, but I’ve never got to grips with it, as it seems that you need to connect a GPIO pin to the reset pin to get that to work (very odd)

mrburnette
Wed Apr 13, 2016 11:40 pm
ahull wrote:If you can make this work consistently, it opens up some interesting low power options, for example you could theoretically log data in short bursts of activity and thus at very low power, over many days and then say once per week, upload it over wifi to a web server. This potentially vastly extend battery life since the ESP8266 documentation suggests it is capable of fairly frugal low power modes.

RogerClark
Wed Apr 13, 2016 11:46 pm
Hi Ray

I wondered how the SSID stuff was handled, so that it auto-reconnects

I thought it was the OS that was storing that stuff, but I’ve not delved to much into the Arduino core code.

I do make some native calls from the Arduino code, but nothing that seemed to cause any problems.

But its a good point to make about conflicts between writing your own code and using the Arduino code.

Personally, I’d prefer a more pick-and-mix style approach, as I’m not averse to using callbacks, rather than all functions “blocking”, as callbacks are preferable in a lot of circumstances.


mrburnette
Wed Apr 13, 2016 11:52 pm
RogerClark wrote:Hi Ray

I wondered how the SSID stuff was handled, so that it auto-reconnects

I thought it was the OS that was storing that stuff, but I’ve not delved to much into the Arduino core code.

I do make some native calls from the Arduino code, but nothing that seemed to cause any problems.

But its a good point to make about conflicts between writing your own code and using the Arduino code.

Personally, I’d prefer a more pick-and-mix style approach, as I’m not averse to using callbacks, rather than all functions “blocking”, as callbacks are preferable in a lot of circumstances.


mrburnette
Sat Apr 16, 2016 1:24 pm
This has been an awkward journey because I was making everything more complicated than it really is… duh! :?

I can now consistently disable the RF section of the ESP12E module which should be applicable across the product line of ESP8266 using the ArduinoIDE and the igrr core. In reading about this “stuff”, I must have read the same paragraph 10 times and still made the same silly error. :cry:

There appears to be a number of ways to accomplish disabling the RF section and a number of ways to reduce the RF power profile. The trick shown below is intended to disable the RF completely – however, I cannot completely confirm that the RF will not wake-up after 0xFFFFFFF uS. Just a matter of testing to validate the long-term behavior of the RF section. The pertinent ESP8266 ArduinoIDE github referenceis here.

Essentially, your non-RF sketch must

  • import ESP8266WiFi.h
  • call WiFi.forceSleepBegin();
  • call delay(100); // or some other numeric delay value.
    The delay() makes certain that the task-switcher moves from Arduino to the ESP native section to shut-down the RF orderly.

I have tried the above using a faux NodeMCU from LoLin. I can run normal WiFi sketches at around 80-100 mA and then run Arduino sketches without RF resources at around 20-30 mA. The behavior is consistent.

As mentioned, I (at this time) do not know if 0xFFFFFFF uS will expire or is coded to be an “always” value. Reading suggests that the effects of WiFi.forceSleepBegin(); can be circumvented and the RF section returned to active status. I do not know the implication of such a reversal or even if the reversal is truly possible (other network resources, etc.) Such unknowns will need to be tested.

Here is the Blink ‘n Count script modified for the ESP8266 without using any current for the RF section… I measure between 20-30 mA.

/*
BlinkNcount for ESP8266 NodeMCU by m. ray burnette
Compiled on Linux Mint 17.8 64-bit
Arduino 1.6.8 tested on 20160416 http://esp8266.github.io/Arduino/versions/2.1.0/
USING WiFi Library calls to turn off the normally on RF electronics:
Sketch uses 232,408 bytes (22%) of program storage space. Maximum is 1,044,464 bytes.
Global variables use 31,813 bytes (38%) of dynamic memory, leaving 50,107 bytes for local variables. Maximum is 81,920

*----> PROGRAMMED AS Generic / reset method: nodemcu / Flash mode: QIO / Flash Size: 4M (1M SPIFFS) <----*

Turns on an LED on for one second, then off for one second, repeatedly.
Counts and displays the count on the attached serial monitor
This example code is in the public domain.
RF sleep reference: https://github.com/esp8266/Arduino/issues/460#issuecomment-168970936
*/

#include <ESP8266WiFi.h>
#define BOARD_LED_PIN 2 // MAPLE MINI

int n = 0;

void setup() {
pinMode(BOARD_LED_PIN, OUTPUT);
Serial.begin(115200);
Serial.println("\n\n\r\rBlink LED & count Demo\n\r");
WiFi.forceSleepBegin();
delay(100);
}

void loop() {
long uSeconds = micros();
digitalWrite(BOARD_LED_PIN,!digitalRead(BOARD_LED_PIN));
Serial.print("Loop #: ");
n++;
Serial.print(n);
Serial.print(" uS=");
Serial.println(micros()-uSeconds);
delay(1000);
}


ahull
Sat Apr 16, 2016 1:46 pm
If we are talking uS here, then my quick back of the envelope calculation suggests 0xFFFFFFF uS is 268435455uS or 268.435455 seconds, which is around 4 1/2 minutes, so you should be able to check to see if it wakes back up fairly easily. Start sketch, measure current, make coffee, check to see if it woke back up. :D

Furthermore, calling WiFi.forceSleepBegin(); within the 4 1/2 minutes will most likely reset the sleep time back to 4 1/2 minutes, so longer sleeps should be relatively trivial to code.


martinayotte
Sat Apr 16, 2016 2:04 pm
Yes, like some people doing for the deepSleep(), storing an additional counter in the RTC_RAM, check it at WakeUp and re-enter in deepSleep() if the real sleep time isn’t achieved.

mrburnette
Sun Apr 17, 2016 2:28 am
ahull wrote:If we are talking uS here, then my quick back of the envelope calculation suggests 0xFFFFFFF uS is 268435455uS or 268.435455 seconds, which is around 4 1/2 minutes, so you should be able to check to see if it wakes back up fairly easily. Start sketch, measure current, make coffee, check to see if it woke back up. :D <…>

WereCatf
Sun Apr 17, 2016 5:17 am
mrburnette wrote:Essentially, your non-RF sketch must

  • import ESP8266WiFi.h
  • call WiFi.forceSleepBegin();
  • call delay(100); // or some other numeric delay value.
    The delay() makes certain that the task-switcher moves from Arduino to the ESP native section to shut-down the RF orderly.

I have tried the above using a faux NodeMCU from LoLin. I can run normal WiFi sketches at around 80-100 mA and then run Arduino sketches without RF resources at around 20-30 mA. The behavior is consistent.


RogerClark
Sun Apr 17, 2016 5:59 am
does yield() work as well as delay

I suspect the thing that is being used in delay is actually yield()


WereCatf
Sun Apr 17, 2016 6:10 am
RogerClark wrote:does yield() work as well as delay

I suspect the thing that is being used in delay is actually yield()


mrburnette
Sun Apr 17, 2016 5:52 pm
RogerClark wrote:does yield() work as well as delay

I suspect the thing that is being used in delay is actually yield()


WereCatf
Sun Apr 17, 2016 6:02 pm
mrburnette wrote:RogerClark wrote:does yield() work as well as delay

I suspect the thing that is being used in delay is actually yield()


mrburnette
Sun Apr 17, 2016 6:14 pm
WereCatf wrote:mrburnette wrote:RogerClark wrote:does yield() work as well as delay

I suspect the thing that is being used in delay is actually yield()


mrburnette
Sun Apr 17, 2016 6:21 pm
mrburnette wrote:
<…>
I’m currently sourcing the stable branch, but I usually am more cutting-edge and source the “staging” release!
http://arduino.esp8266.com/stable/packa … index.json

Ray


WereCatf
Sun Apr 17, 2016 6:53 pm
mrburnette wrote:RogerClark wrote:does yield() work as well as delay

I suspect the thing that is being used in delay is actually yield()


RogerClark
Sun Apr 17, 2016 9:14 pm
I looked at delay() and it calls esp_yield(), but it also does some stuff with arming and disarming timers.

I didnt have time to see what esp_yield() does or whether its an API function


mrburnette
Sun Apr 17, 2016 9:25 pm
WereCatf wrote:
<…>
I cannot replicate this. If I use yield() the WiFi doesn’t power off. Do you call delay() anywhere, like, say, in your loop()-function? If yes, then you are, indeed, using delay() to have the power-save to kick in.

mrburnette
Sun Apr 17, 2016 9:28 pm
RogerClark wrote:I looked at delay() and it calls esp_yield(), but it also does some stuff with arming and disarming timers.

I didnt have time to see what esp_yield() does or whether its an API function


WereCatf
Sun Apr 17, 2016 9:36 pm
mrburnette wrote:Or, just use delay(1) and forget about it all.

RogerClark
Sun Apr 17, 2016 9:39 pm
Hi Ray,

I still havent figured out how iggr’s code turns non-blocking functions into Arduino style blocking ones.

I guess its some sort if semaphore system, and there must be a way in the ESP API to suspend the foreground / user task.

The ESP is a very strange beast. But this is probably the fault of the ESP RTOS rather than the actual hardware.
Well, actually… I find it odd that the device has no internal program flash..( or did I miss something?)

This OHMO is not great for a wifi device as it means the code can keys cant be secured.


WereCatf
Sun Apr 17, 2016 9:47 pm
RogerClark wrote:The ESP is a very strange beast. But this is probably the fault of the ESP RTOS rather than the actual hardware.
Well, actually… I find it odd that the device has no internal program flash..( or did I miss something?)

This OHMO is not great for a wifi device as it means the code can keys cant be secured.


mrburnette
Sun Apr 17, 2016 9:56 pm
RogerClark wrote:
<…>
The ESP is a very strange beast. But this is probably the fault of the ESP RTOS rather than the actual hardware.
Well, actually… I find it odd that the device has no internal program flash..( or did I miss something?)

This OHMO is not great for a wifi device as it means the code can keys cant be secured.


WereCatf
Sun Apr 17, 2016 10:11 pm
mrburnette wrote:Agree on the security issue and I do not know if the ESP API makes any attempts to scramble stuff to prevent easy extraction.

mrburnette
Sun Apr 17, 2016 10:25 pm
WereCatf wrote:
<…>
One could always disable WiFi-persistence ( WiFi.persistent(false) ) at boot so it doesn’t store the keys on the flash automatically, then one could use the unique, chip-specific ID ( ESP.getChipId() ) stored in the ESP’s ROM to encrypt the key and store it manually and, at boot, load it manually and decrypt it and use the decrypted keys as usual.<…>

WereCatf
Sun Apr 17, 2016 10:35 pm
mrburnette wrote:so the unique number is an approach – provided it is truly random and not serialized. Sequential numbering so makes it easy for a decryption algorithm.

RogerClark
Sun Apr 17, 2016 11:02 pm
There are various methods to do secure booting, but I’m not sure if the device ID in the silicon would be a big enough key to make this particularly secure.

iggr wrote

… By default, ESP sets its MAC address as a concatenation of 3 fixed bytes and 3 unique bytes burned into chip (which are read by getChipId function).

But 3 bytes would probably be easy to brute force attack.

Using Mac ID’s is generally not a viable security solution either, as AFIK vendors don’t guarantee that a each device will have a unique MAC, and quite often reuse the same Mac more than once.

I generally use server created GUID’s which are logged in a database, so no two devices should have the same GUID.

But of course as the GUID and the password, can be read back out of the external Flash, there is nothing to prevent someone from cloning a ESP8266 device.


Leave a Reply

Your email address will not be published. Required fields are marked *