# ESP32 vs ESP8266 Chip Info Properties: What ESP-Flasher Displays

> Discover ESP32 vs ESP8266 chip info displayed by ESP-Flasher. Learn about core count, CPU frequency, Bluetooth support, chip_id and more to choose the right chip for your project.

- Repository: [Jason2866/esp_flasher](https://github.com/jason2866/esp_flasher)
- Tags: deep-dive
- Published: 2026-03-04

---

**ESP-Flasher displays five common properties for all chips (family, model, MAC, is_esp32 flag) and adds variant-specific fields: ESP32 devices expose core count, CPU frequency, Bluetooth support, embedded flash status, and ADC calibration data, while ESP8266 devices only expose a numeric chip_id.**

When flashing firmware with the `jason2866/esp_flasher` tool, understanding the hardware capabilities of your target device is critical. The library extracts detailed **chip info properties** through its `ChipInfo` class hierarchy, returning different metadata dictionaries depending on whether you're working with an ESP32 or ESP8266 variant. This article breaks down exactly which fields appear in the output dictionary for each chip family based on the current source code implementation.

## Common Properties Across All Chip Families

The base `ChipInfo` class defined in [`esp_flasher/common.py`](https://github.com/jason2866/esp_flasher/blob/main/esp_flasher/common.py) establishes the universal identification fields shared by every supported microcontroller. According to the source code at lines 52-66, all chip info objects expose four core attributes through the `as_dict()` method:

- **family**: The chip family string (e.g., "ESP32" or "ESP8266")
- **model**: Human-readable model name including revision information
- **mac**: The device's MAC address as a formatted string
- **is_esp32**: A boolean flag indicating ESP32 architecture (populated during detection)

These fields form the foundation of the dictionary returned whenever you call `read_chip_info()` on a detected device.

## Variant-Specific Chip Information

Beyond the common base properties, ESP-Flasher implements two specialized subclasses that capture hardware-specific capabilities unique to each architecture.

### ESP32 Properties (ESP32ChipInfo)

For all ESP32-family devices—including the ESP32, ESP32-S2, ESP32-S3, and ESP32-C3—the `ESP32ChipInfo` subclass extends the base class with five additional fields. As implemented in [`esp_flasher/common.py`](https://github.com/jason2866/esp_flasher/blob/main/esp_flasher/common.py) lines 68-96, the `as_dict()` method includes:

- **num_cores**: Integer count of CPU cores (1 or 2)
- **cpu_frequency**: String representation of the clock speed (e.g., "160MHz")
- **has_bluetooth**: Boolean indicating BT/BLE support capability
- **has_embedded_flash**: Boolean flagging whether flash memory is integrated on-chip
- **has_factory_calibrated_adc**: Boolean showing if ADC calibration data exists in eFuse

These properties allow firmware tools to verify that compiled binaries match the target hardware's peripheral set and computational resources.

### ESP8266 Properties (ESP8266ChipInfo)

The ESP8266 variant uses a leaner information structure. The `ESP8266ChipInfo` subclass defined at lines 100-112 of [`esp_flasher/common.py`](https://github.com/jason2866/esp_flasher/blob/main/esp_flasher/common.py) adds exactly one unique field to the common base:

- **chip_id**: A numeric identifier specific to the ESP8266 ROM (distinct from the MAC address)

Unlike the ESP32 implementation, the ESP8266 subclass does not expose core counts, frequency data, or peripheral flags, reflecting the simpler, single-core architecture of these legacy devices.

## Retrieving Chip Information Programmatically

To access these properties in your own Python scripts, use the `detect_chip()` and `read_chip_info()` functions provided by the library. The following example demonstrates how to extract the complete metadata dictionary for any connected device:

```python
from esp_flasher.common import read_chip_info, detect_chip

# Open serial connection to target device

chip = detect_chip("/dev/ttyUSB0")  # or "COM3" on Windows

info = read_chip_info(chip)

# Display variant-specific dictionary

print(info.as_dict())

```

For an ESP32-C3, this outputs:

```python
{
  "family": "ESP32",
  "model": "ESP32-C3 (revision v0.1)",
  "mac": "AA:BB:CC:DD:EE:FF",
  "is_esp32": None,
  "num_cores": 1,
  "cpu_frequency": "160MHz",
  "has_bluetooth": True,
  "has_embedded_flash": True,
  "has_factory_calibrated_adc": False
}

```

For an ESP8266, the output contains only the common fields plus the chip identifier:

```python
{
  "family": "ESP8266",
  "model": "ESP8266EX",
  "mac": "11:22:33:44:55:66",
  "is_esp32": False,
  "chip_id": 1234567
}

```

## Implementation Architecture and Source Files

The chip information system relies on coordination between three primary modules in the `jason2866/esp_flasher` repository:

- **esp_flasher/common.py**: Defines the `ChipInfo` base class, `ESP32ChipInfo`, `ESP8266ChipInfo`, and the `read_chip_info()` factory function that instantiates the correct subclass based on the detected ROM type.
- **esp_flasher/own_esptool.py**: Provides the low-level ROM loader classes (`ESP32ROM`, `ESP8266ROM`) whose methods (`get_chip_description()`, `get_chip_features()`, `chip_id()`) supply raw hardware data to populate the info objects.
- **esp_flasher/__main__.py**: The CLI entry point that orchestrates the detection workflow, ultimately calling `detect_chip()` followed by `read_chip_info()` during the flashing process.

## Summary

- The **ChipInfo** base class provides universal identification fields: `family`, `model`, `mac`, and `is_esp32`.
- **ESP32** variants expose five additional hardware capability fields through `ESP32ChipInfo`: `num_cores`, `cpu_frequency`, `has_bluetooth`, `has_embedded_flash`, and `has_factory_calibrated_adc`.
- **ESP8266** devices return only one unique property through `ESP8266ChipInfo`: the numeric `chip_id`.
- All properties are accessed uniformly via the `as_dict()` method, regardless of underlying chip architecture.
- The `read_chip_info()` function in [`esp_flasher/common.py`](https://github.com/jason2866/esp_flasher/blob/main/esp_flasher/common.py) automatically instantiates the correct subclass based on the ROM type detected by `detect_chip()`.

## Frequently Asked Questions

### How do I check if my device supports Bluetooth using ESP-Flasher?

Check the `has_bluetooth` key in the dictionary returned by `as_dict()`. For ESP32 variants, this boolean indicates BT/BLE capability, while ESP8266 devices will not include this key in their output since they lack native Bluetooth support.

### Why does my ESP8266 show fewer properties than my ESP32?

The ESP8266 architecture uses a simplified `ESP8266ChipInfo` class that only adds the `chip_id` field to the base properties. The ESP32 family includes additional fields like `num_cores` and `has_embedded_flash` because these devices feature heterogeneous multiprocessing and varying peripheral configurations that firmware must verify before flashing.

### Where is the MAC address format defined in the source code?

The MAC address string formatting occurs within the `ChipInfo` base class initialization in [`esp_flasher/common.py`](https://github.com/jason2866/esp_flasher/blob/main/esp_flasher/common.py). The underlying raw bytes are retrieved from the ROM loader classes in [`esp_flasher/own_esptool.py`](https://github.com/jason2866/esp_flasher/blob/main/esp_flasher/own_esptool.py), then normalized into the standard colon-separated hex string stored in the `mac` property.

### Can I use read_chip_info() without flashing the device?

Yes. The `read_chip_info()` function only queries the chip's identification registers and eFuse data through the serial bootloader. It does not write to flash memory, making it safe to use for hardware detection and inventory purposes without altering the device firmware.