PiAxe – Hashrate Below 400 GH/s Target
Warning — Should be addressed soon
Symptoms
- Pool-side hashrate reads consistently `<400 GH/s` averaged over 1+ hours despite the PiAxe being healthy and connected
- `pyminer.py` log shows `accepted share` lines but local `hashrate` field reads `300-390 GH/s` not `~500 GH/s`
- `journalctl -u pyminer -f` shows occasional `BM1366 framing error`, `nonce error`, or `chip response timeout` correlated with low-hashrate windows
- BM1366 heatsink reads `>75 °C` on the top fin under sustained mining (IR thermometer or thermal probe)
- Ambient room temperature `>30 °C` (Canadian summer or unventilated closet)
- PiAxe lives in a closed enclosure, on top of a router, or on carpet - airflow blocked under or around the heatsink
- No active fan on the BM1366 heatsink despite the chip pulling `15-18 W` at target frequency
- `~/piaxe-miner/config.yaml` has `freq` set lower than the platform's documented target (commonly `400 MHz` instead of `485 MHz`)
- Core voltage in config reads `1.20 V` or lower instead of the chip's documented sweet spot near `1.30 V`
- Multimeter shows `12 V` input rail to the PiAxe HAT sagging below `11.5 V` under load (cheap brick or undersized supply)
- Fresh thermal paste has never been applied - chip has been hashing on factory paste for `12+ months`
- Recently `git pull`-ed a newer `piaxe-miner` commit and hashrate dropped - upstream config defaults changed under you
- Pi CPU governor is set to `powersave` or `ondemand` (mini-UART baud rate jitter starves the chip of work)
- Two or more PiAxes in the same room hash similarly low - environmental, not per-unit
Step-by-Step Fix
Capture ground-truth hashrate before changing anything. SSH to the Pi, run `sudo journalctl -u pyminer -f` for 5 minutes minimum, and pull the local `hashrate` field reported by `pyminer.py` per cycle. Open the pool dashboard for the same worker; record the 1-hour average. You need both: local self-reported and pool-reported. If local says `~500 GH/s` but pool says `<400`, you have a stale-share / network problem, not a chip-tune problem - different page (`piaxe-pyminer-stratum-connection-interrupted`). If local AND pool both read `<400`, you have a real throttle and proceed.
Open `~/piaxe-miner/config.yaml` (or whatever your branch calls the config; some forks use `pyminer.cfg`). Find the `freq` and `voltage` keys. Compare against the platform defaults documented in the upstream README - typically `freq: 485` (MHz) and `voltage: 1.30` (V). Some commits ship conservative defaults like `freq: 400` / `voltage: 1.20 V`. If your config is below documented targets, edit to the targets, save, restart `pyminer` with `sudo systemctl restart pyminer`. Re-run step 1's hashrate check after 5 minutes.
Check the Pi CPU governor. Run `cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor`. If it reads `powersave` or `ondemand`, switch to `performance`: `sudo cpufreq-set -g performance` and persist with `echo 'GOVERNOR="performance"' | sudo tee -a /etc/default/cpufrequtils`. Reboot. The Python miner bit-bangs the BM1366 UART; CPU throttling jitters the timing and starves the chip of work - hashrate drops without any visible chip-side symptom.
Probe BM1366 heatsink temperature under load. Use an IR thermometer (a $15 Amazon unit is fine) aimed at the top fin while the chip is hashing. Hold for 30 seconds for a settled reading. Targets: `<70 °C` excellent, `70-75 °C` acceptable, `75-80 °C` is the throttle band, `>80 °C` is hard throttle. If reading is `<70 °C` and hashrate is still low, thermal isn't the issue - skip to step 6. If `>75 °C`, continue.
Reseat the heatsink and refresh thermal paste. Power down completely (unplug Pi USB-C and HAT 12V). Wait 30 seconds. Remove heatsink screws/clips. Lift the heatsink. Wipe old paste off chip and heatsink with `99% IPA` and lint-free wipes - both surfaces clean. Apply a fresh thin layer of `Arctic MX-6` (or `Thermal Grizzly Kryonaut` for premium / hot ambient). Reseat the heatsink with even pressure on all four corners; the contact pressure matters more than the paste choice. Power back up. Re-run step 4 after 15 minutes of sustained hashing.
Add active airflow if there's no fan on the heatsink. A `40 mm` or `60 mm` `12 V` axial fan zip-tied or 3D-printed-bracket-mounted above the heatsink fins drops sustained heatsink temp by `10-15 °C` versus passive. Wire from the same 12V rail. Quiet alternative: run a 12V fan at 5V using a step-down or USB-A trigger - cuts noise, still moves enough air for a single BM1366. Re-measure heatsink temperature after 15 minutes.
Verify the `12 V` rail to the PiAxe HAT under load with a multimeter. Set DC mode, probe the `12 V` input pin or barrel jack while the chip is hashing at full target. Target: `>=11.7 V` sustained. `11.0-11.7 V` = supply sagging, costs `30-80 GH/s`; replace with a `12V/5A` brick. `<11.0 V` = supply is undersized or dying; mandatory replacement. Cross-reference with `piaxe-12v-dc-undervoltage-rpi` if you also see Pi-side undervoltage flags - the same root cause can manifest both ways.
Audit Linux-side bottlenecks with `htop` while hashing. Find the `python3` process running `pyminer.py`. If it's pegged at or above `90% CPU` on one core for sustained intervals, the Python miner is CPU-bound and can't dispatch work fast enough. Confirm CPU governor is `performance` (step 3). If still bound, consider running `pyminer` on a faster Pi (Pi 4 or Pi 5 instead of Pi Zero 2 W) - the older Pis can struggle to keep a `BM1366` at `485 MHz` fed cleanly through Python.
Check for serial-side errors masquerading as hashrate loss. Run `sudo journalctl -u pyminer | grep -iE "framing|nonce|response|timeout" | tail -50`. Count error lines per minute over the last 30 minutes of mining. Healthy: `0-2/min`. Marginal: `5-10/min`. Failing: `>20/min`. Each framing error costs the work the chip computed but the Pi failed to read. Common cause on Pi 3/4/5/Zero 2 W: `/dev/serial0` is pointing at the mini-UART (`ttyS0`) whose baud drifts under CPU load. Fix in the `piaxe-bm1366-serial-communication-error` page (add `dtoverlay=disable-bt` to `config.txt`).
Single-step the frequency / voltage to find this specific chip's silicon-lottery ceiling. Edit `config.yaml`. Set `freq: 460`, `voltage: 1.28 V`. Restart `pyminer`. Wait 5 minutes; record hashrate. Step up: `freq: 470`, `voltage: 1.29 V`; wait. Step up: `freq: 480`, `voltage: 1.30 V`; wait. Step up: `freq: 490`, `voltage: 1.31 V`; wait. Watch the hashrate-vs-frequency curve. The chip plateaus or starts producing framing errors at its silicon-lottery ceiling. Stop at the last clean step - that's your tune. Don't push further; the marginal `5%` isn't worth chip-aging acceleration.
Run a 60-minute stability burn-in at the chosen tune. Let it run uninterrupted. Watch `journalctl -u pyminer -f` and count error events. Watch heatsink temperature (settle, don't oscillate). Watch the pool dashboard's 30-min rolling average. Pass criteria: hashrate `>=475 GH/s`, framing errors `<2/min`, heatsink `<72 °C`. If any axis fails, back the tune off `5 MHz` and `0.01 V` and re-burn-in. PiAxe tunes are not for daily fiddling - settle on one and let it run for weeks.
Pin the working tune. Once you have a stable tune that holds 60 minutes of burn-in, commit `config.yaml` to a private repo (or just save a copy with `cp config.yaml config.yaml.tuned-$(date +%Y-%m-%d).bak`) and record the `piaxe-miner` Git commit (`cd ~/piaxe-miner && git rev-parse HEAD > ~/piaxe-pinned-commit.txt`). The next time `git pull` ships a config-default change that drops your hashrate, you have a known-good fallback you can `git checkout` in 30 seconds.
Add fleet monitoring. Cron job every 15 minutes: append the `pyminer.py` self-reported hashrate (parse from `journalctl` or from `pyminer`'s HTTP status if your fork exposes one) to a CSV. Pipe to a Discord/Telegram webhook if it drops below `400 GH/s` for 3 consecutive samples. For a multi-PiAxe farm, use Prometheus + Grafana via `node_exporter`'s textfile collector, alert on the same threshold per-unit, dashboard the fleet. Catches creeping thermal drift weeks before it becomes a 'PiAxe died' support ticket.
If you operate a multi-PiAxe farm with `>3` units, manage configs with `Ansible` or `ansible-pull`. One git-managed `config.yaml` template per silicon-lottery bin, applied to all units in that bin via a single playbook run. When the upstream `piaxe-miner` ships a default-config regression, you fix it once in your fork and roll it to the whole fleet in two minutes. Per-unit silicon tunes go in host-vars; environmental tunes (summer-vs-winter ambient profiles) go in group-vars. This is the open-source equivalent of an ASIC fleet-management tool, written in YAML over SSH.
Capture sub-millisecond rail transients with an oscilloscope if Tier 1-2 fixes pass but hashrate is still sub-target. Probe the BM1366 12V input pin during pyminer startup and during sustained hashing. Trigger on falling edge below `11.0 V`, single-shot. Burst-current pulls on microsecond timescales can dip the rail below the chip's stable operating point and recover before a multimeter sees it. Capture confirms the supply needs upgrading even though steady-state DC reads fine. Same physics as `piaxe-12v-dc-undervoltage-rpi`, milder severity.
Escalate to D-Central's open-source / pleb-mining queue if Tier 1-3 fixes pass every gate but the chip still won't break `400 GH/s` over a 60-minute burn-in. The BM1366 has likely drifted (silicon-lottery aging, common after `12+` months of 24/7 mining at `~70 °C`). Email D-Central support with: Pi model, `piaxe-miner` commit hash, `config.yaml` contents, last 200 lines of `journalctl -u pyminer`, multimeter rail readings, heatsink temperature log, and any electrical events the kit lived through. Half an hour of preparation saves billable bench time.
Ship the PiAxe to D-Central for chip-replacement bench work if drift is confirmed. Pack the HAT in an anti-static bag, double-box with `3 cm` of foam on every side. Include a printed note: Pi model, OS version, current power topology sketch, the failure mode you observed, the fixes you tried with their results, current heatsink temperature, current rail voltage, current `freq`/`voltage` config. Ship to the D-Central address on the Repair Service page. Ask for the pleb-mining queue. Turnaround `3-7 business days` Canada-wide, `5-10 days` US / international. We return the PiAxe with a printed test report (new chip silicon-lottery ceiling recorded, tune set, 4-hour burn-in pass).
When to Seek Professional Repair
If the steps above do not resolve the issue, or if you are not comfortable performing these repairs yourself, professional service is recommended. Attempting advanced repairs without proper equipment can cause further damage.
Related Error Codes
Still Having Issues?
Our team of Bitcoin Mining Hackers has been repairing ASIC miners since 2016. We have seen it all and fixed it all. Get a professional diagnosis.
