Skip to content

SparkMiner: A high-performance, open-source ESP32 Bitcoin solo miner. By combining the usability of NerdMinerV2 with the raw speed of BitsyMiner's pipelined assembly, SparkMiner delivers optimized hashrates (~725+ KH/s) to challenge paid firmware alternatives.

License

Notifications You must be signed in to change notification settings

SneezeGUI/SparkMiner

Repository files navigation

SparkMiner v2.9.5

High-performance Bitcoin solo miner for ESP32, ESP32-S3 & ESP32-C3

SparkMiner Display

SparkMiner is optimized firmware for ESP32-based boards with displays, delivering ~1+ MH/s (pool-reported) using hardware-accelerated SHA-256 and pipelined assembly mining. Supports both ESP32 "Cheap Yellow Display" (CYD) boards and ESP32-S3 variants.

Solo Mining Disclaimer: Solo mining on an ESP32 is a lottery. The odds of finding a block are astronomically low (~1 in 10^20 per hash at current difficulty). This project is for education, fun, and supporting network decentralization - not profit.


Quick Start

Option 1: Launcher + SD Card (Recommended for CYD Boards)

The easiest way to install and manage SparkMiner on CYD boards (1-USB or 2-USB variants):

Step 1: Flash the Launcher (one-time)

  1. Go to Bruce Launcher Web Flasher
  2. Connect your CYD board via USB
  3. Select your board type and click Install
  4. The Launcher provides a boot menu for multiple firmwares

Step 2: Prepare SD Card

  1. Format a microSD card as FAT32
  2. Download cyd-2usb_firmware.bin (or your board variant) from Releases
  3. Copy the .bin file to the SD card root
  4. Create a config.json file (see Configuration section)
  5. Insert SD card into CYD

Step 3: Boot SparkMiner

  1. Power on the CYD - the Launcher menu appears
  2. Select SparkMiner firmware from the SD card
  3. SparkMiner loads your config and starts mining!

Why use the Launcher?

  • Easy firmware updates - just replace the .bin on SD card
  • Switch between multiple firmwares
  • No need to re-flash via USB for updates
  • Config persists on SD card

Option 2: Direct USB Flashing

  1. Download the latest *_factory.bin firmware from Releases
  2. Flash using ESP Web Flasher or esptool:
    esptool.py --chip esp32 --port COM3 write_flash 0x0 cyd-2usb_factory.bin
  3. Power on the board - it will create a WiFi access point
  4. Connect to SparkMiner-XXXX WiFi and configure via the web portal

Option 3: Build from Source

# Clone repository
git clone https://github.com/SneezeGUI/SparkMiner.git
cd SparkMiner

# Create virtual environment and install dependencies
python -m venv .venv
.venv\Scripts\activate  # Windows
# source .venv/bin/activate  # Linux/Mac
pip install platformio

# Use the interactive devtool (recommended)
devtool.bat          # Windows - interactive menu
python devtool.py    # Cross-platform

# Or build a specific board directly
python devtool.py build -b cyd-2usb
python devtool.py flash -b cyd-2usb
python devtool.py monitor

# All-in-one: build, flash, and monitor
python devtool.py all -b cyd-2usb

Firmware Types

Understanding the difference between the firmware files:

  • *_firmware.bin: The application only. Use this for Launcher/SD card updates or OTA updates. It does not include the bootloader.
  • *_factory.bin: The complete image (Bootloader + Partition Table + App). Use this for direct USB flashing (Option 2) to a blank board or to restore a board.

Upgrading

To upgrade from an older version:

  1. Via SD Card (Launcher): Replace the *_firmware.bin file on your SD card with the new version (e.g., cyd-2usb_firmware.bin).
  2. Via USB: Flash the new *_factory.bin using the interactive devtool.py or esptool.

Note: NVS stats are persistent across standard reboots, but a full flash might clear NVS depending on your method. The SD card backup (/stats.json) ensures your lifetime totals can be restored.


Which Firmware Do I Download?

Find your board below and download the matching firmware from Releases.

