AxeOS is the open-source operating system on every Bitaxe Bitcoin miner. It runs on the miner’s ESP32-S3 microcontroller, drives the Bitmain ASIC chip, holds the pool connection (Stratum V1 or V2), watches temperature and power, and serves a browser dashboard on your local network. It is built from the ESP-Miner firmware at github.com/bitaxeorg/ESP-Miner, licensed GPL-3.0. The current stable release is v2.15.1 (August 29, 2026); the v2.15.2rc0 pre-release adds BM1372/BM1373 support for the Bitaxe Naja Duo and Gamma Hex.
Key takeaways
- Since v2.15.0 one file, esp-miner.bin, updates both firmware and dashboard. There is no separate www.bin.
- You can open the dashboard by hostname (mDNS, v2.15.0) or by the IP address shown on the miner’s screen.
- AxeOS shuts the ASIC down at 75C (chip) or 105C (voltage regulator), then restarts 100 MHz and 100 mV lower.
- Stratum V2 has been supported since v2.14.0; Stratum V1 remains the default and works with every pool.
- The Public Pool preset moved from port 21496 to 3333 in v2.14.0, and the fallback pool is off by default since v2.15.0.
- OTA updates keep every setting; a factory flash wipes them unless “Keep configuration” is ticked.
What Changed in AxeOS v2.14 and v2.15?
The two 2026 major releases added Stratum V2, a unified firmware binary, mDNS hostname access, Bluetooth LE, and a customizable dashboard. If your guide or memory of AxeOS predates June 2026, these are the changes most likely to trip you up. The timeline below shows where each release lands.

