ESP8266 ADC Detailed Description

Overview

The ADC (Analog-to-Digital Converter) in the ESP8266 is a crucial feature that allows the microcontroller to read analog signals and convert them into digital values for processing. This capability is essential for interfacing with various sensors and devices that output analog signals.

Specifications

How It Works

The ADC in the ESP8266 works by sampling the input voltage on the ADC0 pin. The analog voltage is compared to an internal reference voltage, and the resulting value is mapped to a digital value within the defined resolution. The output of the ADC can then be read in your code.

Pin Configuration

The ADC is accessible through the GPIO pin 0 (also labeled as A0 on some boards). To connect a sensor, simply attach its output to this pin, ensuring that the signal voltage does not exceed 1.0 V to avoid damaging the ADC.

Reading ADC Values

Here’s a simple example of how to read an analog value from the ADC using the Arduino IDE:

 

void setup() {
    Serial.begin(115200); // Initialize serial communication
}

void loop() {
    int adcValue = analogRead(A0); // Read ADC value from pin A0
    float voltage = adcValue * (1.0 / 1023.0); // Convert to voltage (0-1V)
    
    Serial.print("ADC Value: ");
    Serial.print(adcValue);
    Serial.print(" | Voltage: ");
    Serial.println(voltage);
    
    delay(1000); // Wait for 1 second before the next reading
}

Calibration and Considerations

The ADC readings can be affected by several factors, including noise and temperature variations. For accurate measurements, consider the following:

Conclusion

The ADC in the ESP8266 is a powerful feature that enables a variety of applications in sensor monitoring and data acquisition. Its ease of use and integration with the microcontroller makes it an essential tool for IoT and embedded projects.

ESP8266 I2C Master Mode Detailed Description

Overview

The I2C (Inter-Integrated Circuit) protocol allows multiple slave devices to communicate with a single master device using only two wires: SDA (Serial Data Line) and SCL (Serial Clock Line). The ESP8266 can function as an I2C master, enabling it to control and communicate with various I2C peripherals, such as sensors, displays, and other microcontrollers.

Specifications

How It Works

In master mode, the ESP8266 initiates communication by sending a start condition followed by the address of the target slave device. It then reads or writes data to that device, concluding with a stop condition. The master controls the clock line, ensuring synchronized communication.

Unlike the majority of microcontrollers, ESP8266 does not have hardware i2c interface and it is implemented in software

Pin Configuration

The I2C interface uses the following pins on the ESP8266:

Master Mode Example

Here’s an example demonstrating how to use the ESP8266 as an I2C master to communicate with a hypothetical I2C sensor:

 

 #include <Wire.h>
 
 #define SENSOR_ADDRESS 0x50 // Replace with your sensor's I2C address
 
 void setup() {
     Wire.begin(); // Join I2C bus as master
     Serial.begin(115200); // Initialize serial communication
 }
 
 void loop() {
     Wire.beginTransmission(SENSOR_ADDRESS); // Start communication with the sensor
     Wire.write(0x00); // Send a command to the sensor (example command)
     Wire.endTransmission(); // End the transmission
 
     delay(100); // Wait for a short period
 
     Wire.requestFrom(SENSOR_ADDRESS, 2); // Request 2 bytes from the sensor
     while (Wire.available()) { // While there are bytes available
         int data = Wire.read(); // Read a byte
         Serial.println(data); // Print the data to the serial monitor
     }
 
     delay(1000); // Wait for 1 second before the next iteration
 }
         

Considerations

When using the I2C protocol, be mindful of the following:

Conclusion

The ESP8266's ability to operate as an I2C master enables seamless communication with a variety of peripheral devices. This functionality is essential for many IoT applications, allowing for sensor data acquisition and control over connected components.

ESP8266 I2S Interface

The ESP8266 features a basic I2S interface for audio output. It supports transmit (TX) only in master mode. I2S input (RX) is not supported. The interface is commonly used for sending audio to an I2S DAC or amplifier.

GPIO Mapping:

🔹 Example: Generate a 1 kHz Sine Wave (I2S Audio TX)


#include <Arduino.h>
extern "C" {
  #include "i2s_reg.h"
  #include "i2s.h"
}

#define SAMPLE_RATE 44100
#define PI 3.14159265
uint16_t sineWave[256];

void setupI2S() {
  i2s_begin();
  i2s_set_rate(SAMPLE_RATE);
}