CYD (Cheap Yellow Display) Boards - 2.8" TFT

Your Board Firmware File Notes
CYD 2-USB (Type-C + Micro USB) cyd-2usb_firmware.bin Most common, dual USB ports
CYD 1-USB (Single Micro USB) cyd-1usb_firmware.bin Single USB, ILI9341 display
CYD 1-USB ST7789 cyd-1usb-st7789_firmware.bin ST7789 display variant
ESP32-2432S028R cyd-1usb_firmware.bin Same as CYD 1-USB
ESP32-2432S028R 2-USB cyd-2usb_firmware.bin Same as CYD 2-USB

ESP32-S3 Boards

Your Board Firmware File Notes
Freenove ESP32-S3 (FNK0104) freenove-s3_firmware.bin 2.8" IPS display, SD_MMC
Freenove ESP32-S3-WROOM CAM freenove-s3_firmware.bin Same board, ignore camera
ESP32-S3 DevKit esp32-s3-devkit_firmware.bin Headless (no display)
Wemos/Lolin S3 Mini esp32-s3-mini_firmware.bin RGB LED status indicator
WeAct S3 Mini esp32-s3-mini_firmware.bin Compatible with Lolin
ESP32-S3 + SSD1306 OLED esp32-s3-oled_firmware.bin 128x64 I2C OLED

ESP32-C3 Boards

Your Board Firmware File Notes
ESP32-C3 SuperMini esp32-c3-supermini_firmware.bin Headless, ultra-compact
ESP32-C3 + SSD1306 OLED esp32-c3-oled_firmware.bin 128x64 I2C OLED
Seeed XIAO ESP32-C3 esp32-c3-supermini_firmware.bin Use SuperMini firmware

Generic ESP32 Boards

Your Board Firmware File Notes
ESP32 DevKit esp32-headless_firmware.bin Any generic ESP32, GPIO LED status
ESP32-WROOM-32 esp32-headless_firmware.bin GPIO LED on pin 2
NodeMCU ESP32 esp32-headless_firmware.bin Use headless firmware

File Types

  • *_firmware.bin - Use with Bruce Launcher or SD card boot
  • *_factory.bin - Use for direct USB flashing (includes bootloader)

Hardware

Performance by Chip

Chip Hashrate Notes
ESP32 (dual-core) ~715 KH/s Best performance, hardware SHA-256
ESP32-S3 (dual-core) ~280-400 KH/s Software SHA-256, more RAM
ESP32-C3 (single-core) ~200-300 KH/s RISC-V, lowest power

Board Compatibility Status

Board Status Notes
CYD (ESP32-2432S028) ✅ Full Primary target, 3 variants
Freenove ESP32-S3 ✅ Full 2.8" IPS with SD_MMC
ESP32-S3/C3 + OLED ✅ Full 128x64 SSD1306 I2C
ESP32-S3/C3 Mini ✅ Full RGB LED status
ESP32 Headless ✅ Full GPIO LED status indicator
LILYGO T-Display S3 ❌ None Not yet supported
LILYGO T-Display V1 ❌ None Not yet supported
ESP32-S2 boards ❌ None Single-core not supported
M5Stack boards ❌ None Not configured

Legend: ✅ Supported | ❌ Not supported

Where to Buy

  • AliExpress: Search "ESP32-2432S028" for CYD boards (~$4-16 USD)
  • Amazon: Search "CYD ESP32 2.8 inch" or "Freenove ESP32-S3" (~$15-25 USD)
  • Freenove Store: FNK0104 ESP32-S3 Display (~$20 USD)

Hardware Features

  • CPU: Dual-core Xtensa LX6 @ 240MHz (ESP32), LX7 (S3), or single-core RISC-V (C3)
  • Display: TFT (ILI9341/ST7789) or OLED (SSD1306)
  • Storage: MicroSD card slot (select boards)
  • Connectivity: WiFi 802.11 b/g/n
  • RGB LED: Status indicator (S3 Mini, Headless-LED boards)
  • GPIO LED: Simple blink status indicator (Headless boards, pin 2)
  • Button: Boot button for interaction

