esp

From Notebook
Revision as of 08:24, 11 September 2023 by 173.76.164.186 (talk) (→‎Projects)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

ESP12[edit]


The ESP12 (or ESP12E, ESP12F ...) is an RF module containing the ESP8266 SoC and other necessary components, like the antenna. With a module like this, it's a lot easier to design products with WiFi capabilities, as you can simply use the module without needing a ton of additional components.

The ESP12 is made by AI-Thinker, but Espressif also has its own modules like the ESP-WROOM-02. There are a variety of modules available. Most of them only differ in form factor, price, and antenna design.


Notes

All ESP-12x modules need the GPIO15 (CS) pulled low and CH_PD or EN (enable) pin pulled high to boot normally. It is best to check with a multimeter whether the previous module had similar requirements and that those pins have continuity with GND for low and VCC for high. If not you will have to connect them with some wire or whatnot.



(TOP)

ESP Development Boards[edit]

[ESP8266 Pinout Reference: Which GPIO pins should you use?]


ESP8285
ESP8266-01
ESP8266-07
ESP32
WT32-ETH01
NodeMCU
Wemos D1
Wemos D1 Mini


Wemos ESP32 S2 Mini

Notes from [https://community.home-assistant.io/t/esp32-s2-and-esphome-upload/382885/43 the Home Assistant forum.


Pins




(TOP)

Downloader for ESP Modules[edit]

Instructions
  • Hold PROG while turning on the power.
  • Flash the device using espHome Flasher





(TOP)

ESP Pins (general)[edit]

Label GPIO Input Output Notes
D0 GPIO16 no interrupt no PWM
or I2C support
HIGH at boot
used to wake up from deep sleep
D1 GPIO5 OK OK often used as SCL (I2C)
D2 GPIO4 OK OK often used as SDA (I2C)
D3 GPIO0 pulled up OK connected to FLASH button,
boot fails if pulled LOW
D4 GPIO2 pulled up OK HIGH at boot
connected to on-board LED,
boot fails if pulled LOW
D5 GPIO14 OK OK SPI (SCLK)
D6 GPIO12 OK OK SPI (MISO)
D7 GPIO13 OK OK SPI (MOSI)
D8 GPIO15 pulled to GND OK SPI (CS)
Boot fails if pulled HIGH
RX GPIO3 OK RX pin HIGH at boot
TX GPIO1 TX pin OK HIGH at boot
debug output at boot,
boot fails if pulled LOW
A0 ADC0 Analog Input X pin

GPIO6 to GPIO11 are not recommended to use.
GPIO4 and GPIO5 are the most safe to use GPIOs if you want to operate relays.
You can read this article that investigates the state and behavior of each GPIO on boot.

Wemos D1 Mini pinout

(TOP)

Analog Input[edit]

The ESP8266 only supports analog reading in ADC0 and it is usually marked on the silkscreen as A0.

The maximum input voltage of the ADC0 pin is 0 to 1V if you’re using the ESP8266 bare chip. If you’re using a development board like the ESP8266 12-E NodeMCU kit, the voltage input range is 0 to 3.3V because these boards contain an internal voltage divider.

You can learn how to use analog reading with the ESP8266 with this guide:
ESP8266 ADC – Read Analog Values with Arduino IDE, MicroPython and Lua

(TOP)

On-board LED[edit]

LED_BUILTIN

Most of the ESP8266 development boards have a built-in LED. This LED is usually connected to GPIO2 (D4 on the Wemos D1 Mini).

(TOP)

RST Pin[edit]

When the RST pin is pulled LOW, the ESP8266 resets. This is the same as pressing the on-board RESET button.

(TOP)

GPIO0[edit]

When GPIO0 is pulled LOW, it sets the ESP8266 into bootloader mode. This is the same as pressing the on-board FLASH/BOOT button.

(TOP)

I2C[edit]

The ESP8266 doesn’t have hardware I2C pins, but it can be implemented in software. So you can use any GPIOs as I2C. Usually, the following GPIOs are used as I2C pins:

GPIO5: SCL
GPIO4: SDA

(TOP)

SPI[edit]

The pins used as SPI in the ESP8266 are:

GPIO12: MISO
GPIO13: MOSI
GPIO14: SCLK
GPIO15: CS

(TOP)

PWM Pins[edit]

ESP8266 allows software PWM in all I/O pins: GPIO0 to GPIO16. PWM signals on ESP8266 have 10-bit resolution.

(TOP)

Interrupts[edit]

Pins[edit]

The ESP8266 supports interrupts in any GPIO, except GPIO16 (D0).

setup()[edit]

Attach the interrupt pin to the handler in setup:

attachInterrupt(START_PIN, startButtonHandler, RISING);


ISR tips[edit]

The ESP expects handlers to be stored in the IRAM space, or you will get an error and reboot:

ISR not in IRAM!

Just add a compiler directive and your interrupt handler will work just fine.

volatile bool interruptReceived= false;

IRAM_ATTR void handleInterrupt() {
  interruptReceived = true;
}
Example
IRAM_ATTR void limitSwitchHandler() {
  {
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  // If interrupts come faster than 200ms, assume it's a bounce and ignore
  if (interrupt_time - last_interrupt_time > 200) 
  motorState = !motorState;                //Limit switch is closed, stop the motor
  }
  last_interrupt_time = interrupt_time;
}

Debounce ISR[edit]

void my_interrupt_handler()
{
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  // If interrupts come faster than 200ms, assume it's a bounce and ignore
  if (interrupt_time - last_interrupt_time > 200) 
  {
    ... do your thing
  }
  last_interrupt_time = interrupt_time;
}



(TOP)

Core Library Reference[edit]

Added: 8/13/2019

Libraries Reference
ESP Projects from Random Nerd Tutorials




(TOP)

Libraries[edit]

Reference

WiFi(ESP8266WiFi library)[edit]

This is mostly similar to WiFi shield library. Differences include:

WiFi.mode(m)
set mode to WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF.
call WiFi.softAP(ssid)
to set up an open network.
call WiFi.softAP(ssid, password)
to set up a WPA2-PSK network (password should be at least 8 characters)
WiFi.macAddress(mac)
is for STA, WiFi.softAPmacAddress(mac) is for AP.
WiFi.localIP()
is for STA, WiFi.softAPIP() is for AP.
WiFi.printDiag(Serial)
will print out some diagnostic info
WiFiUDP class
supports sending and receiving multicast packets on STA interface. When sending a multicast packet, replace udp.beginPacket(addr, port) with udp.beginPacketMulticast(addr, port, WiFi.localIP()). When listening to multicast packets, replace udp.begin(port) with udp.beginMulticast(WiFi.localIP(), multicast_ip_addr, port). You can use udp.destinationIP() to tell whether the packet received was sent to the multicast or unicast address.


WiFiServer, WiFiClient, and WiFiUDP behave mostly the same way as with WiFi shield library. Four samples are provided for this library.


You can see more commands here.

WL_DEFINITIONS[edit]

WL_IDLE_STATUS = 0,
WL_NO_SSID_AVAIL = 1,
WL_SCAN_COMPLETED = 2,
WL_CONNECTED = 3,
WL_CONNECT_FAILED = 4,
WL_CONNECTION_LOST = 5,
WL_WRONG_PASSWORD = 6,
WL_DISCONNECTED = 7



(TOP)

Function to print the wifi.status[edit]

const char* wl_status_to_string(wl_status_t status) {
  switch (status) {
    case WL_IDLE_STATUS: return "WL_IDLE_STATUS";
    case WL_NO_SSID_AVAIL: return "WL_NO_SSID_AVAIL";
    case WL_SCAN_COMPLETED: return "WL_SCAN_COMPLETED";
    case WL_CONNECTED: return "WL_CONNECTED";
    case WL_CONNECT_FAILED: return "WL_CONNECT_FAILED";
    case WL_CONNECTION_LOST: return "WL_CONNECTION_LOST";
    case WL_DISCONNECTED: return "WL_DISCONNECTED";
  }
}
Serial.println(wl_status_to_string(WiFi.status()));

(TOP)

WiFi.status()[edit]

The status function in the WiFi class, doesn’t take any arguments but it returns stuff depending on the status of the network that you’re connected to.

The WiFi.status function returns a value

Code Vulue Meaning
WL_IDLE_STATUS 0 WiFi is in process of changing between statuses
WL_NO_SSID_AVAIL 1 SSID cannot be reached
WL_SCAN_COMPLETED 2
WL_CONNECTED 3 Successful connection is established
WL_CONNECT_FAILED 4 Password is incorrect
WL_CONNECTION_LOST 5
WL_CONNECT_WRONG_PASSWORD 6 Password is incorrect
WL_DISCONNECTED 7 not configured in station mode

If you get code 1, WL_NO_SSID_AVAIL, try adding this before WiFi.begin():

WiFi.enableInsecureWEP();


It is recommended by some to set the mode to STA:

WiFi.mode(WIFI_AP_STA);
WiFi.begin();



(TOP)

Ticker[edit]

Library for calling functions repeatedly with a certain period. Two examples included.
It is currently not recommended to do blocking IO operations (network, serial, file) from Ticker callback functions. Instead, set a flag inside the ticker callback and check for that flag inside the loop function.

Examples
Ticker.h Examples
C Reference: ticker.h



(TOP)

EEPROM[edit]

Reading and Writing Data Structures to EEPROM

Using structures, reading and writing to the EEPROM is reduced to a single call.
(Reference from playground.arduino.cc.

I used this in my Monkey Detector to record the servo positions and timing between boot sessions.

First, add a tab in the IDE named: eepromAnything.h, then add this code:

// https://playground.arduino.cc/Code/EEPROMWriteAnything/

#include <EEPROM.h>
#include <Arduino.h>  // for type definitions

template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
          EEPROM.write(ee++, *p++);
    return i;
}

template <class T> int EEPROM_readAnything(int ee, T& value)
{
    byte* p = (byte*)(void*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
          *p++ = EEPROM.read(ee++);
    return i;
}



At the top of the sketch, add this
#include "eepromAnything.h"

//structure declaration with three values as members.
struct servo {
  int locked_Position ;
  int unlocked_Position ;
  unsigned long drawerTime;
};

//create an unitialized struct variable called myServo.
struct servo myServo;

//Declare the individual variables for use later.
//I could also use the struct?
int locked_Position = myServo.locked_Position;
int unlocked_Position = myServo.unlocked_Position;
unsigned long drawerTime = myServo.drawerTime;



In setup(), I read the EEPROM just for verification
  EEPROM_readAnything(0, myServo);
  locked_Position = myServo.locked_Position;
  unlocked_Position = myServo.unlocked_Position;
  drawerTime = myServo.drawerTime;

  Serial.print(F("lock-unlock-time= "));
  Serial.print(locked_Position);
  Serial.print(F(" - "));
  Serial.print(unlocked_Position);
  Serial.print(F(" - "));
  Serial.println(drawerTime);



When I write data to the EEPROM
myServo.locked_Position = locked_Position;
myServo.unlocked_Position = unlocked_Position;
myServo.drawerTime = drawerTime;

EEPROM_writeAnything(0, myServo);




(TOP)

Old EEPROM Stuff

EEPROM Library for the ESP devices.

This is a bit different from standard EEPROM class.
EEPROM.begin(size)
You need to call EEPROM.begin(size) before you start reading or writing, size being the number of bytes you want to use. Size can be anywhere between 4 and 4096 bytes.
EEPROM.write()
EEPROM.write does not write to flash immediately, instead you must call EEPROM.commit() whenever you wish to save changes to flash. EEPROM.end() will also commit, and will release the RAM copy of EEPROM contents.
EEPROM.commit()
you must call EEPROM.commit() whenever you wish to save changes to flash.
EEPROM.end()
EEPROM.end() will also commit, and will release the RAM copy of EEPROM contents.


EEPROM library uses one sector of flash located just after the SPIFFS.



The ESP8266 handles EEPROM different from the Arduino.

Here is a sketch that I found on the Google machine a few months ago, edited for readability.
Sample code:

#include <EEPROM.h>

void setup() {
  Serial.begin(115200);
  while (!Serial) {}
  Serial.println();
  Serial.println("EEPROM_esp8266_example.ino");

  /* Using the ESP8266 EEPROM is different from the standard Arduino EEPROM class.
     You need to call EEPROM.begin(size) before you can start reading or writing, where
     the size parameter is the number of bytes you want to use store
     Size can be anywhere between a minimum of 4 and maximum of 4096 bytes.
  */

  EEPROM.begin(32);  //EEPROM.begin(Size)

  /*
    Commands EEPROM.write or EEPROM.put do not write to flash immediately, to invoke them
    you must call EEPROM.commit() to save changes to flash/EEPROM.
    EEPROM.end() will also commit, but releases the RAM copy of EEPROM contents.
  */

  // Commands to determine variable sizes, needed for storing to EEPROM
  Serial.println();
  Serial.println("            Floating point variables need: " + String(sizeof(float)) + " Bytes"); // Determine how many bytes (4) are needed to save a floating point variable
  Serial.println("Double size floating point variables need: " + String(sizeof(double)) + " Bytes"); // Determine how many bytes (8) are needed to save a floating point variable
  Serial.println("                   Integer variables need: " + String(sizeof(int)) + " Bytes"); // Determine how many bytes (4) are needed to save an integer variable
  Serial.println("         Boolean values or variables need: " + String(sizeof(bool)) + " Bytes"); // Determine how many bytes (1) are needed to save a boolean variable
  Serial.println("           String variables need at least: " + String(sizeof(String)) + " Bytes"); // Determine how many bytes (min. 12) are needed to save a string variable
  Serial.println();

  //----------------------------------------------------------------------------
  // Example-1 Write a value to EEPROM at address = 0
  int EEaddress = 0;
  EEPROM.write(EEaddress, 123); // Writes the value 123 to EEPROM
  // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Contents of EEPROM
  // 7B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Contents of RAM
  EEPROM.commit();
  // 7B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Contents of EEPROM
  // Serial.print(F("Write a value: 123 to EEPROM at address = 0"));
  Serial.print("EEPROM contents at Address=0 is  : ");
  Serial.println(EEPROM.read(EEaddress));

  //----------------------------------------------------------------------------
  // Example-2 Write a value to EEPROM at address = 0
  // 7B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Contents of EEPROM
  EEPROM.write(EEaddress, 257); // Writes the value 257 to EEPROM
  EEPROM.commit();
  // 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Contents of EEPROM
  Serial.print("EEPROM contents at Address=0 is  : ");
  Serial.println(EEPROM.read(EEaddress));

  //----------------------------------------------------------------------------
  // Example-3 Write an integer variable to EEPROM at address = 0
  int integer_variable = 257;
  // 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Contents of EEPROM
  EEPROM.put(EEaddress, integer_variable); // Writes the value 257 to EEPROM
  EEPROM.commit();
  // 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Contents of EEPROM
  Serial.print("EEPROM contents at Address=0 is  : ");
  EEPROM.get(EEaddress, integer_variable);
  Serial.println(integer_variable);

  //----------------------------------------------------------------------------
  // Example-4 Write another integer variable to EEPROM
  int integer_variable2 = 1234;
  EEaddress = EEaddress + sizeof(int); // Moves the address along by 4
  EEPROM.put(EEaddress, integer_variable2); // Writes the value 1234 to EEPROM
  EEPROM.commit();
  // 01 01 00 00 D2 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Contents of EEPROM
  Serial.print("EEPROM contents at Address=4 is  : ");
  EEPROM.get(EEaddress, integer_variable2);
  Serial.println(integer_variable2);
  EEaddress = EEaddress + sizeof(int); // Moves the address along by 4

  //----------------------------------------------------------------------------
  // Example-5 Write a floating point variable to EEPROM
  float floatingpoint_variable = 3.141592654;
  EEPROM.put(EEaddress, floatingpoint_variable); // Writes the value 3.141592654 to EEPROM
  EEPROM.commit();
  Serial.print("EEPROM contents at Address=8 is  : ");
  EEPROM.get(EEaddress, floatingpoint_variable);
  Serial.println(floatingpoint_variable, 8);
  EEaddress = EEaddress + sizeof(float);        // Moves the address along by 4

  //----------------------------------------------------------------------------
  // Example-6 Write a string variable to EEPROM
  String string_variable = "Hello world";
  EEPROM.put(EEaddress, string_variable); // Writes the value 3.141592654 to EEPROM
  EEPROM.commit();
  Serial.print("EEPROM contents at Address=12 is : ");
  EEPROM.get(EEaddress, string_variable);
  Serial.println(string_variable);
  EEaddress = EEaddress + sizeof(string_variable);        // Moves the address along by 4

  //----------------------------------------------------------------------------
  // Example-7 Write a series of values to EEPROM
  for (int i = 1000; i <= 1032; i = i + 4) {
    EEPROM.put(i - 1000, i); // Address range 0-32
  }
  EEPROM.commit();
  for (int j = 1000; j <= 1032; j = j + 4) {
    EEPROM.get((j - 1000), integer_variable); // Read the 32 values
    Serial.println(integer_variable);
  }

  //----------------------------------------------------------------------------
  // Example-8 Testing that the EEPROM extent has not been exceeded, remember not to exceed address space
  if (EEaddress == 32) {
    EEaddress = 0;
  }

  //----------------------------------------------------------------------------
  // Example-9 Compact method of writing and reading values from EEPROM
  EEaddress = 20;
  // Writing
  floatingpoint_variable = 2 * PI;
  EEaddress += EEPROM.put(EEaddress, floatingpoint_variable);
  integer_variable = 123456789;
  EEaddress += EEPROM.put(EEaddress, integer_variable);
  EEPROM.end();

  EEaddress = 20;
  // Reading
  EEaddress += EEPROM.get(EEaddress, floatingpoint_variable);
  EEaddress += EEPROM.get(EEaddress, integer_variable);
  EEPROM.commit();
  Serial.println(floatingpoint_variable, 7);
  Serial.println(integer_variable);

}

void loop() {}




(TOP)

espnow[edit]

ESP-NOW with ESP8266: Send Data to Multiple Boards (one-to-many)
Many to One
Tutorial from The Workshop
ESP Now integration for ESPhome (GitHub)




(TOP)

I2C (Wire library)[edit]

Wire library currently supports master mode up to approximately 450KHz.
Before using I2C, pins for SDA and SCL need to be set by calling Wire.begin(int sda, int scl), i.e. Wire.begin(0, 2) on ESP-01, else they default to pins 4(SDA) and 5(SCL).

if you have a problems with conflicting I2C addresses use an [I2C multiplexor]. You can run 8 devices with the same address of a single hardware I2C interface rather than using software I2C



(TOP)

SPI[edit]

SPI library supports the entire Arduino SPI API including transactions, including setting phase (CPHA). Setting the Clock polarity (CPOL) is not supported, yet (SPI_MODE2 and SPI_MODE3 not working).



(TOP)

SoftwareSerial[edit]

An ESP8266 port of SoftwareSerial library done by Peter Lerup (@plerup) supports baud rate up to 115200 and multiples SoftwareSerial instances. See developers Git if you want to suggest an improvement or open an issue related to SoftwareSerial.



(TOP)

ESP-specific APIs[edit]

APIs related to deep sleep and watchdog timer are available in the ESP object, only available in Alpha version.

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. (GPIO16 needs to be tied to RST to wake from deepSleep.)
ESP.restart() restarts the CPU.
ESP.getFreeHeap() returns the free heap size.
ESP.getChipId() returns the ESP8266 chip ID as a 32-bit integer.


Several APIs may be used to get flash chip info:
ESP.getFlashChipId() returns the flash chip ID as a 32-bit integer.
ESP.getFlashChipSize() returns the flash chip size, in bytes, as seen by the SDK (may be less than actual size).
ESP.getFlashChipSpeed(void) returns the flash chip frequency, in Hz.
ESP.getCycleCount() returns the cpu instruction cycle count since start as an unsigned 32-bit. This is useful for accurate timing of very short actions like bit banging.
ESP.getVcc() may be used to measure supply voltage. ESP needs to reconfigure the ADC at startup in order for this feature to be available. Add the following line to the top of your sketch to use getVcc:
ADC_MODE(ADC_VCC);
TOUT pin has to be disconnected in this mode.
Note that by default ADC is configured to read from TOUT pin using analogRead(A0), and ESP.getVCC() is not available.



(TOP)

OneWire[edit]

Library was adapted to work with ESP8266 by including register definitions into OneWire.h Note that if you already have OneWire library in your Arduino/libraries folder, it will be used instead of the one that comes with this package.



(TOP)

mDNS and DNS-SD responder (ESP8266mDNS library)[edit]

Allows the sketch to respond to multicast DNS queries for domain names like "foo.local", and DNS-SD (service discovery) queries. See example for details.




(TOP)

SSDP responder (ESP8266SSDP)[edit]

SSDP is another service discovery protocol, supported on Windows out of the box. See attached example for reference.



(TOP)

DNS server (DNSServer library)[edit]

Implements a simple DNS server that can be used in both STA and AP modes. The DNS server currently supports only one domain (for all other domains it will reply with NXDOMAIN or custom status code). With it clients can open a web server running on ESP8266 using a domain name, not an IP address. See attached example for details.



(TOP)

Servo[edit]

This library exposes the ability to control RC (hobby) servo motors. It will support upto 24 servos on any available output pin. By default the first 12 servos will use Timer0 and currently this will not interfere with any other support. Servo counts above 12 will use Timer1 and features that use it will be effected. While many RC servo motors will accept the 3.3V IO data pin from a ESP8266, most will not be able to run off 3.3v and will require another power source that matches their specifications. Make sure to connect the grounds between the ESP8266 and the servo motor power supply.



(TOP)

Other libraries (not included with the IDE)[edit]

Libraries that don't rely on low-level access to AVR registers should work well. Here are a few libraries that were verified to work:

arduinoWebSockets - WebSocket Server and Client compatible with ESP8266 (RFC6455)
aREST REST API handler library.
Blynk - easy IoT framework for Makers (check out the Kickstarter page).
DallasTemperature
DHT-sensor-library - Arduino library for the DHT11/DHT22 temperature and humidity sensors. Download latest v1.1.1 library and no changes are necessary. Older versions should initialize DHT as follows: DHT dht(DHTPIN, DHTTYPE, 15)
NeoPixel - Adafruit's NeoPixel library, now with support for the ESP8266 (use version 1.0.2 or higher from Arduino's library manager).
NeoPixelBus - Arduino NeoPixel library compatible with ESP8266. Use the "NeoPixelAnimator" branch for ESP8266 to get HSL color support and more.
PubSubClient MQTT library by @Imroy.
RTC - Arduino Library for Ds1307 & Ds3231 compatible with ESP8266.
Souliss, Smart Home - Framework for Smart Home based on Arduino, Android and openHAB.
ST7735 - Adafruit's ST7735 library modified to be compatible with ESP8266. Just make sure to modify the pins in the examples as they are still AVR specific.




(TOP)

ESP-specific functions[edit]

Here is a description of the ESP specific API's.

ESP.deepSleep()[edit]

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.

(GPIO16 needs to be tied to RST to wake from deepSleep.) The chip can sleep for at most ESP.deepSleepMax() microseconds. If you implement deep sleep with WAKE_RF_DISABLED and require WiFi functionality on wake up, you will need to implement an additional WAKE_RF_DEFAULT before WiFi functionality is available.

ESP.deepSleepInstant(microseconds, mode) works similarly to ESP.deepSleep but sleeps instantly without waiting for WiFi to shutdown.


Steps to use the Deep-sleep mode
  1. Connect the module with the Wi-Fi AP
  2. Perform a task like reading a sensor value, publishing an MQTT message, etc.
  3. Sleep for a defined number of microseconds
  4. Repeat the above process again

Sleep time is defined in microseconds. According to the ESP8266 SDK, you can only sleep for 4,294,967,295 µs which is about ~71 minutes.

Example:

Serial.println("deep sleep for 15 seconds");
ESP.deepSleep(15e6);

The system goes into Deep-sleep mode via the following interface:

ESPdeepSleep(uint32 time_in_us)

If time is == 0, then the chip won’t be woken up at regular intervals, i.e., won’t wake up automatically.

ESP.dsleep(0)    //Will cause the ESP to sleep forever.

The mode WAKE_RF_DISABLED doesn't change how deep-sleep works, the mode changes what happens when the device wakes up. In deep-sleep WiFi is always off, no matter what mode you give it. WAKE_RF_DISABLED disables WiFi when you reset the device/it wakes up.

(TOP)

ESP.reset[edit]

ESP.reset() is a hard reset and can leave some of the registers in the old state which can lead to problems, it's more or less like the reset button on the PC.

(TOP)

ESP.restart[edit]

ESP.restart() tells the SDK to reboot, so it's a more clean reboot, use this one if possible.

(TOP)

ESP.getResetReason()[edit]

ESP.getResetReason() returns a String containing the last reset reason in human readable format.

Sample code
#include "ESP8266WiFi.h"
#include <Kaywinnet.h>

const char ssid[] = MYSSID;
const char password[] = MYPASSWORD;

void setup() {
  Serial.begin(115200);
  while (!Serial);            //Wait for serial to be ready
  delay(500);

  Serial.println("...");
  Serial.println(F("WiFi_Test.ino"));
  Serial.print(F("WiFi Connecting to: "));
  Serial.print(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(WiFi.status()); Serial.print(F(" "));
  }
  Serial.println("");
  Serial.print(F("ResetReason= "));
  Serial.println(ESP.getResetReason());
}

void loop()
{
}
Reset Reasons
rst cause
REASON_DEFAULT_RST = 0, /* normal startup by power on */
REASON_WDT_RST = 1, /* hardware watch dog reset */
REASON_EXCEPTION_RST = 2, /* exception reset, GPIO status won’t change */
REASON_SOFT_WDT_RST = 3, /* software watch dog reset, GPIO status won’t change */
REASON_SOFT_RESTART = 4, /* software restart ,system_restart , GPIO status won’t change */
REASON_DEEP_SLEEP_AWAKE = 5, /* wake up from deep-sleep */
REASON_EXT_SYS_RST = 6 /* external system reset */


(TOP)

ESP.getFreeHeap()[edit]

ESP.getFreeHeap() returns the free heap size.

(TOP)

ESP.getHeapFragmentation()[edit]

ESP.getHeapFragmentation() returns the fragmentation metric (0% is clean, more than ~50% is not harmless)

(TOP)

ESP.getMaxFreeBlockSize()[edit]

ESP.getMaxFreeBlockSize() returns the maximum allocatable ram block regarding heap fragmentation

(TOP)

ESP.getChipId()[edit]

ESP.getChipId() returns the ESP8266 chip ID as a 32-bit integer.

(TOP)

ESP.getCoreVersion()[edit]

ESP.getCoreVersion() returns a String containing the core version.

(TOP)

ESP.getSdkVersion()[edit]

ESP.getSdkVersion() returns the SDK version as a char.

(TOP)

ESP.getCpuFreqMHz()[edit]

ESP.getCpuFreqMHz() returns the CPU frequency in MHz as an unsigned 8-bit integer.

(TOP)

ESP.getSketchSize()[edit]

ESP.getSketchSize() returns the size of the current sketch as an unsigned 32-bit integer.

(TOP)

ESP.getFreeSketchSpace()[edit]

ESP.getFreeSketchSpace() returns the free sketch space as an unsigned 32-bit integer.

(TOP)

ESP.getSketchMD5()[edit]

ESP.getSketchMD5() returns a lowercase String containing the MD5 of the current sketch.

(TOP)

ESP.getFlashChipId()[edit]

ESP.getFlashChipId() returns the flash chip ID as a 32-bit integer.

(TOP)

ESP.getFlashChipSize()[edit]

ESP.getFlashChipSize() returns the flash chip size, in bytes, as seen by the SDK (may be less than actual size).

(TOP)

ESP.getFlashChipRealSize()[edit]

ESP.getFlashChipRealSize() returns the real chip size, in bytes, based on the flash chip ID.

(TOP)

ESP.getFlashChipSpeed(void)[edit]

ESP.getFlashChipSpeed(void) returns the flash chip frequency, in Hz.

(TOP)

ESP.getCycleCount()[edit]

ESP.getCycleCount() returns the cpu instruction cycle count since start as an unsigned 32-bit. This is useful for accurate timing of very short actions like bit banging.

(TOP)

ESP.getVcc()[edit]

ESP.getVcc() may be used to measure supply voltage. ESP needs to reconfigure the ADC at startup in order for this feature to be available. Add the following line to the top of your sketch to use getVcc:

ADC_MODE(ADC_VCC);

TOUT pin has to be disconnected in this mode.
Note that by default ADC is configured to read from TOUT pin using analogRead(A0), and ESP.getVCC() is not available.



(TOP)

ESP.reset[edit]

esp8266 arduino core has soft reset: ESP.reset(). Calling this function you get a valid reset.

Note to software reset. esp8266 has a bug. If software reset (or exception) is executed in program started right after the flashing, the board goes back to flashing mode because the flashing flag is still active.

(TOP)

ESP.wdtDisable();[edit]

Disable the software watchdog
Although this disables the software watchdog, the hardware watchdog will still remain active, causing a reset after some time. As indicated in the comments of the wdtDisable method, if we stop the software watchdog by more than 6 seconds, the hardware watchdog will trigger.

ESP.wdtEnable(1000);[edit]

Re-enable the software watchdog
It’s important to note that an integer value needs to be passed as input argument of this method, which would correspond to the number of milliseconds for the watchdog to trigger. Nevertheless, this value makes no effect and it is not used in the internal call of the SDK ESP8266 functions
Additionally, in the header file, it’s clearly stated that, at the time, setting the timeout is not implemented. Unfortunately, it’s not clear what is the default value of the watchdog timer when we call this function, and neither it is documented in the SDK of the ESP8266.

ESP.wdtFeed();[edit]

In order to explicitly restart the watchdog, we can call the wdtFeed method. Fortunately, the ESP libraries implicitly reset the watchdog in many of the functions, so most of the time we don’t need to worry about feeding the watchdog. Nevertheless, it’s important to know that it exists, in order to troubleshoot spontaneous reboots of our programs.



(TOP)

ESP.WiFi[edit]

ESP8266WiFi Documentation

ESP8266 WiFi stack will save WiFi configuration to flash memory, and automatically reconnect to the same network on restart. This happens even if you aren't using WiFi functions. You can disable persistence by adding WiFi.persistent(false); in the beginning of your WiFi initialization code. To disable WiFi in a sketch where you don't need it you can use WiFi.mode(WIFI_OFF);.

Functions[edit]

hostname[edit]
Get the DHCP hostname assigned to ESP station.
WiFi.hostname()

Function returns String type. Default hostname is in format ESP_24xMAC where 24xMAC are the last 24 bits of module’s MAC address.

The hostname may be changed using the following function:

WiFi.hostname(aHostname)

Input parameter aHostname may be a type of char*, const char* or String. Maximum length of assigned hostname is 32 characters. Function returns either true or false depending on result. For instance, if the limit of 32 characters is exceeded, function will return false without assigning the new hostname.

Example code:

Serial.printf("Default hostname: %s\n", WiFi.hostname().c_str());
WiFi.hostname("Station_Tester_02");
Serial.printf("New hostname: %s\n", WiFi.hostname().c_str());


WiFi.scanNetworks(true)[edit]

The optional parameter, true, is an instruction to scan in asynchronous mode, i.e. trigger scanning process, do not wait for result (processing will be done in background) and move to the next line of code.
Example Code

WiFi.disconnect()[edit]

WiFi.disconnect() shuts down a connection to an access point that module may have automatically made using previously saved credentials.

mDNS[edit]

DNS works great for normal sites on the Internet, but most local networks don't have their own DNS server. This means that you can't reach local devices using a domain name, and you're stuck using IP addresses.

Fortunately, there's another way: multicast DNS, or mDNS.
mDNS uses domain names with the .local suffix, for example http://esp8266.local. If your computer needs to send a request to a domain name that ends in .local, it will send a multicast query to all other devices on the LAN that support mDNS, asking the device with that specific domain name to identify itself. The device with the right name will then respond with another multicast and send its IP address. Now that your computer knows the IP address of the device, it can send normal requests.

Luckily for us, the ESP8266 Arduino Core supports mDNS:

#include <ESP8266WiFi.h>        // Include the Wi-Fi library
#include <ESP8266WiFiMulti.h>   // Include the Wi-Fi-Multi library
#include <ESP8266mDNS.h>        // Include the mDNS library

ESP8266WiFiMulti wifiMulti;     // Create an instance of the ESP8266WiFiMulti class, called 'wifiMulti'

void setup() {
  Serial.begin(115200);         // Start the Serial communication to send messages to the computer
  delay(10);
  Serial.println('\n');

  wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1");   // add Wi-Fi networks you want to connect to
  wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2");
  wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");

  Serial.println("Connecting ...");
  int i = 0;
  while (wifiMulti.run() != WL_CONNECTED) { // Wait for the Wi-Fi to connect: scan for Wi-Fi networks, and connect to the strongest of the networks above
    delay(1000);
    Serial.print(++i); Serial.print(' ');
  }
  Serial.println('\n');
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());              // Tell us what network we're connected to
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());           // Send the IP address of the ESP8266 to the computer

  if (!MDNS.begin("esp8266")) {             // Start the mDNS responder for esp8266.local
    Serial.println("Error setting up MDNS responder!");
  }
  Serial.println("mDNS responder started");
}