void generateSineWave() {
  for (int i = 0; i < 256; i++) {
    sineWave[i] = 0x8000 + 0x7FFF * sin(2 * PI * i / 256);
  }
}

void setup() {
  generateSineWave();
  setupI2S();
}

void loop() {
  for (int i = 0; i < 256; i++) {
    while (!i2s_available()) delayMicroseconds(10);
    i2s_write_sample(sineWave[i]);
  }
}
    

Note: You must use the i2slibrary available in ESP8266 Arduino core. The audio output is in 16-bit mono format, typically connected to an I2S DAC or class D amplifier.

Resources: ESP8266Audio, esp8266/Arduino

ESP8266 SPI Detailed Description

Overview

The SPI (Serial Peripheral Interface) is a synchronous serial communication protocol used for short-distance communication, primarily in embedded systems. The ESP8266 supports SPI in both master and slave modes, allowing it to communicate with various peripherals such as sensors, displays, and memory devices.

Specifications

Master Mode

In master mode, the ESP8266 initiates the communication and controls the clock line (SCK). It can read and write data to one or multiple slave devices. The master sends commands to the slave, managing data flow effectively.

Pin Configuration for Master Mode

Master Mode Example

Below is an example demonstrating how to use the ESP8266 as an SPI master to communicate with a hypothetical SPI device:

 

 #include <SPI.h>
 
 void setup() {
     SPI.begin(); // Initialize SPI as master
     pinMode(15, OUTPUT); // Set CS pin as output
     digitalWrite(15, HIGH); // Deselect the slave
 }
 
 void loop() {
     digitalWrite(15, LOW); // Select the slave
     byte response = SPI.transfer(0x01); // Send a byte and receive response
     digitalWrite(15, HIGH); // Deselect the slave
 
     Serial.print("Response: ");
     Serial.println(response, HEX); // Print the response in hex format
 
     delay(1000); // Wait for 1 second before the next iteration
 }
         

Slave Mode

In slave mode, the ESP8266 listens for commands from the master device. It responds to data requests and can also send data back to the master. The slave must wait for the master to initiate communication.

Pin Configuration for Slave Mode

Slave Mode Example

The following example demonstrates how to set up the ESP8266 as an SPI slave. Note that the handling of SPI in slave mode may require additional care due to timing:

 

 #include <SPI.h>
 
 volatile byte dataReceived = 0;
 
 void setup() {
     SPI.begin(); // Initialize SPI
     pinMode(15, INPUT); // Set CS pin as input
     SPCR |= _BV(SPE); // Enable SPI in slave mode
 }
 
 ISR(SPI_STC_vect) {
     dataReceived = SPDR; // Read the received data
     SPDR = dataReceived; // Echo back the received data
 }
 
 void loop() {
     // Main loop can perform other tasks
     if (dataReceived) {
         Serial.print("Data received: ");
         Serial.println(dataReceived, HEX); // Print received data
         dataReceived = 0; // Clear the received data
     }
 }
         

Considerations

When using SPI with the ESP8266, consider the following:

Conclusion

The ESP8266's SPI capabilities in both master and slave modes provide flexible options for high-speed communication with a variety of peripherals. This functionality is essential for applications requiring fast data exchange, such as sensors and displays.

Understanding Timers in ESP8266

The ESP8266 microcontroller features simple yet effective hardware timers. These are primarily used for scheduling tasks, handling delays, and generating PWM signals. Unlike more advanced microcontrollers, the ESP8266 has fewer timer resources, making efficient use of these timers critical.

Types of Timers in ESP8266

ESP8266 includes two types of timers:

Timer Registers

The ESP8266 timer is controlled through specific registers:

Timer Modes

The ESP8266 operates its hardware timer in two basic modes:

Prescaler and Clock Source

The ESP8266 timer operates using the internal clock, which is divided using a prescaler to control the counting frequency. This allows you to adjust how frequently the timer generates events or interrupts.

Interrupts and Events

When the timer reaches its alarm value, it generates an interrupt. The interrupt service routine can then be used to perform time-critical tasks. Since ESP8266 has limited hardware resources, these interrupts are crucial for managing precise time-sensitive tasks.

Conclusion

While ESP8266 only has a single hardware timer, it is still an essential tool for managing precise timing operations. For more advanced timing needs, software-based timers can be utilized, although they rely on interrupts, which can affect system performance during heavy workloads.