Configuration

SparkMiner can be configured in three ways (in order of priority):

1. SD Card Configuration (Recommended)

Create a config.json file on a FAT32-formatted microSD card:

{
  "ssid": "YourWiFiName",
  "wifi_password": "YourWiFiPassword",
  "pool_url": "public-pool.io",
  "pool_port": 21496,
  "wallet": "bc1qYourBitcoinAddressHere",
  "worker_name": "SparkMiner-1",
  "pool_password": "x",
  "brightness": 100
}

Configuration Options

Field Required Default Description
ssid Yes - Your WiFi network name
wifi_password Yes - Your WiFi password
pool_url Yes public-pool.io Mining pool hostname
pool_port Yes 21496 Mining pool port
wallet Yes - Your Bitcoin address (receives payouts)
worker_name No SparkMiner Identifier shown on pool dashboard
pool_password No x Pool password (usually x)
brightness No 100 Display brightness (0-100)
screen_timeout No 0 Screen auto-off timeout in seconds (0=never, 30, 60, 120, 300)
rotation No 1 Screen rotation (0-3)
invert_colors No false Invert display colors
backup_pool_url No - Failover pool hostname
backup_pool_port No - Failover pool port
backup_wallet No - Wallet for backup pool
stats_enabled No true Enable/disable live stats fetching
stats_api_url No - Custom stats API endpoint (HTTP)
stats_proxy_url No - HTTP proxy for HTTPS APIs
enable_https_stats No false Direct HTTPS (unstable)

2. WiFi Access Point Portal

If no SD card config is found, SparkMiner creates a WiFi access point:

  1. Connect to WiFi network: SparkMiner-XXXX (password: minebitcoin)
  2. Open browser to http://192.168.4.1
  3. You will see the new dark-themed portal with full configuration options:
    • Primary & Backup Pool settings
    • Display brightness, rotation, and color inversion
    • Target difficulty
  4. Configure your settings, click Save, and the device will reboot and connect.

3. NVS (Non-Volatile Storage)

Configuration is automatically saved to flash memory after first successful setup. To reset:

  • Long-press BOOT button (1.5s) during operation for 3-second countdown reset, OR
  • Hold BOOT button for 5 seconds at power-on, OR
  • Reflash the firmware

Persistent Mining Stats

SparkMiner automatically saves mining statistics to ensure your lifetime totals are preserved across reboots and power cycles.

  • NVS Persistence: Stats are saved to the device's non-volatile storage.
    • Triggers: First share found, 5 minutes after boot, and hourly thereafter.
    • Data: Lifetime hashes, shares (accepted/rejected), best difficulty, and blocks found.
  • SD Card Backup: If an SD card is present, stats are also backed up to /stats.json for disaster recovery. This survives firmware updates and factory resets.
  • Reset: A factory reset (long-press BOOT) will clear NVS stats. Delete /stats.json from the SD card to fully reset.

Live Stats Configuration

SparkMiner displays live Bitcoin price, network hashrate, difficulty, and fee estimates. These external APIs use HTTPS, which is memory-intensive for the ESP32 and can impact mining hashrate.

SparkMiner supports three modes for fetching external stats (in priority order):

Priority 1: Custom Stats API (Recommended)

If you're running a stratum proxy (e.g., for solo mining via VPN), you can extend it to serve aggregated stats via HTTP. This is the most efficient option - single HTTP call, zero SSL overhead.

{
  "stats_enabled": true,
  "stats_api_url": "http://192.168.1.100:3334/stats"
}

Expected API response format:

{
  "btc_price_usd": 94100,
  "block_height": 880000,
  "network_hashrate": "600.00 EH/s",
  "network_difficulty": "90.00T",
  "fee_half_hour": 5,
  "fee_fastest": 10,
  "workers": 4,
  "pool_name": "My Pool",
  "failovers": 0,
  "pool_hashrate": "50.00 PH/s",
  "worker_hashrate": "1.50 MH/s",
  "address_best_diff": "100.00K",
  "difficulty_progress": 45.0,
  "difficulty_change": -2.5,
  "difficulty_retarget_blocks": 1100
}