void loop() { }


Upload it and ping to esp8266.local



(TOP)

ping.h[edit]

Needs more info here
After Ping.ping() has been called, the average response time (in milliseconds) can be retrieved with

int avg_time_ms = Ping.averageTime();



(TOP)

WDT- Watchdog Timer[edit]

Boot messages and Modes

Here is a very detailed explanation of the Watchdog timers in the ESP8266.

The ESP8266 is a little different than the standard Arduino boards in that it has the watchdog(WDT) turned on by default. If the watchdog timer isn't periodically reset then it will automatically reset your ESP8266. The watchdog is reset every time loop() runs or you call delay() or yield() but if you have blocking code like a while or for loop, then the watchdog may time out, resulting in your reset.

The delay() function is blocking so this prevents other code from running while it's sitting there waiting out the delay. delay() doesn't cause WDT reset though because it automatically calls yield() to prevent that.

When the ESP reboots, you get the reboot cause:

ets Jan  8 2013,rst cause:2, boot mode:(3,7)
  • Soft WDT: Cause 2
  • Hardware WDT: Cause 4
Cause for reset
Number Description
0 unknown
1 normal boot
2 reset pin
3 software reset
4 watchdog reset


Boot Mode
Number GPIO15 GPIO0 GPIO2 Mode
0 0V 0V 0V Not valid
1 0V 0V 3.3V Uart
2 0V 3.3V 0V Not valid
3 0V 3.3V 3.3V Flash
4 3.3V 0V 0V SDIO
5 3.3V 0V 3.3V SDIO
6 3.3V 3.3V 0V SDIO
7 3.3V 3.3V 3.3V SDIO