ESP8266 Timer Demonstration

This page provides examples of how to use the ESP8266 hardware timers in various configurations, such as generating a frequency, creating PWM signals at 25kHz, one-shot pulse generation, frequency measurement, and timer interrupts. Each section includes a code example in Arduino C.

1. Frequency Generator

This example demonstrates how to use the ESP8266 timer to generate a frequency by toggling a pin at a specified rate. The timer runs in a loop mode with a 1kHz output signal.


void setup() {
  pinMode(2, OUTPUT); // Use GPIO 2 as output
  timer1_attachInterrupt(togglePin); // Attach the interrupt to toggle the pin
  timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP); // Enable timer with no prescaler
  timer1_write(80000000 / (2 * 1000)); // Set frequency to 1kHz (adjust 1000 for desired frequency)
}

void togglePin() {
  digitalWrite(2, !digitalRead(2)); // Toggle pin state
}

void loop() {
  // Main loop does nothing, frequency generated by timer interrupt
}
        

2. PWM Generator at 25kHz

This example shows how to generate a 25kHz PWM signal on a pin with a 50% duty cycle using the ESP8266.


void setup() {
  pinMode(5, OUTPUT); // Set GPIO5 as PWM output
  analogWriteFreq(25000); // Set PWM frequency to 25kHz
  analogWrite(5, 128); // Set 50% duty cycle (0-255 scale)
}

void loop() {
  // Change duty cycle over time if needed
}
        

3. One-Shot Pulse Generation

This code generates a one-shot pulse on a GPIO pin. The pulse width is controlled in microseconds, and the timer runs only once in single-shot mode.


void setup() {
  pinMode(4, OUTPUT); // Set GPIO4 as output
  digitalWrite(4, LOW); // Start with low signal
  timer1_attachInterrupt(generatePulse); // Attach one-shot pulse function
  timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE); // Set timer to one-shot mode
  timer1_write(50000); // Set time for 50ms pulse
}

void generatePulse() {
  digitalWrite(4, HIGH); // Set high
  delayMicroseconds(100); // Set pulse width (adjust as needed)
  digitalWrite(4, LOW); // Set low again
}

void loop() {
  // Wait for next pulse trigger
}
        

4. Frequency Measurement

To measure the frequency of a signal on a GPIO pin, this code counts pulses using interrupts and calculates the frequency over a 1-second interval.


volatile unsigned long pulseCount = 0;
unsigned long prevMillis = 0;
unsigned long frequency = 0;

void IRAM_ATTR countPulse() {
  pulseCount++; // Count pulses
}

void setup() {
  pinMode(12, INPUT); // Set GPIO12 as input for frequency signal
  attachInterrupt(digitalPinToInterrupt(12), countPulse, RISING); // Count rising edges
  prevMillis = millis();
}

void loop() {
  if (millis() - prevMillis >= 1000) { // Every second, calculate frequency
    frequency = pulseCount;
    pulseCount = 0;
    prevMillis = millis();
    Serial.print("Frequency: ");
    Serial.println(frequency); // Output frequency value
  }
}
        

5. Timer Interrupt Example

This example demonstrates using the ESP8266 timer to trigger an interrupt every 5 seconds. The timer is set in loop mode, and an interrupt flag is set when the timer triggers.


volatile bool timerFlag = false;

void IRAM_ATTR onTimer() {
  timerFlag = true; // Set flag on timer interrupt
}

void setup() {
  Serial.begin(115200);
  timer1_attachInterrupt(onTimer); // Attach the interrupt service routine
  timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP); // Enable timer with prescaler
  timer1_write(5000000); // Set timer to trigger every 5 seconds
}

void loop() {
  if (timerFlag) {
    Serial.println("Timer interrupt triggered");
    timerFlag = false; // Reset flag
  }
}
        

ESP RTC (Real-Time Clock) Detailed Description

The ESP8266 microcontroller does not have a Real-Time Clock (RTC), it does however have networking and ESPconfig by Peter Dunne takes advantage of this to provide NTP functionality.

ESP8266 Interrupts Detailed Description

Overview

Interrupts are a powerful feature in microcontrollers that allow the processor to respond to events without polling. The ESP8266 supports various types of interrupts that can enhance the responsiveness and efficiency of applications.