v2.14.0 (June 4, 2026):
- Stratum V2 (SV2) protocol support (#1553). AxeOS can now speak SV2 to pools that offer it, alongside Stratum V1.
- Customizable dashboard (#1622). Cards can be rearranged to your preference.
- Scoreboard (#1236) showing your best shares.
- Pause/resume mining (#1608) without powering down.
- Log download button with log preservation across soft reboots (#1646).
- WebSocket API (#1623) for live data without polling.
- Actual resolved frequency shown on the dashboard (#1629, #1674), so you see what the PLL really locked to, not just the requested value.
- CPU usage and ASIC share-processing time metrics (#1621).
- Public Pool quick link changed to port 3333 (#1611).
- Fan controller tuning (#1640) and hostname changes without reboot (#1726).
- BIP-54 and BIP-110 signals shown in the block header (#1588, #1609); fractional pool difficulty (#1594); ESP-IDF 5.5.3.
v2.15.0 (August 21, 2026):
- Unified firmware. The AxeOS web interface is now embedded inside esp-miner.bin. There is no longer a separate www.bin to upload (#1763).
- mDNS support. You can open the dashboard by hostname instead of IP address (#1240).
- Bluetooth LE (#1827).
- Multi-line charts (#1736), total uptime and total hashes (#1555), and the target temperature shown on the temperature bars (#1691).
- Higher input voltage tolerance for solar setups (#1819).
- Fallback pool is now off by default (useFallbackStratum defaults to false, #1823).
- The “luck” figure was removed from the hashrate card (#1832); uptime moved to the misc card (#1687).
- SV2 per-pool “require authentication” option (#1796); pending SV2 shares shown on the dashboard (#1735).
- Board version 603 support (#1760, first shipped in v2.14.1).
- Under the hood: PrimeNG removed in favor of Tailwind CSS (#1815), Angular 19 (#1651), ESP-IDF 6.0.2 (#1829).
v2.15.1 (August 29, 2026): fixes swarm IP handling (#1905), disables RSNO client support to restore WPA2/WPA3 compatibility-mode Wi-Fi (#1912), and prevents reconnect storms from slow clients (#1913).
v2.15.2rc0 (August 29, 2026, release candidate): adds the BM1372/BM1373 ASIC driver (#1890) and “Bitaxe Color” support for the Naja Duo and Gamma Hex with their ST7789 color display (#1916), plus a settings-page typo fix (#1920). It is a test build; the maintainers say it is not meant for stability. Naja Duo and Gamma Hex owners should watch for the stable v2.15.2.
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 firmware, and troubleshooting. Part 2 goes under the hood for developers and enthusiasts: system architecture, mining pipeline internals, Stratum V1 and V2, ASIC driver layer, REST and WebSocket APIs, and building from source.
Table of Contents
Part 1: Operating Your Bitaxe with AxeOS
- What Is AxeOS?
- What Changed in AxeOS v2.14 and v2.15?
- How to Access the AxeOS Dashboard
- Understanding the Dashboard: What Every Metric Means
- Configuring Your Mining Pool and Wallet
- Fan Control and Temperature Management
- Overclock Mode: What It Does and When to Use It
- What Is Overheat Mode?
- How to Update AxeOS Firmware
- Swarm: Managing Multiple Bitaxe Devices
- Using the Logs Tab for Troubleshooting
- The OLED/LCD Display: What Each Screen Shows
- Troubleshooting Common AxeOS Issues
- Which Settings Are Preserved During Updates?
Part 2: Inside AxeOS (Technical Deep Dive)
- Open-Source Licensing and Contributors
- System Architecture Overview
- Supported Hardware Platforms and Device Models
- Software Stack and Dependencies
- Initialization and Startup Sequence
- The Mining Pipeline: How AxeOS Mines Bitcoin
- Stratum V1 Protocol Implementation
- Stratum V2 (SV2) Support
- TLS Encrypted Pool Connections
- ASIC Hardware Control and Chip Drivers
- Power and Thermal Management Internals
- Configuration System: NVS, CSV, and Runtime
- Factory Self-Test System
- REST and WebSocket API Reference
- BAP Protocol: Bitaxe Accessory Protocol
- Security Features
- Building AxeOS from Source
- Bitaxetool: Command-Line Flashing Utility
- Version History Highlights
- Where to Buy Bitaxe Hardware Running AxeOS
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. 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. Since v2.15.0 the two ship as a single binary, so the distinction matters less than it used to.
The software is 100% open source under the GPL-3.0 license. Anyone can inspect, modify, or contribute to the code. The project is maintained by the bitaxeorg GitHub organization with dozens of contributors worldwide.
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 three ways to reach AxeOS: the setup hotspot on first boot, the IP address on your network, or (since v2.15.0) the miner’s hostname.
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 by IP (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.
Normal Access by Hostname (v2.15.0 and later): mDNS support was added in v2.15.0 (#1240), so you can open the dashboard using the miner’s hostname followed by .local (for example, http://bitaxe.local). The hostname is shown in the dashboard header and can be changed in Settings without a reboot (v2.14.0, #1726). Hostname access had been removed in v2.5.0 as part of a security patch; v2.15.0 restored it through mDNS. If you run several miners, give each a unique hostname.
If you cannot find the IP address, check your router’s admin page for connected devices, or use a network scanner. Look for a device with port 80 open, which indicates the AxeOS web server is running.
If the main dashboard fails to load, a minimal recovery page is available at http://[IP]/recovery. This emergency page allows firmware re-flashing without the full web 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 polls the /api/system/info endpoint every 5 seconds (verified in home.component.ts at v2.13.0, commit 18a5619). Since v2.14.0 the layout is customizable (#1622), so card positions may differ from screenshots you see elsewhere. 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 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.
Frequency (requested vs. actual): Since v2.14.0 the dashboard shows the actual resolved PLL frequency (#1629, #1674), not just the value you typed. The two can differ by a few MHz because the PLL can only lock to discrete steps.
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. This metric is derived from the ASIC’s hashrate registers, added in v2.11.0 by mutatrum (#1249, #1271, #1301, #1340). A healthy error percentage stays under 5%. Consistently high values may indicate thermal throttling or a firmware issue. For a detailed breakdown, 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 (power_management_task.c, verified at v2.13.0, commit 18a5619). Since v2.15.0 the target temperature is drawn directly on the temperature bar (#1691). 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 (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. v2.15.0 improved undervoltage detection in the UI (#1888) and raised the accepted input voltage ceiling for solar setups (#1819).
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 moved into its own dedicated FreeRTOS task (#1357), and v2.14.0 tuned its response curve (#1640). 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. Since v2.14.0, only shares confirmed in a mining.submit response are counted (#1591). 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. The dashboard tracks rejection reasons in a breakdown; v2.14.0 added parsing for the reject messages used by ckpool, blitzpool, and miningcore-based pools (#1586, #1695, #1701).
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. Your Bitaxe will regularly find shares at difficulty levels measured in billions (represented as G), which is normal. The v2.14.0 scoreboard (#1236) keeps a list of your best shares.
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 (often around 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. Fractional difficulty values are supported since v2.14.0 (#1594).
Response Time: The round-trip latency for share submissions to the pool, measured in milliseconds. The metric was added in v2.9.0 (#1063) and the graph in v2.13.0 (#1423). For SV2 connections it is measured per share since v2.14.0 (#1720). Lower is better. High response times (consistently above 500ms) may indicate network issues.
Uptime, Total Uptime, and Total Hashes: Uptime is how long the Bitaxe has been running since its last reboot. v2.15.0 added lifetime totals for uptime and hashes (#1555). If your device reboots frequently, check for power supply issues, Wi-Fi interference, or overheating.
Charts: The dashboard chart shows historical data over the past hour (up to 720 data points at 5-second intervals). v2.15.0 added multi-line charts (#1736), so several metrics can be overlaid. 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, which protocol it uses, 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. The Public Pool quick link built into AxeOS uses port 3333 since v2.14.0 (#1611); earlier firmware and older guides used 21496. Confirm the current port on the pool’s own site before saving.
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. Since v2.13.0, AxeOS displays a warning on the dashboard if the default address is still configured (#1449), 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. Browser autocomplete is disabled on pool password fields since v2.15.0 (#1733).
Protocol (Stratum V1 or V2): Since v2.14.0 you can select Stratum V2 for pools that support it (#1553). Most solo pools still use V1. See the SV2 section for details.
Fallback Stratum: AxeOS supports a backup pool connection. If the primary pool becomes unreachable after three consecutive connection failures, the firmware switches to the fallback pool. As of v2.15.0 the fallback is disabled by default (#1823), so you must enable it and configure a second pool URL, port, and user if you want a safety net.
Pool quick links: The Settings page includes one-click presets for a growing list of pools; v2.15.0 expanded the list (#1795, #1785).
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 in main.c, verified at v2.13.0, commit 18a5619) that operates independently from the mining pipeline. The controller was tuned in v2.14.0 (#1640), and since v2.15.0 the target temperature is shown on the dashboard temperature bar (#1691).
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, and a minimum fan speed percentage can be configured (v2.10.0, #1059).
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 stand designed for airflow.
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 edit.component.ts (verified at v2.13.0, commit 18a5619), which checks for the “oc” URL parameter and toggles overclock mode. 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. Since v2.14.0 the dashboard shows the actual resolved frequency, so you can confirm the PLL accepted your target.
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. The current implementation was introduced in v2.11.0 (#1304). When the ASIC chip temperature exceeds 75C or the voltage regulator temperature exceeds 105C (thresholds in power_management_task.c, verified at v2.13.0, commit 18a5619), 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
Since v2.15.0, updating AxeOS is a single-file upload: esp-miner.bin now contains both the firmware and the web interface, so you no longer upload a separate www.bin. Updating over Wi-Fi takes about 60 seconds and preserves all your settings.
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 and click “Check.”
4. If a newer version is available, download the esp-miner.bin file for that release.
5. Under “Update Firmware,” click “Browse,” select the downloaded esp-miner.bin file, and upload it. Since v2.14.0 a progress modal shows the upload status (#1650).
6. Wait approximately 60 seconds. A green “Success! Firmware updated” message confirms the update.
7. The device reboots automatically with the new firmware. Refresh the dashboard page after the reboot so your browser loads the new interface.
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 (the ESP-IDF OTA mechanism used in http_server.c, verified at v2.13.0, commit 18a5619). 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.
Upgrading from v2.14.x or earlier: Upload the v2.15.x esp-miner.bin as usual. The old www.bin upload field is no longer needed; the web interface is included in the main binary (#1763). v2.15.1 also updated the download-assets message on the update page to reflect this (#1907).
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.
Swarm milestones by version: sortable columns arrived in v2.9.0 (#948) along with a pool-difficulty column (#1103); a facelift, grid view, and device notifications came in v2.11.0 (#1231, #1247, #1290); remote clearing of power faults and a scan fix landed in v2.13.0 (#1524, #1528); device editing was fixed in v2.14.1 (#1767); and v2.15.1 fixed swarm IP handling (#1905).
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 (#884). In v2.14.0 a download button was added, and logs are preserved across soft reboots (#1646), which makes it far easier to capture what happened just before a restart.
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 (some ASUS and 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, using the LVGL library.
Screens include: the device’s IP address (essential for accessing the dashboard), current hashrate, ASIC temperature, best difficulty found, share acceptance stats, uptime, Wi-Fi signal strength (v2.9.0, #1019), and a mining status indicator. A Wi-Fi connect QR code is shown during setup (v2.11.0, #1323).
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 (v2.13.0, #1366). 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. Note that the Public Pool port in AxeOS changed from 21496 to 3333 in v2.14.0.
- 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. Since v2.11.0 AxeOS automatically cleans up the Stratum URL field (#1316).
- Confirm your router is not blocking mining traffic. Some ASUS and 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.
- Check whether mining is paused. v2.14.0 added a pause/resume control (#1608); a paused miner reports zero hashrate by design.
- If the issue persists, test with a known-reliable pool such as public-pool.io to rule out pool-side problems.
Cannot access the AxeOS dashboard:
- Type http:// explicitly before the IP address or hostname. AxeOS uses plain HTTP on port 80, and browsers may auto-redirect to HTTPS, which will fail.
- On v2.15.0 or later, try the hostname (for example, http://bitaxe.local) if the IP has changed.
- 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.
- If the dashboard loads but looks broken right after an update, hard-refresh the page. Since v2.15.0 the UI is embedded in the firmware and your browser may be caching the old interface.
“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.
- The fault can be cleared remotely from the Swarm tab since v2.13.0 (#1524).
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.
- On SV2 pools, “difficulty too low” rejects were fixed in v2.15.0 by keeping fractional pool difficulty (#1779). Update if you are on v2.14.x.
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.
- If your router runs in WPA2/WPA3 compatibility (mixed) mode, update to v2.15.1. It disables RSNO client support, which was breaking connections on those networks (#1912).
- 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.
- SSIDs up to 32 characters are supported since v2.13.0 (#1376); empty Wi-Fi passwords since v2.12.0 (#1387).
Firmware update shows “Failed”:
- Verify the file is named exactly “esp-miner.bin” (not “esp-miner (1).bin” or similar).
- Ensure you downloaded the correct file for your hardware version from the ESP-Miner releases page.
- Do not try to upload a www.bin on v2.15.0 or later; it no longer exists as a separate file.
- If OTA updates consistently fail, use the USB webflasher method described in our firmware update guide.
Which Settings Are Preserved During Updates?
OTA updates preserve every setting; factory flashes erase them unless you tick “Keep configuration.” Knowing which is which prevents reconfiguring everything after an 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. Since v2.15.0 this single upload also refreshes the web interface.
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)
A note on source citations: file and line references in this part were verified against ESP-Miner v2.13.0 (commit 18a5619). The v2.15.0 refactors (unified firmware, ESP-IDF 6.0.2, header decoupling) moved some code, so treat line numbers as a starting point for that tag rather than the current main branch.
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.15.1 (attributions taken from the release notes):
Skot (skot9000): Original creator of ESP-Miner and Bitaxe hardware. Wrote nearly all of the IC and ASIC drivers in the firmware. Variable-length extranonce2 (#1168).
WantClue: Lead developer and primary release manager. Overheat protection (#1304), BAP share request (#1482) and block-found parameter (#1547), TPS phase register support (#1490), IPv6 zone identifier fix (#1277), hashrate-register fallback fix (#1263), default wallet address warning (#1449), Public Pool port change (#1611), customizable dashboard (#1622), hostname change without reboot (#1726), board 603 support (#1760), Bluetooth LE (#1827), higher VIN for solar (#1819), 801 config (#1479), R2 deployment.
mutatrum: Prolific contributor. Hashrate registers and the error-percentage metric (#1249, #1271, #1301, #1340), queueless mining architecture (#1424), coinbase transaction parser (#1391), TLS co-authorship (#1413), mining.ping (#1439), fan controller task (#1357) and tuning (#1640), IPv6 public address resolution (#1468), swarm scanning and edit fixes (#1528, #1767), response time graph (#1423), uptime restoration (#1428), scoreboard (#1236), log download (#1646), WebSocket API (#1623), unified firmware (#1763), multi-line charts (#1736), total uptime and hashes (#1555), PrimeNG-to-Tailwind migration (#1815), Angular 19 upgrade (#1651), self-test refactors (#1615, #1632), the v2.13.1 self-test fix (#1580), the RSNO/WPA2-3 compatibility fix (#1912), and Bitaxe Color support for the Naja Duo and Gamma Hex ST7789 display (#1916, v2.15.2rc0).
benjamin-wilson: Core firmware engineer. ASIC driver work (BM1370, BM1368, and the BM1372/BM1373 driver in v2.15.2rc0, #1890), device model abstraction (801 strapless #1478, 650 Duo #1537), self-test infrastructure and validation (#1480, #1596, #1642, #1738), BAP protocol improvements (#1525), CSRF fix (#637).
warioishere: Stratum V2 protocol support (#1553), SV2 per-share response time (#1720), TCP_NODELAY on pool sockets (#1722), SV2 single-write frames (#1771), fractional SV2 difficulty (#1779), pending SV2 shares on dashboard (#1735), testnet/regtest detection in the coinbase decoder (#1578), blitzpool rejection reasons (#1695).
duckaxe: Frontend developer. Dashboard unreachable notification (#1385), swarm table sorting (#948), swarm facelift and grid view (#1231, #1247), navigation redesign (#1026), custom component icons (#1435), browser tab title (#996), identify device (#1369), sensitive data service (#1135), log font fix (#1448), TLS UI integration.
terratec: Real-time log filtering and clear (#884), chart data source selection (#955), statistics slider consolidation (#1016), screen wake on identify mode (#1443), API type checks (#880).
0xf0xx0: OpenAPI specification maintenance (#1433, #1467), frontend API generation from the spec (#1442), fan RPM tooltip merge (#1527), configurable minimum fan speed (#1059), SV2 minimum extranonce reduction (#1799), restart prompt in topbar (#1831).
eandersson: Build system and ESP-IDF upgrades (5.5.1 #1215, 5.5.2 #1486, 5.5.3 #1581, 6.0.2 #1829), WebSocket reconnect loop fix (#1830).
camalolo: mDNS support (#1240). AxisRay: Co-authored TLS (#1413). b-rowan: Pause/resume mining (#1608). adammwest: Nonce space and timeout control for all chip topologies (#420). leandroalbero: Block found condition fix (#1419). mweinberg: AtlasPool dashboard link (#1416). Zayno: Rejected-share stats buffer overflow fix (#1754). r3mko: 64-bit statistics timestamps (#1545), fallback default change (#1823), reconnect-storm prevention (#1913). tassoneroberto: Update-page asset message (#1907). steveluscher: Settings page typo fix (#1920). SoloSatoshi: Self-test auto-restart for Bitaxe Touch production (#1602).
Additional contributors include pRizz (documentation), STSMiner1 (esptool version and router compatibility notes, #1252), johnny9 (devcontainer and build tooling), KillerInk, frickl, cbyam, sololuckio, mbmtbtbc, Distortions81, maxmalysh, jemekite, and shaunography (CSRF vulnerability discovery).
System Architecture Overview
AxeOS uses a hub-and-spoke architecture with a central GlobalState structure serving as the shared data repository for all subsystems. GlobalState is defined in main/global_state.h and statically allocated in main/main.c (verified at v2.13.0, commit 18a5619).
The firmware is organized into four layers:
User Interface Layer: Web UI (AxeOS Angular dashboard), physical OLED/LCD display, REST API, WebSocket API and log streaming, BAP protocol for accessories, and (since v2.15.0) Bluetooth LE.
Application Layer: System initialization, power management, thermal protection, fan control, and self-test diagnostics.
Mining Layer: Stratum V1 and V2 protocol handling, job creation, ASIC work submission, nonce validation, and share submission.
Hardware Layer: ASIC chip drivers (BM1366/1368/1370/1397, plus BM1372/1373 in the v2.15.2 RC), 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) to prevent race conditions on shared data; a v2.13.0 fix corrected its initialization (#1441).
The GlobalState structure contains module sub-structures including SystemModule (share statistics, pool configuration, network status), PowerManagementModule (voltage, power, temperature, frequency), AsicTaskModule (active jobs array, current job pointer, semaphore), and DeviceConfig (hardware variant identification). v2.15.0 decoupled header dependencies and tightened type safety across these modules (#1826).
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. Each release ships around 20 factory images, one per board configuration.
| 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) | 302-303 | BM1366 | 6 | ~3 TH/s |
| Bitaxe Supra | 400-403 | BM1368 | 1 | ~600 GH/s |
| Bitaxe Gamma | 601-603 | 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 |
| Bitaxe Naja Duo (v2.15.2rc0) | See product page | BM1373 | 2 | See product page |
| Bitaxe Gamma Hex (v2.15.2rc0) | See product page | See product page | See product page | See product page |
Board version 603 (a Gamma revision) was added in v2.14.1 (#1760). The Bitaxe Naja Duo and Bitaxe Gamma Hex, both with an ST7789 color display, are supported starting with the v2.15.2rc0 release candidate (#1916), which also introduces the BM1372/BM1373 driver (#1890); the release notes do not yet list their config IDs. Read more in our Bitaxe Naja Duo coverage. The 801 GT was finalized in v2.12.2 and the 650 Duo in v2.13.0, where its default frequency was set to 400 MHz (#1557). Hex 303 returned in v2.11.0 (#1257) and SupraHex 701/702 in v2.12.0 (#1395).
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; v2.15.0 added a global PSRAM allocation check (#1772).
Software Stack and Dependencies
ESP-IDF 6.0.2: Espressif’s official development framework providing hardware abstraction, networking (lwIP), TLS (mbedTLS), NVS flash storage, and the FreeRTOS kernel. v2.15.0 upgraded from 5.5.3 to 6.0.2 (#1829); v2.13.0 ran 5.5.2 and v2.14.0 ran 5.5.3.
FreeRTOS: 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 19 and Tailwind CSS: The AxeOS web dashboard is an Angular single-page app, upgraded to Angular 19 in v2.15.0 (#1651). PrimeNG was removed in the same release in favor of Tailwind CSS (#1815). The frontend auto-generates its API client from the OpenAPI specification in main/http_server/openapi.yaml (#1442, migrated to ng-openapi-gen in v2.14.0, #1597). Since v2.15.0 the compiled UI is embedded in esp-miner.bin rather than a separate SPIFFS image.
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.
LVGL: Graphics library driving the OLED/LCD display, and the ST7789 color display on the Naja Duo and Gamma Hex as of v2.15.2rc0 (#1916).
Initialization and Startup Sequence
The app_main() function in main/main.c orchestrates a strict dependency-ordered initialization. The following sequence is verified against v2.13.0 (commit 18a5619); line numbers refer to that tag.
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 the version file.
Step 14 (line 100): BAP_init(&GLOBAL_STATE). Initializes the Bitaxe Accessory Protocol interface.
Step 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. Since v2.15.0, mDNS registration and (where enabled) Bluetooth LE also start during boot.
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 for V1 (mining.subscribe, mining.authorize, mining.notify, mining.submit) or the SV2 mining protocol since v2.14.0. Manages automatic failover to the backup pool after three consecutive connection failures (when a fallback is configured). Uses a monotonically increasing message ID system starting from 1 and a 1,024-entry circular buffer for request timing (MAX_REQUEST_IDS), verified at v2.13.0, commit 18a5619.
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 new work, 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) for improved performance. v2.14.0 added functions to control nonce space and timeouts for all chip topologies (#420) and ignores duplicate job IDs since v2.15.0 (#1731).
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. Hashrate-counter overflow on reconnect was fixed in v2.14.0 (#1564), and hashrate spikes in v2.13.0 and v2.14.0 (#1559, #1673).
Stratum V1 Protocol Implementation
Stratum V1 is the default and most widely supported protocol in AxeOS, implemented in components/stratum/stratum_api.c and main/tasks/stratum_task.c (verified at v2.13.0, commit 18a5619; the parsing code was cleaned up in v2.15.0, #1755).
Transport: Connections are established over TCP or TLS using ESP-IDF’s esp_transport component. The STRATUM_V1_transport_init() function 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. TCP_NODELAY is set on pool sockets since v2.14.0 (#1722).
DNS Resolution: Supports both IPv4 and IPv6 with automatic address family selection. 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 (for example, fe80::1%wlan0). Public IPv6 name resolution was added in v2.13.0 (#1468).
Message Parsing: The STRATUM_V1_parse() function 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. client.show_message is handled since v2.14.0 (#1565), and fractional mining.set_difficulty values are accepted (#1594).
Share Submission: When a valid nonce is found, STRATUM_V1_submit_share() formats the JSON-RPC message. Response processing categorizes rejected shares by error message and counts them in the rejected_reason_stats[] array for dashboard display (a buffer overflow in this array was fixed in v2.14.1, #1754).
Failover: A separate heartbeat task monitors primary pool availability using lightweight probe connections. When the primary pool recovers, the main task reconnects. Share statistics are cleared during failover. Fallback is off by default since v2.15.0 (#1823).
Coinbase Transaction Parser: Added in v2.13.0 (#1391), this decoder parses the coinbase transaction from mining.notify data, enabling the dashboard to display the pool’s payout information and block reward details, which is how AxeOS can flag a scam pool. An option to disable the decoder was added for non-Bitcoin chains (#1544), and testnet/regtest detection came in v2.14.0 (#1578).
Stratum V2 (SV2) Support
AxeOS has supported Stratum V2 since v2.14.0 (June 4, 2026), when warioishere’s implementation was merged (#1553). SV2 is selectable per pool in Settings; Stratum V1 remains the default and works with every pool.
What SV2 changes: Stratum V2 replaces V1’s plaintext JSON-RPC with a binary, encrypted framing protocol. For a home miner, the practical benefits are a smaller, faster message format and built-in transport encryption without needing the separate TLS option. For background on why SV2 matters for decentralization, see our explainer on DATUM and Stratum V2.
SV2 improvements by release:
- v2.14.0: initial SV2 support (#1553); per-share response time measurement for SV2 (#1720); TCP_NODELAY on pool sockets to fix SV2 submit latency (#1722); fix for the “work received” screen notification under SV2 (#1778, shipped in v2.15.0).
- v2.15.0: SV2 frames sent in a single write (#1771); frame size increased to 8 KB (#1783); minimum extranonce size reduced from 6 to 2 bytes (#1799); fractional SV2 pool difficulty retained to avoid “difficulty too low” rejects (#1779); per-pool “require authentication” option (#1796); pending SV2 shares shown on the dashboard (#1735); SV2 NVS configuration cleaned up (#1743).
Which pools support SV2: Only a handful of pools speak SV2 today, and the list changes. Check the pool’s own documentation for an SV2 endpoint (host and port) before switching. [PLACEHOLDER: list the SV2 pools tested on the Solo Satoshi bench, with endpoint and date.] Every pool still supports Stratum V1, so V1 is the safe default.
How to connect a Bitaxe to a Stratum V2 pool
- Update to v2.15.1 or later. SV2 shipped in v2.14.0, but the framing, extranonce, and fractional-difficulty fixes in v2.15.0 (#1771, #1783, #1799, #1779) remove the most common causes of rejected SV2 shares.
- Get the pool’s SV2 endpoint. SV2 uses a different host/port from the pool’s V1 Stratum address. Copy it exactly from the pool’s docs.
- Open Settings and edit the pool. Enter the SV2 host and port, then switch the pool’s protocol from Stratum V1 to Stratum V2. [PLACEHOLDER: exact field label as shown in the v2.15.1 Settings page, with screenshot.]
- Set the user and authentication. Enter your wallet address (and worker name, if the pool uses one) as usual. If the pool requires authentication over SV2, enable the per-pool “require authentication” option added in v2.15.0 (#1796).
- Save and let the miner reconnect. Watch the Logs tab. [PLACEHOLDER: paste the handshake lines from a successful SV2 connection on the bench.]
- Confirm shares are counted. The dashboard shows pending SV2 shares since v2.15.0 (#1735), and accepted shares should climb within a minute or two. Response time is measured per share on SV2 (#1720).
What a failing SV2 connection looks like: [PLACEHOLDER: paste log lines from a wrong-port and a wrong-protocol attempt on the bench.] The two common mistakes are pointing the SV2 setting at the pool’s V1 port, and forgetting to enable SV2 on the pool side where the pool requires it. If shares are rejected for “difficulty too low” on v2.14.x, update to v2.15.x (#1779). If nothing works, switch the pool back to Stratum V1; it is fully supported and every pool accepts it.
TLS Encrypted Pool Connections
TLS support for Stratum V1 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 (#1447). Stratum V2 provides its own transport encryption and does not use these modes.
ASIC Hardware Control and Chip Drivers
AxeOS supports four Bitmain SHA-256 ASIC models in stable firmware, with a fifth driver (BM1372/BM1373) arriving in the v2.15.2 release candidate (#1890). Drivers live in the components/asic/ directory (line counts as of v2.13.0, commit 18a5619).
| ASIC | Driver File | Bitaxe Models | Process |
|---|---|---|---|
| BM1397 | bm1397.c (454 lines) | Max (legacy) | 7nm |
| BM1366 | bm1366.c (448 lines) | Ultra, Hex, SupraHex | 5nm |
| BM1368 | bm1368.c (358 lines) | Supra | 5nm |
| BM1370 | bm1370.c (485 lines) | Gamma, Duo, GT, Turbo Touch | 5nm |
| BM1372 / BM1373 | Added in v2.15.2rc0 (#1890) | Naja Duo (pre-release) | See manufacturer spec |
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.
Initialization: Each driver implements an init function 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 (bm1370.c, verified at v2.13.0): Frequency = 25MHz * fb_divider / (ref_divider * post_divider1 * post_divider2). Floating-point PLL calculation for BM1366/1368/1370 arrived in v2.10.0 (#1051). Frequency transitions ramp gradually through intermediate steps, preventing ASIC lockups from abrupt jumps; a ramp for the BM1397 was added in v2.12.0 (#1069). Since v2.14.0 the dashboard reports the resolved frequency the PLL actually locked to (#1674).
Hashrate Registers: Since v2.11.0 (#1249, #1271, #1301) the firmware reads the ASIC’s own hashrate registers, which is what powers the error-percentage metric and the per-core heatmap (#1274).
Expected Hashrate Calculation: expected_hashrate (GH/s) = frequency (MHz) * small_core_count * asic_count / 1000 (power_management_task.c, verified at v2.13.0).
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 in power_management_task.c at v2.13.0, commit 18a5619.
Sensor Reading: Each cycle reads from I2C peripherals: INA260 (input voltage, power, current) on older boards, 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. A power-reading race condition was fixed in v2.14.0 (#1669), and TPS546 configuration moved into NVS in v2.15.0 (#1838).
Thermal Thresholds:
| 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 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. 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 every hardware variant.
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 (for example, 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. Custom board configs are supported since v2.9.0 (#1018).
Tier 3 (Runtime): main/nvs_config.c provides type-safe get/set functions with an enum-based key system. The settings[] array 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) prevents blocking the HTTP request handler during flash writes; NVS access was isolated into its own task in v2.11.0 (#1286). The background task processes writes sequentially and commits after each operation. Unchanged values are not rewritten (v2.12.0, #1410), and indexed strings are supported since v2.14.0 (#1504).
Factory Self-Test System
The self-test at main/self_test/self_test.c 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. The test was refactored twice in v2.14.0 (#1615, #1632) and gained configurable warm-up temperature and fan speed in v2.14.1 and v2.15.0 (#1764, #1817).
Tests and pass criteria (verified at v2.13.0, commit 18a5619):
- PSRAM. esp_psram_is_initialized() must return true. Failure prints “PSRAM:FAIL” and halts.
- Voltage regulator. The TPS546 or DS4432U must respond on I2C. Failure prints “VCORE:FAIL” and halts.
- Core voltage. Measured value must fall between 1000 mV and 1300 mV. Failure prints “VCORE:FAIL” and halts.
- ASIC count. Detected chips must match the expected configuration. Failure prints “ASIC:FAIL X CHIPS” and halts.
- Temperature. Must read between -1C and 55C during the test. Failure prints “TEMP:FAIL” and halts. The ASIC start temperature was raised in v2.14.0 (#1642).
- Hashrate. Must hold 95% or more of expected hashrate for 30 seconds. Failure prints “HASHRATE:FAIL” and halts. Since v2.13.2 the test monitors share domains (#1596).
- Power draw. Must be within 3W of target; a reading below target passes (v2.12.0, #1415). Failure prints “POWER:FAIL” and halts.
- Fan speed. Must exceed 1000 RPM (500 RPM on Gamma/Hex). Failure prints “FAN:WARN” and continues.
On a pass, Bitaxe Touch production units auto-restart after 10 seconds (v2.14.0, #1602, contributed by Solo Satoshi). Frequency falls back to the board default during the test since v2.14.2 (#1805), and the Stratum coordinator no longer runs during self-test as of v2.15.0 (#1882).
“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 and WebSocket API Reference
AxeOS exposes a RESTful API documented in main/http_server/openapi.yaml, plus a WebSocket API added in v2.14.0 (#1623). 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, blockFound.
Since v2.9.0, stratumDiff was renamed poolDifficulty, flipScreen was replaced by rotation (0/90/180/270), and asicCount moved to /api/system/asic. bestDiff, bestSessionDiff, and networkDifficulty are numbers, not strings, since v2.11.0 (#1202, #1309).
GET /api/system/asic: ASIC-specific settings and identification data, including deviceModel, swarmColor, and asicCount.
GET /api/system/statistics: Historical time-series data. Accepts query parameters specifying which data sources to include: hashrate, hashrate_1m, asicTemp, power, fanRpm, responseTime. Stores up to 720 data points (1 hour at 5-second intervals). URL decoding of path parameters was fixed in v2.14.0 (#1677).
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. Since v2.15.0 this single upload also updates the web interface; the separate www.bin upload path is no longer needed.
PATCH /api/system: Accepts JSON body with configuration parameters to update. Changes are enqueued to the async NVS write queue. Type checks and min/max constraints are enforced (#880).
WebSocket API (v2.14.0+): Live device data pushed over a WebSocket, avoiding 5-second polling for integrations; an error counter fix followed in the same release (#1700). Stale clients are removed after failed sends (v2.15.0, #1803) and reconnect loops were fixed (#1830). Log streaming continues to use /api/ws.
CORS and access control: API access is restricted to private IP ranges (10.x, 172.16-31.x, 192.168.x) and AP-mode connections. Unknown API routes return a JSON 404 (v2.11.0, #1296). v2.15.0 included a full HTTP handler audit (#1759).
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 touchscreen on the Bitaxe Turbo Touch) to receive mining data and control signals. The accessory port itself was introduced in v2.10.0 (#1178).
In v2.13.0, BAP received significant improvements: protocol improvements (#1525), share request capability (#1482), and block found parameter reporting (#1547). BAP is initialized during the boot sequence, before Wi-Fi connects.
The BAP-GT-TOUCH firmware variant specifically targets Bitaxe Touch hardware with enhanced display features through the BAP protocol layer. See our Turbo Touch setup guide for updating that screen firmware.
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).
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 V1 pool connections; SV2 (v2.14.0+) encrypts its own transport.
Default Address Warning (v2.13.0+): Dashboard warns if the default placeholder wallet address is still configured (#1449).
Coinbase Decoder (v2.13.0+): Shows where the pool would actually pay a block reward, exposing pools that quietly redirect rewards.
Sensitive Data Masking (v2.11.0+): Wallet address and other sensitive fields can be hidden on the dashboard (#1135, #1287).
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.
Memory-safety fixes: v2.14.x and v2.15.0 closed a use-after-free race (#1797), a rejected-share buffer overflow (#1754), and a heap fragmentation crash (#1766).
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 compresses all assets. Since v2.15.0 the build embeds the result into the firmware binary (#1763); the build step is skipped when the tracked web_ui_dist files are unchanged (#1338). During development, the npm dev server can connect to a real device (#1699).
Stage 2 (Firmware): idf.py build compiles all C source, links ESP-IDF 6.0.2 libraries, and creates partition images. The merge_bin.sh script combines bootloader, partition table, and application into a single flashable factory 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. Frontend tests run in CI since v2.14.0 (#1653). An AGENTS.md file documents conventions for AI-assisted contributions (#1656).
Bitaxetool: Command-Line Flashing Utility
Install: pip install –upgrade bitaxetool (Python 3.4+). An older esptool release is required; check the ESP-Miner README’s esptool note (added in v2.11.0, #1252) for the currently supported version before installing.
Flash factory image: bitaxetool –firmware ./esp-miner-factory-602-v2.15.1.bin
Flash NVS config only: bitaxetool –config ./config-602.cvs
Flash both: bitaxetool –config ./config-602.cvs –firmware ./esp-miner-factory-602-v2.15.1.bin
Config values override those baked into the factory image. Custom hardware is supported via config-custom.cvs (must be based on an existing device/ASIC model). Run bitaxetool from outside the Docker devcontainer. Some hardware versions before the 602 require a USB-A adapter for the USB-C port (README note, #1225).
Version History Highlights
Release dates and contents below are taken from the ESP-Miner GitHub releases page.
- v2.5.0 (January 2025). CSRF vulnerability patch and IP-based access control.
- v2.9.0 (July 1, 2025). Log filtering and clear (#884), swarm sorting (#948), navigation redesign (#1026), AxeOS version display and mismatch warning (#1006), statistics slider (#1016), stratum response time (#1063), custom board config (#1018), Ultra 207 support (#992). API: stratumDiff renamed poolDifficulty, rotation replaces flipScreen.
- v2.10.0 (September 4, 2025). Pool difficulty on dashboard (#1170), minimum fan speed setting (#1059), Bitaxe accessory port (#1178), floating-point PLL calculation (#1051), variable-length extranonce2 (#1168). v2.10.1 (October 28): self-test and TPS546 fixes.
- v2.11.0 (November 15, 2025). Hashrate registers and error-percentage metric (mutatrum, #1249, #1271, #1301, #1340), hashrate heatmap (#1274), overheat protection (#1304), IPv6 stratum (#1254) with zone-identifier fix (#1277), sensitive data masking (#1135), swarm facelift and grid view (#1231, #1247), Hex 303 (#1257), Wi-Fi QR code (#1323), ESP-IDF 5.5.1.
- v2.12.0 (December 4, 2025). Identify device (#1369), 1m/10m/1h hashrate graph (#1348), reset reason on System page (#1401), SupraHex 701/702 (#1395), BM1397 frequency ramp (#1069), don’t write unchanged NVS values (#1410).
- v2.12.2 (January 6, 2026). Bitaxe GT 801 supported (#1479, #1478), TPS phase registers (#1490), self-test improvements (#1480, #1432, #1461).
- v2.13.0 (February 20, 2026). TLS Stratum (#1413), Duo 650 (#1537), queueless mining (#1424), coinbase transaction parser (#1391), BAP improvements (#1525, #1482, #1547), IPv6 public resolution (#1468), mining.ping (#1439), response time graph (#1423), fan controller task (#1357), block-found dismiss (#1550), default address warning (#1449), clear power fault from swarm (#1524), 32-character SSIDs (#1376), ESP-IDF 5.5.2.
- v2.13.1 (March 3, 2026). Self-test fix for manufacturers (#1580).
- v2.13.2 (March 5, 2026, marked pre-release). Self-test domain monitoring (#1596), R2 deployment fix (#1569), “mining reward” terminology (#1566).
- v2.14.0 (June 4, 2026). Stratum V2 (#1553), customizable dashboard (#1622), scoreboard (#1236), pause/resume mining (#1608), log download (#1646), WebSocket API (#1623), actual frequency display (#1629, #1674), CPU usage metrics (#1621), BIP-54/BIP-110 signals (#1609, #1588), Public Pool port 3333 (#1611), fractional difficulty (#1594), fan controller tuning (#1640), hostname change without reboot (#1726), self-test refactor (#1615, #1632, #1738), ESP-IDF 5.5.3.
- v2.14.1 (June 19, 2026). Board 603 (#1760), configurable self-test warm-up temp (#1764), swarm edit fix (#1767), rejected-share buffer overflow fix (#1754).
- v2.14.2 (July 8, 2026). Use-after-free race fix (#1797), self-test frequency fallback (#1805).
- v2.15.0 (August 21, 2026). Unified firmware with embedded web UI (#1763), mDNS (#1240), Bluetooth LE (#1827), multi-line charts (#1736), total uptime and hashes (#1555), target temp on temp bars (#1691), higher VIN for solar (#1819), fallback pool off by default (#1823), SV2 framing and difficulty fixes (#1771, #1783, #1799, #1779), SV2 per-pool auth (#1796), TPS546 config in NVS (#1838), PSRAM check (#1772), HTTP handler audit (#1759), heap fragmentation fix (#1766), PrimeNG to Tailwind (#1815), Angular 19 (#1651), ESP-IDF 6.0.2 (#1829).
- v2.15.1 (August 29, 2026). Swarm IP fix (#1905), update-page asset message (#1907), RSNO disabled for WPA2/3 compatibility mode (#1912), reconnect-storm prevention (#1913).
- v2.15.2rc0 (August 29, 2026, release candidate). BM1372/BM1373 ASIC driver (#1890), Bitaxe Color support for Naja Duo and Gamma Hex with ST7789 display (#1916), settings typo fix (#1920), plus the v2.15.1 fixes. Test build only.
Pre-release and early-access builds (v2.14.0b1-b4, early-access-2026-03, v2.15.2rc0) are also published on the releases page but are not recommended for production miners unless you need hardware support that only exists there.
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 50,000 mining devices to 70+ countries since May 2024. All devices are assembled in the USA with same-day shipping from Conroe, Texas.
Can I use AxeOS to monitor my Bitaxe from my phone?
Does AxeOS send any data to the cloud or third parties?
Can I use a Lightning address with AxeOS?
Does AxeOS only work with 2.4 GHz Wi-Fi?
Can I run multiple Bitaxe devices on the same pool and wallet address?
What happens if my internet goes down while AxeOS is mining?
Can I access AxeOS remotely from outside my home network?
Is there a way to get notified if my Bitaxe goes offline or finds a block?
Can I use AxeOS with a Bitcoin node I run at home?
Does AxeOS support Stratum V2?