Motivation

Wenn ein ESP8266 im Batterie-Betrieb laufen soll oder durch eine Solar-Zelle versorgt werden soll, hängt die mögliche Betriebsdauer direkt von der Stromaufnahme des Geräts ab. Es gibt eine Reihe von Sites, die sich mit der Stromaufnahme des ESP8266 beschäftigen. Ich habe aber keine gefunden, die einmal sämtliche Zustände durchdekliniert. Das habe ich hier nachgeholt. Eine Zusammenfassung der Ergebnisse erfolgt direkt im Anschluss. Die Details finden sich im Abschnitt Einzelergebnisse.

In­halts­ver­zeich­nis

Zusammenfassung

Konfiguration

Stromaufnahme bei den verschiedenen Zuständen

Bewertung

Testumgebung

Konfiguration

Test-Programm

Einzelergebnisse

WiFi-Mode: WIFI_OFF

WiFi-Mode: WIFI_STA

WiFi-Mode: WIFI_AP, WIFI_AP_STA


Zusammenfassung

Konfiguration

Board:  ESP-12
Chip ID:  14165390
CPU Frequenz:  80 MHz
Flash Chip Type:  BG25Q32
Flash-Größe:  4 MB
Firmware: Arduino Plugin ESP8266 core for Arduino Version 2.3.0

Stromaufnahme bei den verschiedenen Zuständen

WiFi-Mode Connection Sleep-Mode Stromaufnahme
Off - - Ø 90mA ^ 90mA
STA none - Ø 90mA ^ 90mA
connected none Ø 90mA ^ 370mA
modem Ø 40mA ^ 370mA
light Ø 30mA ^ 370mA
AP - - Ø 90mA ^ 370mA
AP_STA - - Ø 90mA ^ 370mA

  (Werte wurden zur Sicherheit aufgerundet)

Bewertung


Testumgebung

Konfiguration

Board:  ESP-12
Chip ID:  14165390
CPU Frequenz:  80 MHz
Flash Chip Type:  BG25Q32
Flash-Größe:  4 MB
Firmware: Arduino Plugin ESP8266 core for Arduino Version 2.3.0

Ein FT232-Board dient der Stromversorgung und zur Kommunikation mit dem ESP. In die Masseleitung wurde ein 1Ω-Widerstand eingeschleift. Der Spannungsabfall an dem Widerstand wurde mit einem Oszilloskop aufgezeichnet (Kanal 1). 1mV entspricht dabei 1mA.

Die übrige Verschaltung entspricht dem Standard (s. Arduino: Was geht)).

Um feststellen zu können, wann der ESP erneut seine Arbeitsschleife beginnt, wird zu Beginn von loop() GPIO14 kurzeitig (1ms) auf HIGH gelegt (s.u. Testprogramm).

Test-Schaltung

Hier eine typische Ausgabe des Oszilloskops:/p>

Typische Oszilloskop-Ausgabe

Im oberen Teil (gelber Graph) sieht man den zeitlichen Verlauf der Stromaufnahme des ESP-12. Auf dem unteren grünen Graph sind die Trigger-Pulse zu erkennen.

Test-Programm

Das Testprogramm ist ein sehr einfach gehaltenes Arduino-Programm mit den Standard-Methoden setup() zur Initialisierung des Systems und der Arbeitsschleife loop(). In loop() erfolgt zunächst die Ausgabe eines 1ms dauernden Trigger-Pulses auf GPIO14. Danach wird die serielle Schnittstelle abgefragt, ob der Sleep-Modus gewechselt werden soll. Zuletzt erfolgt ein delay(1000). Die zusätzliche Stromsparfunktion beim Modus Light-Sleep erfolgt nur während des Delay.

Die Method printState() gibt den aktuellen Zustand über die serielle Schnittstelle aus. connectStation() stellt eine Verbindung zum Access-Point (Router) her.

#include <ESP8266WiFi.h>
#include "Helpers.h"

const char* ssid = "xxx";
const char* password = "xxx";
const char* hostName = "ESP-Current";

void setup() {
  ESP.eraseConfig(); // Alte Konfiguration löschen

  Serial.begin(115200);
  Serial.println("\n----------------------------");

  WiFi.mode(WIFI_OFF);
  WiFi.setAutoConnect(false);

  // Initialen Zustand ausgeben
  printState();
  pinMode(14, OUTPUT); // Pin für Trigger-Signal auf Output
}