Priority 2: HTTP Proxy (SSL Bumping)

Run an HTTP-to-HTTPS proxy that handles SSL/TLS offloading:

# Using Node.js (save scripts/cloudflare_stats_proxy.js as proxy.js)
npm install -g wrangler
wrangler dev proxy.js --port 8080

# Or use any HTTP-to-HTTPS proxy like:
# - nginx with proxy_pass
# - Caddy with reverse_proxy
# - mitmproxy
{
  "stats_enabled": true,
  "stats_proxy_url": "http://192.168.1.100:8080"
}

Priority 3: Direct HTTPS (Not Recommended)

Fetch HTTPS APIs directly on the ESP32. This uses ~30KB extra RAM and may cause mining interruptions or watchdog resets.

{
  "stats_enabled": true,
  "enable_https_stats": true
}

Disable Stats Entirely

If you don't need live stats and want maximum stability:

{
  "stats_enabled": false
}

Configuration Reference

Field Default Description
stats_enabled true Master switch for live stats
stats_api_url - Custom HTTP endpoint (highest priority)
stats_proxy_url - HTTP proxy for HTTPS APIs
enable_https_stats false Direct HTTPS fetching (unstable)

Pool Configuration

Recommended Pools

Pool URL Port Fee Notes
Public Pool public-pool.io 21496 0% Recommended, solo mining
FindMyBlock EU eu.findmyblock.xyz 3335 0% Solo mining, EU server
CKPool Solo solo.ckpool.org 3333 0.5% Solo mining
Braiins Pool stratum.braiins.com 3333 2% Pooled mining

Bitcoin Address Formats

SparkMiner supports all standard Bitcoin address formats:

  • Bech32 (bc1q...) - Native SegWit, lowest fees (recommended)
  • Bech32m (bc1p...) - Taproot addresses
  • P2SH (3...) - SegWit-compatible
  • Legacy (1...) - Original format

Important: Use YOUR OWN wallet address. Never use an exchange deposit address for mining.


Button Controls

The BOOT button (closest to USB-C) provides these actions:

Action Function Notes
Single click Cycle screens Mining → Stats → Clock
Double click Cycle rotation (0°→90°→180°→270°) Rotation saved to NVS
Triple click Toggle color inversion Saved to NVS
Long press (1.5s) Factory reset 3-second countdown, release to cancel
Hold at boot (5s) Factory reset Alternative if UI is unresponsive

Note: Buttons remain responsive during mining thanks to a dedicated FreeRTOS task. If screen timeout is enabled, the first button press wakes the display instead of performing its normal action.


Display Orientation

You can change the screen rotation by double-clicking the BOOT button or setting "rotation" in config.json.

Rotation Orientation USB Position
0 Portrait Right side
1 Landscape Bottom (default)
2 Portrait Left side
3 Landscape Top

Note: Portrait mode has a bottom status bar.


Display Screens

SparkMiner has 3 display screens. Press BOOT to cycle:

Screen 1: Mining Status (Default)

┌─────────────────────────────────┐
│ SparkMiner v2.9     45C  [●][●] │
├─────────────────────────────────┤
│  687.25 KH/s          Shares    │
│                        12/12    │
│ Best     Hashes    Uptime       │
│ 100.0K   47.5M     2h 15m       │
│ Retarget Blocks    Workers      │
│ 45% -2%  0         1.5 MH/s     │
│                                 │
│ Pool: public-pool.io            │
│ Diff: 1000.00      Jobs: 47     │
│ Pool: 50 PH/s      IP: 192.168.x│
└─────────────────────────────────┘

Stats Grid:

  • Best: Best difficulty achieved (lifetime)
  • Hashes: Total hashes computed
  • Uptime: Session uptime
  • Retarget: Difficulty adjustment progress + expected change %
  • Blocks: Solo blocks found
  • Workers: Your combined worker hashrate from pool