The timeout for the hardware watchdog is 8.2 seconds, and 3.2 seconds for the software watchdog timeout

Don't block software watchdog too long with blocking code, otherwise it will trigger hardware watchdog reset.
You can reset the WDT inside your blocking code with:

ESP.wdt_reset()

or

yield();




(TOP)

ESP Troubleshooting[edit]


Arduino ESP8266/ESP32 Exception Stack Trace Decoder



(TOP)

Floating Point experiments[edit]

//Floating point comparisons

float f1 = 1.11111111111111111111;
float f2 = 4.44444444444444444444;
float fSum = f1 + f2;
float fSqr = sqrtf(f1);
float fMul = f1 * f2;
float fDiv = f1 / f2;
float fPow = powf(f1, f2);
float fSin = sinf(f1);
double d1 = 1.11111111111111111111;
double d2 = 4.44444444444444444444;
double dSum = d1 + d2;
double dSqr = sqrt(d1);
double dMul = d1 * d2;
double dDiv = d1 / d2;
double dPow = pow(d1, d2);
double dSin = sin(d1);

Arduino
ESP


(TOP)

Projects[edit]

ESP32 Walkie-Talkie[edit]

Hackster.io tutorial

ESP-ZeroCode[edit]

Introduction from Expressif
Forum Discussion