1. External Interrupts

External interrupts can be triggered by changes in the state of a GPIO pin, such as rising or falling edges. The ESP8266 can respond to these changes to perform actions quickly.

Example:

 

#define BUTTON_PIN 4 // GPIO pin for button

void ICACHE_RAM_ATTR handleButtonPress() {
    // Code to execute when button is pressed
}

void setup() {
    pinMode(BUTTON_PIN, INPUT_PULLUP); // Set button pin as input
    attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), handleButtonPress, FALLING);
}

void loop() {
    // Main loop does other tasks
}
        

2. Serial Interrupts

Serial interrupts can be used to respond to incoming data on the serial interface. This is useful for processing data as it arrives.

Example:

 

volatile bool dataReady = false;

void ICACHE_RAM_ATTR onReceive() {
    dataReady = true; // Flag that data has been received
}

void setup() {
    Serial.begin(115200);
    Serial.setTimeout(100); // Set a timeout for Serial read
    attachInterrupt(digitalPinToInterrupt(0), onReceive, RISING);
}

void loop() {
    if (dataReady) {
        String input = Serial.readString();
        Serial.println("Received: " + input);
        dataReady = false; // Clear the flag
    }
}
        

3. Timer Interrupts

Timer interrupts allow code to execute at defined intervals, enabling precise timing for tasks such as periodic sensor readings.

Example:

 

volatile bool timerFlag = false;

void IRAM_ATTR onTimer() {
    timerFlag = true; // Set flag for main loop
}

void setup() {
    Timer1.attachInterrupt(onTimer); // Attach interrupt
    Timer1.enable(TIMER1); // Start timer
}

void loop() {
    if (timerFlag) {
        // Execute periodic task
        timerFlag = false; // Reset flag
    }
}
        

4. SPI Interrupts

SPI interrupts are typically managed through callback functions when using libraries. However, you can still handle events by checking the SPI buffer in a regular loop or using an external interrupt to signal when data is ready.

Example:

 

#define SPI_CS_PIN 15

void ICACHE_RAM_ATTR handleSPI() {
    // Handle SPI data reception
}

void setup() {
    pinMode(SPI_CS_PIN, OUTPUT);
    attachInterrupt(digitalPinToInterrupt(SPI_CS_PIN), handleSPI, FALLING);
}

void loop() {
    // Main loop can perform other tasks
}
        

5. WiFi Interrupts

WiFi events can trigger interrupts when the ESP8266 connects to a network or receives data. You can use callback functions to handle these events.

Example:

 

void onWiFiEvent(WiFiEvent_t event) {
    switch (event) {
        case SYSTEM_EVENT_STA_START:
            Serial.println("WiFi started");
            break;
        case SYSTEM_EVENT_STA_CONNECTED:
            Serial.println("Connected to WiFi");
            break;
        // Handle other events
    }
}

void setup() {
    WiFi.onEvent(onWiFiEvent); // Attach WiFi event handler
    WiFi.begin("yourSSID", "yourPASSWORD"); // Start WiFi connection
}

void loop() {
    // Main loop can perform other tasks
}
        

Conclusion

The ESP8266 offers versatile interrupt capabilities across various functionalities, enabling efficient and responsive applications. By leveraging these interrupts, developers can create responsive and efficient systems that interact seamlessly with external events.

ESP8266 Configuration using ESPconfig

The ESPconfig library by Peter Dunne is a versatile tool for easy configuration of ESP8266 and ESP32 devices. It provides various functionalities, such as WiFi configuration, OTA updates, and web-based user management. This example demonstrates the usage of the ESPconfig library for setting up the ESP8266 in different modes:

Features

Example Code: ESPconfig Setup

Below is an example that shows how to initialize the ESPconfig library and configure it to operate in client, station, and relay modes:

 
    /*  author: Peter Dunne, peterjazenga@gmail.com
 *  purpose: to simplify the management of ESP8266 & ESP32 WiFi configuration
 *  Includes NTP time client, OTA, WPS AP mode and information features
 *  Web interface to Configure WiFi interface
 *  Bluetooth (ESP32 only) control
 *  
 *  This module imports code by Peter Dunne from previous ESP projects in power sensing, RC and on/off power switches
 *  
 *  sysConfig.init(); is called after Serial.begin(); and it handles all WiFi, OTA, NAT, Time setting and Bluetooth configuration
 *  WPS is also supported via sysConfig
 *  sysConfig.run(); keeps things updated, provides for servicing of the OTA & Web server issues among others, it also handles the blinking of the status LED
 *  Released under the Mozilla Public License
 */

