Bitaxe Education

AxeOS Explained: The Complete Guide to Bitaxe Firmware

AxeOS firmware dashboard displaying live hashrate, efficiency, and share metrics next to a Bitaxe Gamma 601 Bitcoin miner

AxeOS is the open-source operating system that runs on every Bitaxe Bitcoin miner, controlling the ASIC chip, managing pool connections, and serving a browser-based dashboard for monitoring and configuration. Built on the ESP-Miner firmware codebase at github.com/bitaxeorg/ESP-Miner, the project has accumulated over 1,180 commits and 841 GitHub stars as of March 2026.

This guide is divided into two parts. Part 1 covers everything you need to operate your Bitaxe: accessing the dashboard, understanding every metric, configuring settings, updating the esp-miner firmware, and troubleshooting common issues. Part 2 goes under the hood for developers and enthusiasts: system architecture, mining pipeline internals, ASIC driver layer, REST API reference, and building from source.


Part 1: Operating Your Bitaxe with AxeOS


What Is AxeOS?

AxeOS is the operating system that runs on the ESP32-S3 microcontroller inside every Bitaxe Bitcoin miner. It controls the mining ASIC chip, connects to your Wi-Fi network, communicates with your chosen mining pool, monitors temperature and power, and serves a web-based dashboard you can access from any browser on your local network.

The underlying codebase is called ESP-Miner, hosted at github.com/bitaxeorg/ESP-Miner. ESP-Miner is the full firmware package that handles everything from ASIC communication to network connectivity. AxeOS is the operating system and web interface built on top of that firmware, the dashboard and control layer you interact with through your browser. In everyday use, most people refer to the entire system as AxeOS.

The software is 100% open source under the GPL-3.0 license. Anyone can inspect, modify, or contribute to the code. As of March 2026, the project has over 1,180 commits from dozens of contributors worldwide, according to the repository’s public statistics.

AxeOS requires no external software, mobile app, or cloud account. Your Bitaxe runs autonomously once configured. The only thing you need is a web browser on the same Wi-Fi network as your miner.


How to Access the AxeOS Dashboard

There are two ways to access AxeOS depending on whether your Bitaxe is already connected to your Wi-Fi network.

First-Time Setup (Access Point Mode): When a Bitaxe powers on without saved Wi-Fi credentials (brand new or after a factory reset), it broadcasts its own Wi-Fi network named something like “Bitaxe_XXXX.” Connect to this network from your phone or computer (no password required), then open a browser and navigate to http://192.168.4.1. This loads the AxeOS interface where you can enter your home Wi-Fi credentials. After saving, the Bitaxe reboots and joins your network.