Screen 2: Network Stats

Shows BTC price, block height, network hashrate, fees, and your contribution.

Screen 3: Clock

Large time display with mining summary at bottom.

Status Indicators

The display features color-coded indicators for quick health monitoring:

Indicator Green Yellow Red
Temperature <50°C 50-70°C >70°C
WiFi Signal >-60dBm -60 to -75dBm <-75dBm
Pool Latency <100ms 100-300ms >300ms

Performance

Expected Hashrates

Board Device Display Pool Reported Power Notes
ESP32-2432S028 (CYD) ~715-725 KH/s ~715-725 KH/s ~0.5W Pipelined assembly v2
ESP32-S3 (Freenove) ~280 KH/s ~400 KH/s ~0.4W Midstate caching v3
ESP32 Headless ~750 KH/s ~750 KH/s ~0.3W No display overhead

Note: Pool-reported hashrate is typically higher than device display due to share submission timing and pool difficulty adjustments.

Architecture

SparkMiner uses both ESP32 cores efficiently:

  • Core 1 (High Priority, 19): Pipelined hardware SHA-256 mining using direct register access and assembly optimization
  • Core 0 (Low Priority, 1): WiFi, Stratum protocol, display updates, and software SHA-256 backup mining

v2.9.5 Features & Architecture:

  • Job ID Fix: Increased job ID buffer to 32 chars, fixing 100% rejection on some pools.
  • Screen Auto-Off: Configurable screen timeout (30s–5m) with button wake.
  • GPIO LED Status: Headless boards now blink the onboard LED for mining status.
  • WiFi Robustness: Disabled power save, faster reconnect, disconnect reason logging.
  • Display Fix: Clock screen date no longer superimposes on redraw.
  • Stratum Proxy Stats: Pool hashrate, worker hashrate, difficulty adjustment via proxy.
  • Persistent Stats: Lifetime mining history preserved via NVS and SD card backups.
  • Display Support: OLED (SSD1306) and LCD (ILI9341/ST7789) via abstraction layer.
  • Multi-Board Support: ESP32-C3, ESP32-S3, and Headless with LED status.
  • Optimized Core Usage:
    • Core 1: Pipelined assembly SHA-256 (v3) with unrolled loops.
    • Core 0: Network stack, Stratum, and UI management.

Troubleshooting

WiFi Issues

Problem Solution
Won't connect to WiFi Check SSID/password, ensure 2.4GHz network (not 5GHz)
Keeps disconnecting Check serial log for [WIFI] Disconnected, reason: X - WiFi power save is disabled automatically to improve stability with routers that have aggressive WPA rekey
AP mode not appearing Hold BOOT 5s at power-on, or long-press during operation

Display Issues

Problem Solution
White/blank screen Try esp32-2432s028-st7789 environment
Inverted colors Triple-click to toggle, or set invert_colors in config.json
Flickering Reduce SPI frequency in platformio.ini

Mining Issues

Problem Solution
0 H/s hashrate Check pool connection, verify wallet address
Shares rejected Check wallet address format, pool may be down
High reject rate Network latency issue, try different pool
"SHA-PIPE WARNING" Normal during HTTPS requests, doesn't affect mining

Serial Debug

Connect via USB and monitor at 115200 baud:

pio device monitor
# or
screen /dev/ttyUSB0 115200

Building from Source

Prerequisites

  • PlatformIO (CLI or VS Code extension)
  • Python 3.8+
  • Git

DevTool (Recommended)

SparkMiner includes a unified development tool that supports all boards with an interactive menu:

# Interactive menu - select board, build, flash, monitor
devtool.bat              # Windows
python devtool.py        # Cross-platform

# List all supported boards
python devtool.py --help

# Build specific board
python devtool.py build -b cyd-2usb
python devtool.py build -b freenove-s3

# Flash to specific port
python devtool.py flash -b cyd-2usb -p COM5

# Monitor serial output
python devtool.py monitor -p COM5