#include "sysconfig8266.h";

void setup() {
  Serial.begin(115200);
  sysConfig.init();
  Serial.println("Ready.");  
 }

void loop() {
  sysConfig.run();
}
        

Explanation of the Code

The example initializes the ESPconfig object and starts the configuration portal if WiFi credentials are not saved or if the connection fails. Once the user enters their WiFi credentials via the web interface, they are saved to the internal memory, and the ESP8266 will automatically connect to the specified network in the future.

WiFi Client Mode

In WiFi Client Mode, the ESP8266 connects to an existing WiFi network using the provided credentials. If the connection fails or if the credentials are not available, the ESPconfig library automatically starts the configuration portal, allowing the user to input WiFi details manually.

Access Point (AP) Mode

In Access Point Mode, the ESP8266 creates a local WiFi network, allowing users to connect to it and configure various settings via a web page. This mode is typically used for initial configuration when the device is deployed for the first time or when the WiFi network changes.

Relay Mode

The Relay Mode is specific to the ESP8266, allowing it to function as a network extender. In this mode, the ESP8266 connects to an existing WiFi network as a client and broadcasts its own access point, effectively extending the coverage of the original network.

More Features

The ESPconfig library offers additional functionalities such as:

ESP8266 WiFi Legacy Modes Demonstration

This page provides examples and detailed descriptions of how to use the ESP8266 in three different WiFi modes: Client Mode, Station Mode, and Relay Mode. The code examples are written in Arduino C and are accompanied by explanations for easy understanding.

1. WiFi Client Mode

In WiFi Client mode, the ESP8266 connects to an existing WiFi network and acts as a client. It can be used to connect to a web server, make HTTP requests, or communicate with other devices on the same network.


// Include the necessary libraries
#include <ESP8266WiFi.h>

// WiFi credentials
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";

void setup() {
  Serial.begin(115200);

  // Connect to WiFi network
  WiFi.begin(ssid, password);
  Serial.println("Connecting to WiFi...");

  // Wait until connected
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  // Main loop, nothing required for basic WiFi client setup
}
    

Explanation: This example connects the ESP8266 to an existing WiFi network by providing the SSID and password. Once connected, the IP address is printed to the serial monitor. You can use this as the base for making HTTP requests or communicating with servers.

2. WiFi Station Mode

In Station Mode, the ESP8266 acts as a WiFi access point, allowing other devices to connect to it. This mode is useful for setting up a local network where the ESP8266 can act as a server.


// Include the necessary libraries
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

// WiFi credentials for the access point
const char* ssid = "ESP8266_Access_Point";
const char* password = "12345678";

// Create a web server on port 80
ESP8266WebServer server(80);

void handleRoot() {
  server.send(200, "text/plain", "Hello from ESP8266!");
}

void setup() {
  Serial.begin(115200);
  
  // Start the ESP8266 in access point mode
  WiFi.softAP(ssid, password);

  // Get and print the IP address of the access point
  Serial.print("Access Point IP: ");
  Serial.println(WiFi.softAPIP());

  // Define the root URL
  server.on("/", handleRoot);

  // Start the web server
  server.begin();
  Serial.println("Web server started.");
}

void loop() {
  // Handle incoming client requests
  server.handleClient();
}
    

Explanation: This example demonstrates how to configure the ESP8266 as a WiFi access point. The ESP8266 creates its own network, allowing devices to connect. It also runs a basic web server that responds with "Hello from ESP8266!" when accessed via a browser.

3. WiFi Relay Mode

In Relay Mode, the ESP8266 connects to an existing WiFi network and simultaneously allows other devices to connect to it, functioning as both a client and an access point. This is useful for extending network coverage or for acting as an intermediary between networks.


// Include the necessary libraries
#include <ESP8266WiFi.h>

// WiFi credentials for both client and access point
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
const char* apSSID = "ESP8266_Relay";
const char* apPassword = "relay_pass";