void loop() {
  // 1 ms Pulse an GPIO 14
  digitalWrite(14, HIGH);
  delay(1);
  digitalWrite(14, LOW);

  // Modi umschalten
  if (Serial.available()) {
    int c = Serial.read();
    switch (c) {
      case 'n': WiFi.setSleepMode(WIFI_NONE_SLEEP); break;
      case 'l': WiFi.setSleepMode(WIFI_LIGHT_SLEEP); break;
      case 'm': WiFi.setSleepMode(WIFI_MODEM_SLEEP); break;
      case 'o': WiFi.mode(WIFI_OFF); break;
      case 's': WiFi.mode(WIFI_STA); break;
      case 'a': WiFi.mode(WIFI_AP); break;
      case 'b': WiFi.mode(WIFI_AP_STA); break;
      case 'c': connectStation(ssid, password, hostName); break; // WLAN Verbindung herstellen
      case 'd': WiFi.disconnect(); break;
      case 'w': WiFi.softAP(hostName, password); break;
    }
    while (Serial.available()) Serial.read(); // Eingabepuffer leer lesen

    // Aktuellen Sleep-Mode ausgeben
    printState();
  }

  delay(1000);
}

Hinzu kommen die Hilfsfunktionen printState() und connectStation().

#include "Helpers.h"

// Aktuellen Sleep-Mode als Text zurück liefern
String getSleepModeString() {
  WiFiSleepType_t sm = WiFi.getSleepMode();
  switch (sm) {
  case WIFI_NONE_SLEEP: return "WIFI_NONE_SLEEP";
  case WIFI_LIGHT_SLEEP: return "WIFI_LIGHT_SLEEP";
  case WIFI_MODEM_SLEEP: return "WIFI_MODEM_SLEEP";
  default: return "UNKNOWN";
  }
}

// Aktuellen Modus als Text zurück liefern
String getModeString() {
  WiFiMode_t m = WiFi.getMode();
  switch (m) {
  case WIFI_OFF: return "WIFI_OFF";
  case WIFI_STA: return "WIFI_STA";
  case WIFI_AP: return "WIFI_AP";
  case WIFI_AP_STA: return "WIFI_AP_STA";
  default: return "UNKNOWN";
  }
}

// Gibt den aktuellen Zustand aus
void printState() {
  Serial.print("      Mode: "); Serial.print(getModeString());
  if (WiFi.isConnected())
    Serial.println(", connected");
  else
    Serial.println(", offline");

  Serial.print("Sleep Mode: "); Serial.println(getSleepModeString());
}

uint8_t connectStation(const char * ssid, const char * password, const char * hostName) {
  uint8_t i = 0;

  // hostName festlegen
  if (hostName) {
    if (*hostName != 0) { // ist nicht leer?
      if (!WiFi.hostname(hostName)) {
        Serial.print(F("***** Error: Could not set hostname: '"));
        Serial.print(hostName);
        Serial.println(F("'!"));
        return 2;
      }
    } // if *hostName
  } // if hostName

    // Verbindung zum WLAN

  Serial.print(F("Connecting to WiFi "));
  Serial.print(ssid);
  Serial.print(F(" as "));
  Serial.print(WiFi.hostname());
  Serial.print(' ');

  WiFi.begin(ssid, password);

  // Auf Verbindung warten (ca. 5 Sec)
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (i > 10) {
      Serial.println(F("***** Error: WiFi connection failed!"));
      return 3;
    }
    i++;
  }

  Serial.println();
  Serial.print(F("Connected to "));
  Serial.print(ssid);
  Serial.print(F(", IP address: "));
  Serial.println(WiFi.localIP());

  return 0;
}

Einzelergebnisse

Hinweis zu den Grafiken: Einige der Messungen wurden mit einem zusätzlichen Glättungskondensator von 1000µF zwischen VCC und GND durchgeführt. Dadurch wurden die Stromspitzen von knapp 400mA auf knapp 90mA reduziert. Die Befürchtung war, dass der Spannungsabfall am Messwiderstand sonst zu groß würde. Außer der Abschwächung der Peaks zu Beginn und Ende einer Übertragung hat dies keinen Effekt.

Einige der Grafiken haben eine vertikale Auflösung von 50mV pro Skaleneinheit, andere 100mV.

WiFi-Mode: WIFI_OFF

Das Test-Programm entspricht vollständig dem vorher aufgeführten.

Der Stromverbrauch ist unabhängig vom Sleep-Modus. Er ist relativ konstant und beträgt durchschnittlich ca. 85mA.

WiFi-Mode: WiFi_OFF

WiFi-Mode: WIFI_STA

unverbunden

WiFi.mode(WIFI_OFF); wurde ersetzt durch WiFi.mode(WIFI_STA);. Eine Verbindung zu einem WLAN wurde nicht hergestellt.

Das Ergebnis entspricht dem vorhergehenden: Der Stromverbrauch ist unabhängig vom Sleep-Modus. Er ist relativ konstant und beträgt durchschnittlich ca. 85mA.

WiFi-Mode: WiFi_STA, offline

Mit WLAN-Verbindung

Die WLAN-Verbindung wird in setup() mit folgender Anweisung hergestellt:

...
// WiFi Verbindung herstellen
UrsWiFi.connectStation(ssid, password, hostName);
...

(Zu UrsWiFi.connectStation siehe ESP8266 UrsWiFi: Was man immer wieder macht)

Sleep-Mode: WIFI_NONE_SLEEP