# All-in-one: build, flash, and monitor
python devtool.py all -b cyd-2usb -p COM5

# Build release firmware for all boards
python devtool.py release

# Flash custom firmware file (opens file browser)
python devtool.py        # Select [F] from menu

ESP32-S3 Note: The Freenove ESP32-S3 requires manual bootloader mode entry:

  1. Hold BOOT button
  2. Press and release RESET button
  3. Release BOOT button
  4. The display will be blank - this is normal in download mode

Manual PlatformIO Commands

# List available environments
pio run --list-targets

# Build specific environment
pio run -e esp32-2432s028-2usb

# Build and upload
pio run -e esp32-2432s028-2usb -t upload

# Clean build
pio run -e esp32-2432s028-2usb -t clean

# Monitor serial output
pio device monitor

Manual Flashing with esptool

If you need to flash manually without PlatformIO:

# ESP32 (CYD boards) - factory bin at 0x0
esptool.py --chip esp32 --port COM3 --baud 921600 \
    write_flash -z --flash-mode dio --flash-freq 40m \
    0x0 cyd-2usb_factory.bin

# ESP32-S3 (Freenove) - factory bin at 0x0
esptool.py --chip esp32s3 --port COM5 --baud 921600 \
    write_flash -z --flash-mode dio --flash-freq 80m \
    0x0 freenove-s3_factory.bin

Project Structure

SparkMiner/
├── src/
│   ├── main.cpp              # Entry point
│   ├── config/               # WiFi & NVS configuration
│   ├── display/              # TFT display driver
│   ├── mining/               # SHA-256 implementations
│   │   ├── miner.cpp         # Mining coordinator
│   │   ├── sha256_hw.cpp     # Hardware SHA (registers)
│   │   └── sha256_pipelined.h # Pipelined assembly
│   ├── stats/                # Live stats & monitoring
│   └── stratum/              # Stratum v1 protocol
├── include/
│   └── board_config.h        # Hardware definitions
├── devtool.py                # Unified build/flash/monitor tool
├── devtool.bat               # Windows launcher
├── devtool.toml              # Board & project configuration
├── platformio.ini            # PlatformIO build settings
└── README.md

FAQ

Q: Will I actually mine a Bitcoin block?

A: Extremely unlikely. At ~700 KH/s vs network ~500 EH/s, your odds per block are about 1 in 10^15. It's like winning the lottery multiple times. But someone has to mine blocks, and it could theoretically be you!

Q: How much electricity does it use?

A: About 0.5W, or 4.4 kWh per year ($0.50-1.00/year in electricity).

Q: Can I mine other cryptocurrencies?

A: No, SparkMiner only supports Bitcoin (SHA-256d). Other coins use different algorithms.

Q: Why is my hashrate lower than expected?

A: Display updates, WiFi activity, and live stats fetching briefly reduce hashrate. The EMA-smoothed display shows average performance.

Q: Do I need an SD card?

A: No, you can configure via the WiFi portal. SD card is just more convenient for headless setup.

Q: Can I use this with a mining pool that pays regularly?

A: Yes, but solo pools like Public Pool only pay if YOU find a block. For regular payouts, use a traditional pool, but the amounts will be negligible.


Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Credits

  • Sneeze - SparkMiner development
  • bmorcelli - Launcher & bootloader magic
  • BitsyMiner - Pipelined SHA-256 assembly inspiration
  • NerdMiner - Stratum protocol reference
  • ESP32 Community - Hardware documentation

License

MIT License - see LICENSE file for details.


Support

If you find a block, consider donating to support development: bc1qkg83n8lek6cwk4mpad9hrvvun7q0u7nlafws9p

About

SparkMiner: A high-performance, open-source ESP32 Bitcoin solo miner. By combining the usability of NerdMinerV2 with the raw speed of BitsyMiner's pipelined assembly, SparkMiner delivers optimized hashrates (~725+ KH/s) to challenge paid firmware alternatives.

Topics

Resources

License

Stars

Watchers

Forks