void setup() {
  Serial.begin(115200);

  // Connect to the existing WiFi network (Client Mode)
  WiFi.begin(ssid, password);
  Serial.println("Connecting to WiFi...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("\nConnected to WiFi.");
  Serial.print("Client Mode IP: ");
  Serial.println(WiFi.localIP());

  // Set up the ESP8266 as an access point (Station Mode)
  WiFi.softAP(apSSID, apPassword);
  Serial.print("Access Point IP: ");
  Serial.println(WiFi.softAPIP());
}

void loop() {
  // Main loop does nothing in this example
}
    

Explanation: This example shows how to use the ESP8266 in relay mode. The ESP8266 connects to an existing WiFi network as a client and simultaneously creates its own access point. This allows it to extend the WiFi coverage or act as a gateway between networks.

ESP8266 Detailed Description

Overview

The ESP8266 is a low-cost Wi-Fi microchip with full TCP/IP stack and microcontroller capability. It is widely used in IoT (Internet of Things) applications due to its affordability, ease of use, and robust capabilities.

Specifications

Features

Common Applications

The ESP8266 is commonly used in various applications, including:

Programming the ESP8266

Programming the ESP8266 is straightforward, especially with the Arduino IDE. The user can easily upload code to the microcontroller via a USB-to-serial adapter. Below is a simple example of connecting to a Wi-Fi network:


#include <ESP8266WiFi.h>

const char* ssid = "your_SSID"; // Your network SSID (name)
const char* password = "your_PASSWORD"; // Your network password

void setup() {
    Serial.begin(115200); // Start the Serial communication
    WiFi.begin(ssid, password); // Connect to Wi-Fi

    while (WiFi.status() != WL_CONNECTED) {
        delay(1000); // Wait for connection
        Serial.println("Connecting to WiFi...");
    }

    Serial.println("Connected to WiFi!");
}

void loop() {
    // Your main code
}
        

ESP8266‑01 Pinout

ESP8266‑01 module pinout diagram

Image: Sayan123Wiki / Wikimedia Commons, CC BY-SA 4.0

ESP‑8266 (ESP‑12E / NodeMCU) Pinout

ESP8266 ESP‑12E development board pinout diagram

Image: from GitHub "Googler00tGER / NodeMCU‑ESP12E‑pinouts" repository. Please check the repo for full license / reuse permission. (Source: GitHub repo)

Conclusion

The ESP8266 has become a staple in the maker and IoT communities due to its low cost, simplicity, and versatility. Whether you are building a simple Wi-Fi-enabled device or a complex IoT system, the ESP8266 is an excellent choice for your project.

List of ESP8266 variants

Board CPU Speed RAM Flash Memory Peripherals Operating Voltage Other Specifications
ESP8266-01 80 MHz (Tensilica Xtensa LX106) 64 KB 512 KB - 1 MB 2 GPIO, UART, SPI 3.3V Basic Wi-Fi module, minimal GPIO
ESP8266 NodeMCU 80/160 MHz (Tensilica Xtensa LX106) 128 KB 4 MB 11 GPIO, UART, SPI, I2C, ADC, PWM 3.3V Popular development board, Lua-based firmware, USB interface
ESP8266 WeMos D1 Mini 80/160 MHz (Tensilica Xtensa LX106) 128 KB 4 MB 11 GPIO, UART, SPI, I2C, ADC, PWM 3.3V Compact size, compatible with Arduino IDE, widely used in IoT projects
ESP8285 ESP-M2 80/160 MHz (Tensilica Xtensa LX106) 64 KB 1 MB 8 GPIO, UART, SPI 3.3V Built-in flash, ideal for space-constrained designs
ESP8285 ESP-01F 80/160 MHz (Tensilica Xtensa LX106) 64 KB 1 MB 4 GPIO, UART, SPI 3.3V Miniature form factor, built-in flash
ESP8266 ESP-12E 80/160 MHz (Tensilica Xtensa LX106) 128 KB 4 MB 17 GPIO, UART, SPI, I2C, ADC 3.3V One of the most popular ESP8266 variants, ideal for IoT applications
ESP8266 ESP-12F 80/160 MHz (Tensilica Xtensa LX106) 128 KB 4 MB 17 GPIO, UART, SPI, I2C, ADC 3.3V Similar to ESP-12E but with improved antenna design
ESP8266 Huzzah 80/160 MHz (Tensilica Xtensa LX106) 128 KB 4 MB 9 GPIO, UART, SPI, I2C, ADC 3.3V Adafruit's version of the ESP8266, breadboard-friendly