WiFi-Mode: WiFi_STA, connected; Sleep-Mode: None Der Stromverbrauch ist relativ konstant und beträgt durchschnittlich ca. 85mA..

Sleep-Mode: WIFI_MODEM_SLEEP

WiFi-Mode: WiFi_STA, connected; Sleep-Mode: Modem

Der Stromverbrauch ist beträgt durchschnittlich knapp 40mA.

Über die meiste Zeit, während der das Modem ausgeschaltet ist, beträgt die Stromaufnahme etwa 25mA.

Es etwa alle 1,5s treten längere Bereiche (ca. 170ms) mit höherem Verbrauch (gut 85 mA) auf; etwa dem Verbrauch, wie er ohne Modem-Abschaltung vorliegt. Offensichtlich findet hier eine Datenübertragung statt. Diese ist nicht synchron mit dem Programm (grüne Trigger-Pulse). Es muss also eine externe Ursache vorliegen.

Daneben treten etwa alle 100ms kurze Pulse auf, die DTIM-Signale.

WiFi-Mode: WiFi_STA, connected; Sleep-Mode: Modem; Modem off Während das Modem ausgeschaltet ist, beträgt die Stromaufnahme etwa 25mA.
WiFi-Mode: WiFi_STA, connected; Sleep-Mode: Modem; xmit Etwa alle 1,5s gibt es längere Bereiche (ca. 170ms) mit höherem Verbrauch (gut 85 mA). Diese treten meist regelmäßig auf, es gibt aber auch Zwischenereignisse. Zu Beginn und Ende gibt es kurze Pulse von ca. 370mA. Die Dauer dieser Pulse liegt bei etwa 0,1ms.
WiFi-Mode: WiFi_STA, connected; Sleep-Mode: Modem; DTIM Etwa alle 100ms treten kurze Pulse auf, die DTIM-Signale. Hier steigt der Stromverbrauch auch wieder auf etwa 100mA. Der DTIM-Pulse hat eine Länge von etwa 5ms.

Sleep-Mode: WIFI_LIGHT_SLEEP

WiFi-Mode: WiFi_STA, connected; Sleep-Mode: Light

Der Verlauf des Stromverbrauch ist i.W. identisch mit dem beim Modem-Sleep-Modus. Der durchschnittliche Stromverbrauch liegt um etwa 10mA darunter bei knapp 30mA. Die Basis-Stromaufnahme liegt bei etwa 12mA. Deutlich kann man die Zeiten erkennen, während derer die CPU arbeitet. Diese scheinen immer dem DTIM-Intervall zu entsprechen.

WiFi-Mode: WiFi_STA, connected; Sleep-Mode: Light Basis-Stromaufnahme

Die Tatsache, dass die CPU immer für die Dauer eines DTIM-Intervalls aktiv wird, lässt vermuten, dass kleine Delay-Zeiten zusätzliche Stromspar-Effekte durch den Light-Sleep-Modus verhindern. Dies ist in der Tat der Fall. Das folgende Bild zeigt den Stromverbrauch im Light-Sleep-Modus bei einem Delay von nur 90ms. Der Stromverbrauch ist der selbe wie im Modem-Sleep-Modus (Ø 38mA). Die CPU wird nur für kurze Zeit ausgeschaltet (s. Markierung).

WiFi-Mode: WiFi_STA, connected; Sleep-Mode: light; Delay: 90ms 

Im letzten Beispiel zu diesem Thema werden zu Begin jeder Arbeitsschleife fünf UDP-Pakete versandt. Deutlich kann man den erhöhten Stromverbrauch synchron zu den Trigger-Pulsen erkennen. Der durchschnittliche Stromverbrauch stiegt leicht an (ca. +1mA).

WiFi-Mode: WiFi_STA, connected; Sleep-Mode: light; UDP XMIT

WiFi-Mode: WIFI_AP, WIFI_AP_STA

Im Access-Point-Modus beträgt der durchschnittliche Stromverbrauch knapp 90mA. Etwa alle 100ms wird das DTIM-Signal gesandt. Eine Veränderung des Sleep-Modus hat keine Auswirkung. Es spielt auch keine Rolle, ob der Access-Point mit  WiFi.softAP(hostName, password) gestartet wurde. Das gleiche Bild zeigt sich im Modus WIFI_AP_STA. Es gibt keinen Unterschied zu WIFI_AP. Auch das Verbinden mit einem WLAN ändert nichts am Stromverbrauch.

Hinweis: Sobald der AP-Modus aktiviert wird (WiFi.mode(WIFI_AP)), wird ein WLAN eingerichtet. Ohne WiFi.softAP(hostName, password) ist besitzt dies einen internen Namen, z.B. ESP_D8258E, und kein Passwort. Die Methode softAP() gibt den Netzwerk einen Namen und ein Passwort.

WiFi-Mode: WiFi_AP

Die DTIM-Pulsdauer beträgt ca. 1,5ms und der Stromverbrauch steigt auf ca. 350mA.

WiFi-Mode: WiFi_A; STIM-SignalP