Normal Access (Station Mode): Once connected to your Wi-Fi, the Bitaxe’s IP address appears on the OLED or LCD display. Open any browser on the same network and type that IP address (for example, http://192.168.1.42). The AxeOS dashboard loads immediately.

If you cannot find the IP address, check your router’s admin page for connected devices, or use a network scanner like Angry IP Scanner. Look for a device with port 80 open, which indicates the AxeOS web server is running. Note: prior to v2.5.0, the device could also be accessed at http://bitaxe on networks supporting mDNS, but hostname access was removed in v2.5.0 as part of a security patch. The IP address is now required.

If the main dashboard fails to load (for example, after a corrupted web interface update), a minimal recovery page is available at http://[IP]/recovery. This emergency page allows firmware re-flashing without the full Angular interface.

For a step-by-step walkthrough of initial setup, see How to Set Up Your Bitaxe.


Understanding the Dashboard: What Every Metric Means

The AxeOS dashboard is the first screen you see after logging in. It updates every 5 seconds (confirmed in the source code at home.component.ts, which uses a 5-second polling interval against the /api/system/info endpoint). Here is what each metric means and what “healthy” looks like.

Hashrate: Your miner’s current speed, measured in TH/s (terahashes per second). AxeOS displays multiple hashrate values: the instantaneous reading, plus 1-minute, 10-minute, and 1-hour rolling averages. The actual hashrate is calculated from the shares (domains) your miner submits over time, while the “expected hashrate” value shown alongside is derived from your current frequency and voltage settings. Fluctuations of 10 to 15% around the expected hashrate are completely normal. If your actual hashrate is consistently below 85% of the expected value, something may need attention (cooling, power supply, or settings). In some cases, minor underperformance is the result of silicon lottery, the natural variation in ASIC chip quality that means no two chips perform identically at the same frequency and voltage.

Efficiency (J/TH): How much electricity your miner uses per terahash of computation, measured in joules per terahash. Lower is better. The dashboard calculates this by dividing power consumption by hashrate. A Bitaxe Gamma running at stock settings typically achieves around 15 to 18 J/TH, according to customer-reported benchmarks.

Error Percentage: The difference between your actual hashrate and the expected hashrate, expressed as a percentage. A healthy error percentage stays under 5%. Consistently high values may indicate thermal throttling or a firmware issue. For a detailed breakdown of what error percentage means and how to interpret it, see our Bitaxe Hashrate Error Percentage Guide.

Temperature: The ASIC chip’s die temperature in degrees Celsius. AxeOS reads this from the thermal sensor (EMC2101, EMC2103, EMC2302, or TMP1075, depending on your hardware variant) connected via I2C. Aim to keep this below 65C for optimal longevity. The firmware’s overheat protection triggers at 75C (verified at power_management_task.c line 23-36). A second temperature reading (“Temp 2”) appears on dual-chip boards like the Bitaxe Gamma Duo.

VR Temp: The voltage regulator’s internal temperature. This component delivers power to the ASIC chip and generates its own heat. The firmware’s emergency shutdown triggers if this exceeds 105C (verified in the same source file). Under normal conditions, VR temperature should stay well below 90C.

Power (W): Total power consumption in watts. On all recent Bitaxe models, power readings come from the TPS546D24 voltage regulator. Some older models used a separate INA260 power monitor IC.

Input Voltage (mV): The voltage your power supply is delivering to the device. If this drops significantly below the expected value (5V for single-chip models, 12V for multi-chip models), your power supply may be undersized or faulty.

Core Voltage (mV): The voltage being delivered to the ASIC chip itself. This is set through the AxeOS settings and delivered by the on-board voltage regulator. The “actual” core voltage reading shows what the regulator is physically outputting, which should closely match your configured value.

Fan Speed (RPM / %): Current fan speed in revolutions per minute and as a percentage of maximum duty cycle. In automatic mode, AxeOS adjusts this dynamically based on temperature. In v2.13.0, the fan controller was refactored into its own dedicated FreeRTOS task for improved responsiveness. Hovering over the fan metric shows individual RPM values for boards with multiple fans.

Accepted Shares: The number of valid proof-of-work solutions your miner has submitted that the pool acknowledged. This counter should steadily increase during normal operation.

Rejected Shares: Submissions the pool rejected. The most common reason is the share arrived too late (stale), meaning the pool had already moved on to new work. Shares can also be rejected if they do not meet the pool’s assigned difficulty target, which can occur after a reconnection or pool failover. A healthy Bitaxe should have a rejection rate below 2%. If rejections climb higher, it usually indicates Wi-Fi instability, high network latency, or a pool connection problem. Some routers with “AI Protection” or traffic-shaping features block Stratum traffic, which can cause elevated rejections. The dashboard tracks rejection reasons in a breakdown so you can identify the specific cause.

Best Difficulty: The highest-difficulty share your miner has ever found during this session. In Bitcoin solo mining, this is a badge of honor. The higher your best difficulty, the “closer” your miner has come to finding a valid Bitcoin block. For context, Bitcoin’s network difficulty as of early 2026 exceeds 100 trillion. Your Bitaxe will regularly find shares at difficulty levels measured in billions (respresented as G), which is normal.

Block Height: The current Bitcoin block height reported by your connected pool. This updates each time a new block is found on the network.

Pool Difficulty: The difficulty target your pool has assigned to your miner. Solo mining pools typically set this very low (typically 1000 for a Bitaxe) so your miner submits shares frequently for monitoring purposes, even though only a share meeting the full network difficulty would actually solve a block.

Response Time: The round-trip latency for share submissions to the pool, measured in milliseconds. This graph was added in v2.13.0. Lower is better. High response times (consistently above 500ms) may indicate network issues.

Uptime: How long the Bitaxe has been running since its last reboot. Longer uptime generally means more stable operation. If your device reboots frequently, check for power supply issues, Wi-Fi interference, or overheating.

Hashrate Chart: A dual-axis line chart showing historical data over the past hour (up to 720 data points at 5-second intervals, confirmed in the source code). You can select which metrics appear on each axis using the dropdown selectors. Available data sources include hashrate, 1-minute hashrate average, ASIC temperature, power consumption, fan RPM, and response time.


Configuring Your Mining Pool and Wallet

The Settings tab in AxeOS is where you configure which mining pool your Bitaxe connects to and which Bitcoin wallet receives any rewards.

Stratum Host: The pool server address. For solo mining on Public Pool (the most popular choice for Bitaxe owners), enter: public-pool.io

Stratum Port: The port number for the pool connection. For Public Pool, use: 21496

Stratum User: Your Bitcoin wallet address. This is where block rewards are sent if your miner solves a block. Nearly all devices ship with a default placeholder address. Replace this with your own Bitcoin wallet address immediately after setup. Starting in v2.13.0, AxeOS displays a warning on the dashboard if the default address is still configured, preventing accidental mining to someone else’s wallet.

Stratum Password: Optional. Most pools leave this blank or accept any value (entering “x” is common). Worker naming is typically done by appending the worker name to the Stratum User field with a period separator (for example, bc1qYourAddress.livingroom), not through the password field.

Fallback Stratum: AxeOS supports a backup pool connection. If the primary pool becomes unreachable after three consecutive connection failures, the firmware automatically switches to the fallback pool. Configure a second pool URL, port, and user as your safety net.

After changing Stratum settings in v2.13.0 and later, the firmware reconnects to the pool immediately without requiring a reboot.

For guidance on choosing between bitcoin mining pools, see Understanding Mining pools.


Fan Control and Temperature Management

AxeOS offers two fan control modes accessible in the Settings tab.

Automatic Mode (recommended): The firmware dynamically adjusts fan speed based on the ASIC chip temperature. As temperature rises, fan speed increases. As it drops, fan speed decreases. This mode runs in a dedicated FreeRTOS task (FAN_CONTROLLER_task at priority 5, created at main.c line 89) that operates independently from the mining pipeline.

Manual Mode: You set a fixed fan speed percentage. This is useful for noise-sensitive environments where you want to cap fan speed at a specific level. Be aware that setting the fan too low while running at high frequencies can cause overheating. AxeOS displays a warning when fan speed is set below safe thresholds.

For most users, automatic mode provides the best balance between cooling performance and noise. If your Bitaxe is running in a warm environment (above 30C ambient), consider ensuring good airflow around the device or placing it on a specially designed stand for improved ventilation.


Overclock Mode: What It Does and When to Use It

By default, the ASIC Frequency and Core Voltage fields in AxeOS Settings are locked to a set of pre-defined safe values for your specific Bitaxe model. This prevents accidental changes that could damage the hardware or cause instability.

To unlock custom frequency and voltage inputs, append ?oc to your settings page URL. For example: http://192.168.1.42/#/settings?oc

This is confirmed in the source code at edit.component.ts, which checks for the “oc” URL parameter and toggles the overclock mode accordingly. Once enabled, the setting persists in NVS storage, so you only need to do this once.

When to use overclock mode: If you understand the relationship between frequency, voltage, temperature, and hashrate, and you want to push your Bitaxe beyond stock performance. Higher frequency increases hashrate but also increases power consumption and heat. Higher voltage can stabilize a higher frequency but generates more heat.

When not to use overclock mode: If you are new to mining, if your Bitaxe runs in a warm environment without active cooling upgrades, or if you are not comfortable monitoring temperature regularly.

The golden rule: increase frequency in small steps (25 to 50 MHz), monitor temperature for 15 minutes after each change, and back off if temperatures exceed 70C.

For detailed model-specific overclocking strategies, voltage and frequency recommendations, and thermal benchmarks, see our Bitaxe Overclocking Guide.


What Is Overheat Mode?

Overheat mode is an automatic safety mechanism built into AxeOS that protects your hardware from thermal damage. When the ASIC chip temperature exceeds 75C or the voltage regulator temperature exceeds 105C (thresholds verified at power_management_task.c lines 23-36), the firmware executes an emergency shutdown sequence:

1. Core voltage is immediately set to 0V, shutting down the ASIC.
2. The ASIC reset pin is held low.
3. Fan speed is forced to 100%.
4. The firmware waits for temperatures to drop below 45C (ASIC) and 95C (VR).
5. Operating frequency is reduced by 100 MHz and voltage by 100 mV from the previous settings.
6. The ASIC reinitializes with these reduced settings and mining resumes.

The AxeOS dashboard displays “Overheat Mode” when this protection has been triggered. A dedicated button appears in the Settings tab to manually clear the overheat state once you have addressed the cooling issue.

Common causes of overheat mode triggering: inadequate airflow, ambient temperature above 35C, fan failure or obstruction, running at overclocked frequencies without sufficient cooling, or a power supply providing unstable voltage.

For a walkthrough on clearing overheat mode, see How to Disable Overheat Mode.


How to Update AxeOS Firmware

AxeOS receives regular updates from the open-source community that can improve hashrate, add features, fix bugs, and support new hardware. Updating is safe and takes about 60 seconds.

OTA Update (recommended, no cables needed):

1. Open the AxeOS dashboard in your browser.
2. Navigate to the Settings tab.
3. Scroll to the “Latest Releases” section at the bottom and click “Check.”
4. If a newer version is available, click the esp-miner.bin link to download it.
5. Under “Update Firmware,” click “Browse,” select the downloaded esp-miner.bin file, and upload it.
6. Wait approximately 60 seconds. A green “Success! Firmware updated” message confirms the update.
7. The device reboots automatically with the new firmware.

All your mining settings (pool, wallet, frequency, voltage, Wi-Fi) are preserved during OTA updates because they are stored in a separate NVS flash partition.

Why OTA is safe: The ESP32-S3 uses a dual-partition scheme (confirmed in the ESP-IDF OTA mechanism used by http_server.c lines 633-701). New firmware is written to an inactive partition. Only after the write is verified does the bootloader switch to it on reboot. If the update fails mid-flash, the device boots back to the previous working firmware.

Updating the Web Interface Separately: The AxeOS dashboard (www.bin) can be updated independently from the core firmware. This allows UI improvements without touching the mining engine. Upload the www.bin file through the same Settings page under “Update AxeOS.”

For a detailed step-by-step guide including the USB webflasher method, see How to Update Bitaxe Firmware.


Swarm: Managing Multiple Devices

The Swarm tab in AxeOS allows you to monitor and manage multiple mining devices from a single browser window. This works with any device running ESP-Miner or a compatible fork, including Bitaxe and Nerdaxe devices.

AxeOS discovers other devices by scanning your local network subnet. Each discovered device reports its status via the /api/system/info endpoint. The Swarm table displays each device’s hostname, IP address, hashrate, temperature, uptime, firmware version, and status.

In v2.13.0, Swarm received several improvements: all table columns are now sortable, power faults can be cleared remotely from the Swarm interface, and scan reliability was improved.

The Swarm feature requires no central server, cloud service, or additional software. All communication stays on your local network between devices.


Using the Logs Tab for Troubleshooting

The Logs tab provides a real-time stream of ESP32 system messages delivered through a WebSocket connection at /api/ws. This is the most powerful troubleshooting tool built into AxeOS.

Log output includes: Stratum connection messages (connect, disconnect, authentication), share submissions (accepted, rejected, with reasons), ASIC initialization details, temperature readings, Wi-Fi events, and error conditions.

In v2.9.0, the Logs tab gained filtering and clear functionality, allowing you to search through previously received log lines. ANSI color codes are rendered for readability.

What to look for when troubleshooting:

“Stratum connection failed” messages indicate pool connectivity issues. Check your Stratum URL and port, and verify your router is not blocking mining traffic (ASUS and some TP-Link routers have “AI Protection” features that block Stratum connections).

“Share rejected” messages with specific reasons help diagnose network issues. Stale shares typically mean high Wi-Fi latency or a slow connection to the pool. Shares rejected for insufficient difficulty can occur after a reconnection or pool failover where difficulty has not been renegotiated.

“Overheat” messages confirm thermal protection was triggered and show the recovery sequence.

For a detailed walkthrough of every log message and what it means, see our Bitaxe Mining Log Guide.


The OLED/LCD Display: What Each Screen Shows

Bitaxe devices include a small physical display (OLED or LCD, depending on model) that cycles through information screens automatically. The display system is driven by a state machine in main/screen.c.

Screens include: the device’s IP address (essential for accessing the dashboard), current hashrate, ASIC temperature, best difficulty found, share acceptance stats, uptime, and a mining status indicator.

The display automatically cycles through information screens every 10 seconds during normal operation. Pressing the boot button on the left side of the Bitaxe advances the screen manually and wakes the display if it has timed out. AxeOS includes a configurable screen timeout setting to turn off the display after a period of inactivity, extending screen lifespan. The display also shows overheat warnings, self-test progress, Wi-Fi connection status, and a block found celebration animation.


Troubleshooting Common AxeOS Issues

No hashrate / 0 TH/s: The most common cause is incorrect pool or wallet credentials. Check the following:

  • Verify your Stratum URL and port number match your chosen pool exactly.
  • Confirm the wallet address is a valid on-chain Bitcoin address. Legacy addresses start with 1, SegWit addresses start with 3, and Native SegWit (bech32) addresses start with bc1. Lightning addresses, Liquid addresses, and other non-mainchain formats will not work.
  • Check for extra spaces before or after the wallet address, which will cause the pool to reject authentication.
  • Confirm your router is not blocking mining traffic. ASUS and some TP-Link routers have “AI Protection” settings that block Stratum connections. Disable this in your router settings.
  • Verify frequency and voltage are set to their last known working values.
  • If the issue persists, test with a known-reliable pool like public-pool.io (port 21496) to rule out pool-side problems.

Cannot access the AxeOS dashboard:

  • Type http:// explicitly before the IP address. AxeOS uses plain HTTP on port 80, and browsers may auto-redirect to HTTPS, which may fail.
  • Try a different browser or disable ad-blocking extensions that may interfere with local connections.
  • Verify the device’s IP address matches what is shown on the OLED display.
  • Confirm your computer or phone is on the same Wi-Fi network as the Bitaxe.
  • If you are using a VPN or a software firewall on your computer, it may block connections to local network devices. Temporarily disable it to test.

“Power Fault Detected” message:

  • This indicates the voltage regulator detected an issue with the power supply.
  • Verify your power supply matches the required voltage for your model (5V for single-chip, 12V for multi-chip).
  • Never use a 12V supply on a 5V Bitaxe. This will permanently damage the board.
  • If the correct supply is connected, try a different power cable and power cycle the device.
  • In some cases, uneven or insufficient pressure between the ASIC chip and the heatsink can cause this issue. Verify the heatsink is seated evenly and all mounting hardware is secure.

High rejected shares (above 2%):

  • Rejected shares are typically a network issue. Stale shares arrive at the pool after the work has already expired, usually due to Wi-Fi latency.
  • Shares can also be rejected if they do not meet the pool’s minimum difficulty target, which can occur after a reconnection or pool failover.
  • Check your Wi-Fi signal strength and stability.
  • Test with a pool that is geographically closer to you.
  • Check if your router has “AI Protection” or traffic-shaping features that may interfere with Stratum connections.

Wi-Fi keeps disconnecting:

  • Some routers with power-saving features put inactive clients to sleep. Disable “green mode” or Wi-Fi power saving on your router.
  • Update your router firmware.
  • Ensure your Bitaxe is within reasonable range of the router.
  • Some ESP32 devices have difficulty with certain mesh Wi-Fi systems.

Firmware update shows “Failed”:


Which Settings Are Preserved During Updates?

Understanding which update methods preserve your settings prevents the frustration of reconfiguring everything after a firmware update.

OTA Update (esp-miner.bin via AxeOS Settings): All settings are preserved. Pool URL, wallet address, frequency, voltage, fan mode, Wi-Fi credentials, hostname, and all other NVS-stored parameters survive the update. This is because OTA only overwrites the firmware partition, not the NVS configuration partition.

OTA Web Interface Update (www.bin): All settings are preserved. This only updates the SPIFFS partition containing the dashboard files.

Factory Flash (via Bitaxetool or Webflasher): By default, factory images erase all settings and replace the NVS partition. You will need to go through the initial setup process again (Wi-Fi, pool, wallet). However, the Bitaxe webflasher includes a “Keep configuration” checkbox that preserves your existing settings during a factory flash. If you want a clean reset, uncheck this option.

Back up your pool and wallet settings before doing a factory flash. The easiest way is to take a screenshot of your AxeOS Settings page.


Part 2: Inside AxeOS (Technical Deep Dive)


Open-Source Licensing and Contributors

ESP-Miner is released under the GNU General Public License v3.0 (GPL-3.0), guaranteeing the source code remains freely available and that derivative works must also be open source. The project was originally created by Skot (skot9000), the inventor of Bitaxe hardware, and has since grown into a community effort maintained through the Open Source Miners United (OSMU) Discord and the bitaxeorg GitHub organization.

Key contributors to the ESP-Miner codebase as of v2.13.0:

Skot (skot9000): Original creator of ESP-Miner and Bitaxe hardware. Wrote nearly all of the IC and ASIC drivers in the firmware.

WantClue: Lead developer and primary release manager for ESP-Miner. Major contributor to BAP (share request #1482, block found parameter #1547), hashrate error metric v2.11.0 (PR #1263), IPv6 zone identifier fixes (#1277), TPS phase register support (#1490), R2 deployment, and the default wallet address warning (#1449).

benjamin-wilson: Core firmware engineer. Responsible for ASIC driver work (BM1370, BM1368 support), device model abstraction (801 strapless, 650 Duo configurations), self-test infrastructure, and BAP protocol improvements (#1525).

mutatrum: Prolific contributor responsible for the queueless mining architecture (#1424), coinbase transaction parser (#1391), TLS co-authorship (#1413), mining.ping (#1439), fan controller task refactoring (#1357), OLED display system using the LVGL library, IPv6 public address resolution (#1468), swarm scanning fixes (#1528), Portfolio font extension (#1502), response time graph (#1423), uptime restoration (#1428), and dozens of bug fixes. Authored the v2.13.1 self-test fix (#1580).

duckaxe: Frontend developer. Dashboard unreachable notification (#1385), swarm table sorting (#948), navigation redesign (#1026), custom component icons (#1435), browser tab title (#996), log font fixes (#1448), and TLS UI integration.

terratec: Real-time log filtering and clear functionality (#884), statistics slider consolidation (#1016), screen wake on identify mode (#1443).

AxisRay: Co-authored TLS encrypted pool connection support (#1413).

0xf0xx0: OpenAPI specification maintenance (#806, #1433, #1467), fan RPM tooltip merge (#1527).

leandroalbero: Block found condition fix (#1419).

mweinberg: AtlasPool dashboard link integration (#1416).

Additional contributors include Skot (original creator), pRizz (development documentation), STSMiner1 (esptool version notes, router compatibility documentation), shaunography (CSRF vulnerability discovery), and mcpiepie (AtlasPool operator).


System Architecture Overview

AxeOS uses a hub-and-spoke architecture with a central GlobalState structure serving as the shared data repository for all subsystems. This design is confirmed in main/global_state.h (lines 116-156), where GlobalState is defined as a single, statically allocated structure at main/main.c line 25.

The firmware is organized into four layers:

User Interface Layer: Web UI (AxeOS Angular dashboard), physical OLED/LCD display, REST API, WebSocket log streaming, and BAP protocol for accessories.

Application Layer: System initialization, power management, thermal protection, fan control, and self-test diagnostics.

Mining Layer: Stratum V1 protocol handling, job creation with SHA-256 midstate calculation, ASIC work submission, nonce validation, and share submission.

Hardware Layer: ASIC chip drivers (BM1366/1368/1370/1397), voltage regulation (TPS546, DS4432U), thermal sensors (EMC2101/2103/2302, TMP1075), power monitoring (INA260), and fan control.

All subsystems communicate through GlobalState rather than direct inter-module messaging. Critical sections use pthread_mutex_t locks (for example, valid_jobs_lock at global_state.h line 131) to prevent race conditions on shared data.

The GlobalState structure contains module sub-structures including SystemModule (share statistics, pool configuration, network status at global_state.h lines 30-92), PowerManagementModule (voltage, power, temperature, frequency at power_management_task.h lines 4-18), AsicTaskModule (active jobs array, current job pointer, semaphore at global_state.h lines 104-113), and DeviceConfig (hardware variant identification).


Supported Hardware Platforms and Device Models

AxeOS supports multiple hardware variants through device model abstraction. A single compiled firmware binary runs on different hardware by loading the appropriate NVS configuration at flash time. The build system produces 19 factory image configurations.

Device Family Config IDs ASIC Chip Chip Count Typical Hashrate
Bitaxe Max (legacy, discontinued) 102 BM1397 1 ~400 GH/s
Bitaxe Ultra (legacy, discontinued) 201-205, 207 BM1366 1 ~500 GH/s
Bitaxe Hex (legacy, discontinued) 301-303 BM1366 6 ~3 TH/s
Bitaxe Supra 400-403 BM1368 1 ~600 GH/s
Bitaxe Gamma 601-602 BM1370 1 ~1.2 TH/s
Bitaxe Duo 650 BM1370 2 ~2.4 TH/s
Bitaxe SupraHex 701-702 BM1366 6 ~4.2 TH/s
Bitaxe Gamma Turbo (GT) 801 BM1370 2 ~2.15 TH/s
Bitaxe Turbo Touch 801 BM1370 2 ~2.15 TH/s

The Bitaxe Turbo Touch uses the same 801 hardware and AxeOS core as the Bitaxe GT. Its touchscreen display is driven by the BAP-GT-TOUCH firmware layer built on the BAP protocol.

All supported devices use the ESP32-S3-WROOM-1 module (N16R8 variant: 16MB Flash, 8MB Octal SPI PSRAM). This is the only supported module type. Other ESP32 modules without PSRAM or with Quad SPI PSRAM will not work.


Software Stack and Dependencies

ESP-IDF v5.3.1: Espressif’s official development framework providing hardware abstraction, networking (lwIP), TLS (mbedTLS), NVS flash storage, SPIFFS, and the FreeRTOS kernel.

FreeRTOS v10.5.1: Real-time operating system kernel handling task scheduling across the ESP32-S3’s dual-core Xtensa LX7 processor. Provides task creation, queues, semaphores, and software timers.

Angular: The AxeOS web dashboard is built as an Angular SPA, compiled to static files, gzip-compressed, and stored in the SPIFFS partition. The frontend auto-generates its API client from the OpenAPI specification in main/http_server/openapi.yaml.

cJSON: Lightweight JSON parser/generator for Stratum V1 protocol messages and REST API processing.

mbedTLS: TLS library for encrypted Stratum pool connections, added in v2.13.0.

PrimeNG / Chart.js: The dashboard’s charting library, rendering the dual-axis hashrate/temperature/power graphs with a 720-data-point buffer (1 hour at 5-second intervals).


Initialization and Startup Sequence

The app_main() function in main/main.c orchestrates a strict dependency-ordered initialization. The following sequence is verified against the source code at commit 18a5619d (v2.13.0):

Step 1 (line 41): i2c_bitaxe_init(). Initializes the I2C bus required for all peripheral communication.

Step 2 (line 45): asic_hold_reset_low(). Holds the ASIC in reset to minimize power draw during initialization.

Step 3 (line 52): ADC_init(). Initializes the analog-to-digital converter for voltage/current sensing.

Step 4 (line 55): nvs_config_init(). Loads all configuration parameters from Non-Volatile Storage.

Step 5 (line 71): device_config_init(&GLOBAL_STATE). Detects the hardware variant and populates the DeviceConfig structure.

Step 6 (line 76): self_test(&GLOBAL_STATE). Runs the factory self-test if the flag is set or boot button is pressed.

Step 7 (line 79): SYSTEM_init_system(&GLOBAL_STATE). Calls nvs_config_get_*() functions to populate the SystemModule.

Step 8 (line 82): wifi_init(&GLOBAL_STATE). Starts Wi-Fi connection (non-blocking).

Step 9 (line 84): SYSTEM_init_peripherals(&GLOBAL_STATE). Initializes VCORE, thermal sensors, and display.

Steps 10-11 (lines 86-89): Creates POWER_MANAGEMENT_task (priority 10) and FAN_CONTROLLER_task (priority 5). These must start before the ASIC powers on.

Step 12 (line 94): start_rest_server(&GLOBAL_STATE). HTTP server starts early so the recovery page is accessible even if mining fails to initialize.

Step 13 (line 97): SYSTEM_init_versions(&GLOBAL_STATE). Reads /version.txt from SPIFFS.

Step 14 (line 100): BAP_init(&GLOBAL_STATE). Initializes the Bitaxe Accessory Protocol interface.

Steps 15 (lines 106-108): Blocks until Wi-Fi is connected (while (!is_connected) vTaskDelay()).

Step 16 (line 110): queue_init(&stratum_queue). Initializes the work queue.

Step 17 (line 112): asic_initialize(&GLOBAL_STATE, COLD_BOOT). Detects ASIC chips, sets frequency/voltage.

Steps 18-22 (lines 116-129): Creates mining tasks in dependency order: stratum_task (priority 5), create_jobs_task (priority 20), ASIC_result_task (priority 15), hashrate_monitor_task (priority 5, SPIRAM), statistics_task (priority 3, SPIRAM).

The entire sequence from power-on to first hash typically completes in under 10 seconds.


The Mining Pipeline: How AxeOS Mines Bitcoin

The mining pipeline consists of four concurrent FreeRTOS tasks forming a continuous loop. This is the core engine that has produced real-world results: open-source mining community block wins totaling over $1M in BTC rewards, including Block #920,440 (October 23, 2025) mined using a NerdQaxe++ cluster sold by Solo Satoshi, which yielded 3.141 BTC (~$347K).

stratum_task (priority 5, main/tasks/stratum_task.c): Maintains a persistent TCP or TLS connection to the mining pool. Handles JSON-RPC communication: mining.subscribe, mining.authorize, mining.notify (receiving work), and mining.submit (submitting shares). Manages automatic failover to the backup pool after three consecutive connection failures. Uses a monotonically increasing message ID system starting from 1 (line 247-251) and a 1,024-entry circular buffer for request timing (MAX_REQUEST_IDS).

create_jobs_task (priority 20, main/tasks/create_jobs_task.c): Highest priority mining task, ensuring minimal work latency to keep the ASIC busy. When stratum_task receives a mining.notify message, this task pulls the work data, calculates the coinbase transaction hash, computes the merkle root, and constructs a block header. Since the Bitaxe Ultra, midstates are calculated on the ASIC itself rather than in software. In v2.13.0, the architecture was overhauled to a “queueless” design (#1424 by mutatrum) for improved performance.

ASIC_result_task (priority 15, main/tasks/asic_result_task.c): Continuously reads nonce results from the ASIC via UART. When the ASIC finds a nonce meeting its internal difficulty filter, the result is sent back. This task validates the nonce against the pool’s assigned difficulty. Qualifying shares are submitted to the pool through stratum_task. The system maintains a circular buffer of 128 active jobs and tracks valid job IDs using a mutex-protected data structure (valid_jobs_lock) to prevent stale share submission.

hashrate_monitor_task (priority 5, main/tasks/hashrate_monitor_task.c, SPIRAM): Tracks rolling hashrate statistics across multiple time windows (1-minute, 10-minute, 1-hour averages). Uses SPIRAM (external PSRAM) for its stack allocation to conserve internal RAM for critical tasks.


Stratum V1 Protocol Implementation

The Stratum V1 protocol is implemented in components/stratum/stratum_api.c (533 lines) and main/tasks/stratum_task.c (631 lines).

Transport: Connections are established over TCP or TLS using ESP-IDF’s esp_transport component. The STRATUM_V1_transport_init() function (stratum_api.c lines 53-91) creates a transport handle based on the configured TLS mode. Socket options include a 3-minute receive timeout (accommodating pools with infrequent notifications) and TCP keepalive probes for stale connection detection.

DNS Resolution: Supports both IPv4 and IPv6 with automatic address family selection (stratum_task.c lines 68-189). IPv4 is prioritized when available. For IPv6 link-local addresses, the function automatically retrieves the Wi-Fi interface’s scope ID and appends it as a zone identifier (e.g., fe80::1%wlan0).

Message Parsing: The STRATUM_V1_parse() function (stratum_api.c lines 198-407) handles all incoming JSON-RPC messages. For mining.notify, it extracts 8-9 parameters including previous block hash, coinbase parts, merkle branches, version, nbits, ntime, and the clean_jobs flag. The parser handles variable-position fields to support both 8 and 9 parameter formats.

Share Submission: When a valid nonce is found, STRATUM_V1_submit_share() (stratum_api.c lines 506-521) formats the JSON-RPC message. Response processing (stratum_task.c lines 593-615) categorizes rejected shares by error message and counts them in the rejected_reason_stats[] array for dashboard display.

Failover: A separate heartbeat task (stratum_task.c lines 262-334) monitors primary pool availability using lightweight probe connections. When the primary pool recovers, the main task reconnects. Share statistics are cleared during failover.

Coinbase Transaction Parser: Added in v2.13.0 (#1391 by mutatrum), this decoder parses the coinbase transaction structure from mining.notify data, enabling the dashboard to display pool payout information and block reward details. An option to disable the decoder was added in #1544 for compatibility with non-Bitcoin chains.


TLS Encrypted Pool Connections

TLS support for Stratum connections was added in v2.13.0, co-authored by AxisRay, mutatrum, and duckaxe (#1413). This is one of the most significant security features in the firmware’s history.

Before TLS, all Stratum communication traveled as unencrypted plaintext over TCP. Anyone on the same network could inspect the traffic, see the configured wallet address, and theoretically redirect hashrate through a man-in-the-middle attack.

AxeOS supports three TLS modes (configurable in Settings):

Mode 0 (No TLS): Standard unencrypted TCP. Compatible with all pools.

Mode 1 (TLS, No Certificate Verification): Encrypted connection without validating the pool’s certificate. Protects against passive eavesdropping but not active MITM attacks.

Mode 2 (TLS with Certificate Verification): Full encrypted connection with server certificate validation. Highest security, but requires the pool to have a valid TLS certificate.

After TLS transport creation, socket options are restored for mining performance (socket options fix #1447 by mutatrum).


ASIC Hardware Control and Chip Drivers

AxeOS supports four Bitmain SHA-256 ASIC models through dedicated drivers in the components/asic/ directory.

ASIC Driver File Bitaxe Models Process
BM1397 bm1397.c (454 lines) Max (legacy) 7nm
BM1366 bm1366.c (448 lines) Ultra, Hex (legacy) 5nm
BM1368 bm1368.c (358 lines) Supra 5nm
BM1370 bm1370.c (485 lines) Gamma, GT, Duo 5nm

Communication Protocol: All ASICs communicate over UART using a packet-based protocol. Each packet begins with a header byte encoding command type, followed by payload data and CRC checksum. The header format is defined at lines 28-44 of each driver file.

Initialization: Each driver implements an init function (e.g., bm1370.c lines 352-363 for BM1370) that: (1) asserts and releases the reset pin, (2) enumerates active chips via serial, (3) configures PLL registers for the target frequency, (4) programs core registers for job processing.

PLL Frequency Control: Operating frequency is controlled by programming PLL registers. The BM1370 formula (verified at bm1370.c lines 148-202): Frequency = 25MHz * fb_divider / (ref_divider * post_divider1 * post_divider2). Frequency transitions use the do_frequency_transition function to ramp gradually through intermediate steps, preventing ASIC lockups from abrupt jumps.

Expected Hashrate Calculation: Verified at power_management_task.c lines 40-43: expected_hashrate (GH/s) = frequency (MHz) * small_core_count * asic_count / 1000.

Unified Interface: GlobalState contains function pointers for ASIC operations (init, send_work, receive_result, set_frequency). The correct pointers are assigned during device_config_init() at boot, allowing the mining pipeline to operate identically regardless of ASIC model.


Power and Thermal Management Internals

POWER_MANAGEMENT_task runs at priority 10 with a 1,800ms polling cycle (1.8 seconds), verified at power_management_task.c.

Sensor Reading: Each cycle reads from I2C peripherals: INA260 (input voltage, power, current), TPS546 (core voltage readback, VR temperature), and EMC2101/2302 or TMP1075 (ASIC die temperature). The Thermal_get_chip_temp() function returns -1 when the ASIC is powered down, which is important during overheat recovery to avoid false readings.

Thermal Thresholds (power_management_task.c lines 23-36):

Zone ASIC Temp VR Temp Action
Normal Below 75C Below 105C Normal operation
Overheat trigger 75C or above 105C or above Emergency shutdown sequence
Safe to restart Below 45C Below 95C Reinitialize at reduced settings

The overheat condition (lines 88-92) requires both a temperature threshold breach AND meaningful power draw (frequency above 50 MHz or voltage above 1000 mV), preventing false triggers when the ASIC is already shut down.

Voltage and Frequency Change Detection: The task compares current NVS values against last-applied values each cycle (lines 176-196). If a user changes frequency or voltage through the web interface, the change is detected and applied without requiring a reboot. Voltage values are stored in millivolts in NVS but converted to volts for hardware commands.


Configuration System: NVS, CSV, and Runtime

AxeOS uses a three-tier configuration system allowing a single firmware binary to support 19 hardware variants.

Tier 1 (Compile-Time): main/Kconfig.projbuild defines defaults for GPIO pins, Stratum URL, initial frequency, and other build parameters baked into the firmware binary.

Tier 2 (Flash-Time): Device-specific CSV files (e.g., config-602.cvs, config-801.cvs) follow the ESP-IDF NVS CSV format. The nvs_partition_gen.py tool converts these to binary NVS partition images flashed alongside the firmware. Each CSV contains hardware-appropriate defaults for ASIC model, device model, board version, frequency, voltage, and GPIO assignments.

Tier 3 (Runtime): main/nvs_config.c provides type-safe get/set functions with an enum-based key system. The settings[] array (lines 46-112) defines each parameter with its NVS key, data type, default value, REST API field name, and min/max constraints. An asynchronous write queue (nvs_save_queue at line 43) prevents blocking the HTTP request handler during flash writes. The background nvs_task (lines 160-214) processes writes sequentially and calls nvs_commit() after each operation (line 202).


Factory Self-Test System

The self-test at main/self_test/self_test.c (lines 267-540) validates hardware integrity during manufacturing or manual testing. It runs when the NVS_CONFIG_SELF_TEST flag is set or the boot button is held during power-on.

Test Pass Criteria On Failure
PSRAM esp_psram_is_initialized() returns true “PSRAM:FAIL”, halt
Voltage Regulator TPS546 or DS4432U responds on I2C “VCORE:FAIL”, halt
Core Voltage Measured between 1000 mV and 1300 mV “VCORE:FAIL”, halt
ASIC Count Detected chips match expected config “ASIC:FAIL X CHIPS”, halt
Temperature Between -1C and 55C during test “TEMP:FAIL”, halt
Hashrate 95% or above of expected for 30 seconds “HASHRATE:FAIL”, halt
Power Draw Within 3W of target “POWER:FAIL”, halt
Fan Speed Above 1000 RPM (Gamma/Hex: 500 RPM) “FAN:WARN”, continue

“Our manufacturing partner runs the self-test on every unit before it ships,” says Matt Howard. “The 95% hashrate threshold for 30 seconds catches ASIC defects or thermal paste issues that would affect mining. This is why Solo Satoshi backs every open-source miner with a 90-day warranty.”


REST API Reference

AxeOS exposes a RESTful API documented in main/http_server/openapi.yaml. The /api/system/info response contains over 100 fields organized by category.

GET /api/system/info: Returns comprehensive device state. Key fields by category:

Hashrate: hashRate, hashRate_1m, hashRate_10m, hashRate_1h, expectedHashrate, errorPercentage.
Power: power, voltage, current, coreVoltage, coreVoltageActual.
Thermal: temp, temp2, vrTemp.
Shares: sharesAccepted, sharesRejected, sharesRejectedReasons[].
Pool: stratumURL, stratumPort, stratumUser, poolDifficulty, responseTime, isUsingFallbackStratum.
Mining: bestDiff, bestSessionDiff, blockHeight, networkDifficulty.

GET /api/system/asic: ASIC-specific settings and identification data.

GET /api/system/statistics: Historical time-series data. Accepts query parameters specifying which data sources to include. Available sources (verified at http_server.c lines 100-122): hashrate, hashrate_1m, asicTemp, power, fanRpm, responseTime. Stores up to 720 data points (1 hour at 5-second intervals).

GET /api/system/statistics/dashboard: Optimized statistics subset for dashboard polling.

GET /api/system/wifi/scan: Triggers Wi-Fi scan, returns available SSIDs with signal strength.

POST /api/system/restart: Triggers device reboot.

POST /api/system/identify: Activates device identification (flashes display/LED).

POST /api/system/OTA: Accepts esp-miner.bin for firmware update.

POST /api/system/OTAWWW: Accepts www.bin for web interface update.

PATCH /api/system: Accepts JSON body with configuration parameters to update. Changes are enqueued to the async NVS write queue.

CORS: API access restricted to private IP ranges (10.x, 172.16-31.x, 192.168.x) and AP mode connections.

Example: curl http://YOUR-BITAXE-IP/api/system/info

Example: curl -X PATCH http://YOUR-BITAXE-IP/api/system -H “Content-Type: application/json” -d ‘{“fanspeed”: 85}’


BAP Protocol: Bitaxe Accessory Protocol

BAP is a communication standard for accessories and companion devices to interact with Bitaxe hardware. Created by WantClue, BAP enables external devices (like the Bitaxe Touch display) to receive mining data and control signals.

In v2.13.0, BAP received significant improvements: protocol improvements (#1525 by benjamin-wilson), share request capability (#1482 by WantClue), and block found parameter reporting (#1547 by WantClue). BAP is initialized at main.c line 100 during the boot sequence.

The BAP-GT-TOUCH firmware variant by WantClue specifically targets Bitaxe Touch hardware with enhanced display features through the BAP protocol layer.


Security Features

CSRF Protection (v2.5.0+): HTTP server validates request origins against local network ranges. Addresses the vulnerability discovered by @shaunography where malicious websites could modify Bitaxe settings via cross-site request forgery (#637 by benjamin-wilson).

IP-Based Access Control: REST API restricted to private IP ranges (10.x.x.x, 172.16.0.0-172.31.255.255, 192.168.x.x) and AP mode.

TLS Stratum (v2.13.0+): Three configurable encryption modes for pool connections.

Default Address Warning (v2.13.0+): Dashboard warns if the default placeholder wallet address is still configured (#1449 by WantClue).

Dual-Partition OTA: Fail-safe firmware updates via inactive partition write-and-verify.

NVS Type Safety: All configuration parameters enforce type checking and min/max constraints through the settings[] definition array.


Building AxeOS from Source

Two-Stage Build Process:

Stage 1 (Web UI): The Angular frontend at main/http_server/axe-os/ compiles with npm run build. This generates the API client from the OpenAPI spec, compiles TypeScript to JavaScript, and gzip-compresses all assets (level 9). Build configuration is at main/CMakeLists.txt lines 84-152.

Stage 2 (Firmware): idf.py build compiles all C source, links ESP-IDF libraries, and creates partition images. The merge_bin.sh script combines bootloader, partition table, and application into a single flashable image.

Docker Development:
1. git clone https://github.com/bitaxeorg/ESP-Miner.git
2. docker build -t espminer-build .devcontainer
3. docker run –rm -it -v $PWD:/workspace espminer-build /bin/bash
4. git config –global –add safe.directory /workspace
5. idf.py build

CI/CD: GitHub Actions produce continuous builds on every push, stable releases to GitHub Releases and Cloudflare R2, and pre-releases to GitHub only.


Bitaxetool: Command-Line Flashing Utility

Install: pip install –upgrade bitaxetool (Python 3.4+). Requires esptool v4.9.0 or earlier (v5.x.x incompatible). Use pip install bitaxetool==0.6.1 for the compatible locked version.

Flash factory image: bitaxetool –firmware ./esp-miner-factory-602-v2.13.0.bin

Flash NVS config only: bitaxetool –config ./config-602.cvs

Flash both: bitaxetool –config ./config-602.cvs –firmware ./esp-miner-factory-602-v2.13.0.bin

Config values override those baked into the factory image. Custom hardware supported via config-custom.cvs (must be based on existing device/ASIC model). Run bitaxetool from outside the Docker devcontainer. Some hardware versions require a USB-A adapter for the USB-C port.


Version History Highlights

Version Date Key Changes
v2.5.0 Jan 2025 CSRF vulnerability patch, IP-based access control
v2.6.x Apr 2025 OpenAPI spec updates, self-test power fixes
v2.9.0 Jul 2025 Log filtering, swarm sorting, navigation redesign, AxeOS version display, statistics slider
v2.11.0 Late 2025 Hashrate error metric (WantClue #1263), IPv6 fixes, stratum fixes (mutatrum), form fixes (duckaxe)
v2.12.2 Early 2026 Bitaxe GT 801 finalized, self-test improvements, TPS phase registers
v2.13.0 Feb 20, 2026 TLS Stratum, Duo 650, queueless mining, coinbase parser, BAP improvements, IPv6 resolution, mining.ping, response time graph, fan controller task, block found notification, default address warning
v2.13.1 Feb 26, 2026 Self-test fix for manufacturers (mutatrum #1580)
v2.13.2 Mar 5, 2026 Self-test domain monitoring, R2 deployment fix, terminology update

Where to Buy Bitaxe Hardware Running AxeOS

Every Bitaxe miner sold by Solo Satoshi ships with open-source AxeOS firmware pre-installed and tested. Solo Satoshi is a verified and legit seller on bitaxe.org and has shipped over 40,000 mining devices to 70+ countries since May 2024. All devices are assembled in the USA with same-day shipping from Houston, Texas.

To top