⛏️ Mining Monero on a Pi 5, and what the AI HAT cannot do · ขุด Monero บน Pi 5 กับสิ่งที่ AI HAT ทำไม่ได้ · 用 Pi 5 挖 Monero,以及 AI HAT 做不到的事

The AI HAT+ 2 cannot mine. Its 8 GB is not your Pi's memory. The processor can. This works out what that is worth, with live data. Roughly a baht a day, each way. Three challenges: the solo wait, the payback, and the break-even. · AI HAT+ 2 ขุดไม่ได้ และ 8 GB ของมันก็ไม่ใช่หน่วยความจำของ Pi คุณ ตัวประมวลผลขุดได้ และหน้านี้คำนวณให้ว่ามันคุ้มแค่ไหน ด้วยข้อมูลเครือข่ายและราคาสด ๆ ราวบาทเดียวต่อวัน ทั้งสองทาง พร้อมโจทย์สามข้อ คือเวลารอเมื่อขุดเดี่ยว การคืนทุน และอะไรถึงจะทำให้มันคุ้ม · AI HAT+ 2 挖不了矿,它那 8 GB 也不是你 Pi 的内存。处理器可以,这一页用实时的网络和价格数据算出它值多少。大约一天一泰铢,两边都是。三道题:单独挖要等多久、多久回本、以及要什么条件才成立。

🇬🇧 English

The short answer first. The AI HAT+ 2 cannot mine Monero, and its 8 GB is not your Pi's memory.

The Pi's own processor can, and this page works out exactly what that is worth, with today's numbers.

It comes to about a baht a day, both ways. The interesting part is why the accelerator is no help at all.

🇹🇭 ไทย

ตอบสั้น ๆ ก่อน AI HAT+ 2 ขุด Monero ไม่ได้ และ 8 GB ของมันก็ไม่ใช่หน่วยความจำของ Pi คุณ

ตัวประมวลผลของ Pi เองขุดได้ และหน้านี้จะคำนวณให้ดูว่ามันคุ้มแค่ไหน ด้วยตัวเลขของวันนี้

ผลออกมาราวบาทเดียวต่อวัน ทั้งสองทาง ส่วนที่น่าสนใจคือทำไมตัวเร่งความเร็วถึงช่วยอะไรไม่ได้เลย

🇨🇳 中文

先说短的答案。AI HAT+ 2 挖不了 Monero,它那 8 GB 也不是你 Pi 的内存。

Pi 自己的处理器可以挖,这一页会用今天的数字算清楚它到底值多少。

结果大约是一天一泰铢,两边都是。有意思的是,为什么那个加速器一点忙都帮不上。

What it isมันคืออะไร它是什么Can it mine Monero?ขุด Monero ได้ไหม能挖 Monero 吗
Pi 5 processorตัวประมวลผลของ Pi 5Pi 5 的处理器what: four Cortex-A76 cores, general purposeคืออะไร: สี่คอร์ Cortex-A76 แบบใช้งานทั่วไป是什么:四个 Cortex-A76 核心,通用mines: yes, this is the only part that doesขุดได้: ได้ มีแค่ส่วนนี้ที่ทำได้能挖吗:能,而且只有它能
Pi 5 memory, 8 GBหน่วยความจำ Pi 5 ขนาด 8 GBPi 5 的 8 GB 内存what: ordinary system RAMคืออะไร: แรมของระบบตามปกติ是什么:普通的系统内存mines: it holds the 2 GB table, so yes it helpsขุดได้: ใช้เก็บตาราง 2 GB ได้ จึงช่วยได้จริง能挖吗:能放下那张 2 GB 的表,所以有用
AI HAT+ 2, Hailo-10HAI HAT+ 2 ชิป Hailo-10HAI HAT+ 2,Hailo-10Hwhat: a fixed-function neural acceleratorคืออะไร: ตัวเร่งความเร็วโครงข่ายประสาทแบบตายตัว是什么:一个固定功能的神经加速器mines: no, it cannot run arbitrary codeขุดได้: ไม่ได้ มันรันโค้ดทั่วไปไม่ได้能挖吗:不能,它跑不了任意代码
The HAT's 8 GB8 GB ของ HATHAT 上的 8 GBwhat: the accelerator's own, over PCIeคืออะไร: เป็นของตัวเร่งความเร็วเอง ผ่าน PCIe是什么:加速器自己的,走 PCIemines: no, the processor cannot use itขุดได้: ไม่ได้ ตัวประมวลผลใช้มันไม่ได้能挖吗:不能,处理器用不了它
NOTHING HERE WAS RUN ON A PI. SAY SO UP FRONT. There is no Raspberry Pi on this network. No hashrate here was measured on one. Every script runs anywhere, including on your Pi. The hashrate is something you pass in. The network and price figures are fetched live. Measure your own and rerun. The arithmetic is the point, not my guess. ไม่มี Raspberry Pi อยู่บนเครือข่ายนี้ ดังนั้นไม่มีค่าแฮชเรตไหนในหน้านี้ที่วัดจากเครื่องจริง สคริปต์ทุกตัวรันได้ทุกที่ รวมถึงบน Pi ของคุณ และค่าแฮชเรตเป็นสิ่งที่คุณใส่เข้าไปเอง ส่วนตัวเลขเครือข่ายและราคาดึงสดมา วัดของคุณเองแล้วรันใหม่ การคำนวณคือประเด็น ไม่ใช่การเดาฮาร์ดแวร์ของคุณ 这个网络上没有树莓派,所以这一页上没有任何算力是在真机上测的。每个脚本在哪都能跑,包括你的 Pi 上,算力是你自己传进去的。网络和价格的数字是实时取的。量一下你自己的再跑一遍;重点是这套算术,不是我对你硬件的猜测。

🧩 Tutorial 1 — What can mine, and what cannot · บทที่ 1 — อะไรขุดได้ และอะไรขุดไม่ได้ · 教程 1 —— 什么能挖,什么不能

🇬🇧 English

Monero uses an algorithm called RandomX. It was designed, on purpose, to be bad on everything except an ordinary processor.

Knowing what it wants tells you immediately why the HAT is not invited.

🇹🇭 ไทย

Monero ใช้อัลกอริทึมชื่อ RandomX ซึ่งถูกออกแบบมาโดยตั้งใจให้ทำงานได้แย่กับทุกอย่าง ยกเว้นตัวประมวลผลธรรมดา

พอรู้ว่ามันต้องการอะไร ก็จะเข้าใจทันทีว่าทำไม HAT ถึงไม่ได้ถูกเชิญ

🇨🇳 中文

Monero 用的算法叫 RandomX。它是故意被设计成:除了普通处理器之外,在别的东西上都跑不好。

知道它要什么,你立刻就明白为什么 HAT 没被邀请。

1 What RandomX asks for · RandomX ต้องการอะไร · RandomX 要的是什么

🇬🇧 English

Four things, and your machine either has them or it does not. This script reads all four.

Run it on the Pi. It runs here too, which is how the output below exists.

🇹🇭 ไทย

สี่อย่าง และเครื่องของคุณมีหรือไม่มีก็ว่ากันไป สคริปต์นี้อ่านทั้งสี่อย่างให้

รันบน Pi ได้ และรันที่นี่ก็ได้ ซึ่งเป็นที่มาของผลลัพธ์ข้างล่าง

🇨🇳 中文

四样东西,你的机器要么有要么没有。这个脚本四样都读。

在 Pi 上跑得了,在这儿也跑得了,下面的输出就是这么来的。

📄 NEW FILE · whatis1.py

"""whatis1.py — what does this machine actually offer a RandomX miner?

RandomX is the algorithm Monero uses. It was designed on purpose to run
well on an ordinary processor and badly on anything else. This reads the
four things it cares about, on whatever you run it on.
"""
import os
import platform
import sys
from pathlib import Path

# RandomX keeps a 2 GB table in memory and reads it at random. With room
# for it, the miner runs fast mode. Without, it falls back to light mode,
# which is many times slower.
DATASET_GB = 2.08
sys.stdout.reconfigure(encoding="utf-8")


def cpu_flags():
    """The processor's feature list, where the system will tell us."""
    cpuinfo = Path("/proc/cpuinfo")
    if cpuinfo.exists():
        text = cpuinfo.read_text(encoding="utf-8", errors="replace")
        for line in text.splitlines():
            if line.lower().startswith(("flags", "features")):
                return set(line.split(":", 1)[1].split())
    return set()


def total_ram_gb():
    """How much memory the processor can actually use."""
    pages = getattr(os, "sysconf_names", {}).get("SC_PHYS_PAGES")
    if pages:
        return os.sysconf("SC_PHYS_PAGES") * os.sysconf("SC_PAGE_SIZE") / 1e9
    # Windows has no sysconf. Ask the kernel directly.
    import ctypes

    class Status(ctypes.Structure):
        _fields_ = [("dwLength", ctypes.c_ulong),
                    ("dwMemoryLoad", ctypes.c_ulong),
                    ("ullTotalPhys", ctypes.c_ulonglong),
                    ("ullAvailPhys", ctypes.c_ulonglong),
                    ("ullTotalPageFile", ctypes.c_ulonglong),
                    ("ullAvailPageFile", ctypes.c_ulonglong),
                    ("ullTotalVirtual", ctypes.c_ulonglong),
                    ("ullAvailVirtual", ctypes.c_ulonglong),
                    ("ullAvailExtendedVirtual", ctypes.c_ulonglong)]

    status = Status()
    status.dwLength = ctypes.sizeof(Status)
    ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(status))
    return status.ullTotalPhys / 1e9


def main():
    flags = cpu_flags()
    ram = total_ram_gb()
    cores = os.cpu_count() or 0

    print("machine       ", platform.machine(), "-", platform.system())
    print("cores         ", cores)
    print(f"memory         {ram:.1f} GB")

    # Hardware AES is the single biggest difference. Without it RandomX
    # does the same work in software, several times slower.
    aes = bool(flags & {"aes", "aes_ni", "pmull", "sha2"})
    print("hardware AES  ", "yes" if aes else ("no" if flags else "cannot tell here"))

    print()
    if ram >= DATASET_GB + 1:
        print(f"fast mode      yes, {DATASET_GB} GB table fits with room to spare")
    else:
        print(f"fast mode      no, needs about {DATASET_GB} GB free just for the table")

    # Huge pages let the processor find that table with fewer lookups.
    # On Linux this is a number you can change; it is worth a third more.
    huge = Path("/proc/sys/vm/nr_hugepages")
    if huge.exists():
        print("huge pages    ", huge.read_text().strip(), "(want 1280 or more)")
    else:
        print("huge pages     not a setting on this system")

    print()
    print("What none of this asks about: any accelerator you have plugged in.")
    print("RandomX runs on the processor. There is nowhere else for it to go.")


if __name__ == "__main__":
    main()

🖥️ ON AN ARM64 MACHINE · the same architecture family as a Pi 5

machine        aarch64 - Linux
cores          20
memory         130.7 GB
hardware AES   yes

fast mode      yes, 2.08 GB table fits with room to spare
huge pages     0 (want 1280 or more)

What none of this asks about: any accelerator you have plugged in.
RandomX runs on the processor. There is nowhere else for it to go.
LineWhat it does · ทำอะไร · 做什么
DATASET_GB = 2.08RandomX reads a 2 GB table at random. It has to be in memory.RandomX อ่านตารางขนาด 2 GB แบบสุ่ม มันต้องอยู่ในหน่วยความจำRandomX 会随机读一张 2 GB 的表。它必须在内存里。
aes = bool(flags & {"aes", "aes_ni", "pmull", "sha2"})Hardware AES is the biggest single difference to the speed.AES แบบฮาร์ดแวร์คือสิ่งที่ทำให้ความเร็วต่างกันมากที่สุด硬件 AES 是对速度影响最大的一项。
huge = Path("/proc/sys/vm/nr_hugepages")Huge pages cut the lookups to find that table. Worth a third more.huge pages ลดจำนวนครั้งที่ต้องค้นหาตารางนั้น เพิ่มความเร็วได้ราวหนึ่งในสามhuge pages 能减少查那张表的次数。大约能多三分之一。
RandomX needsRandomX ต้องการRandomX 需要A Pi 5 processorตัวประมวลผล Pi 5Pi 5 的处理器A Hailo-10Hชิป Hailo-10HHailo-10H
to run code chosen at randomรันโค้ดที่ถูกสุ่มเลือก运行随机选出的代码Pi: that is what a processor isPi: นั่นคือหน้าที่ของตัวประมวลผลPi:处理器就是干这个的Hailo: no, it runs compiled graphsHailo: ไม่ได้ มันรันกราฟที่คอมไพล์มาแล้วHailo:不行,它跑的是编译好的图
2 GB of random readsการอ่านแบบสุ่ม 2 GB2 GB 的随机读Pi: yes, from the 8 GBPi: ได้ จาก 8 GB ที่มีPi:可以,从那 8 GB 里Hailo: its memory is for weightsHailo: หน่วยความจำของมันมีไว้เก็บน้ำหนักโมเดลHailo:它的内存是放权重的
floating point and AESเลขทศนิยมและ AES浮点和 AESPi: both, in hardwarePi: มีทั้งคู่ ในระดับฮาร์ดแวร์Pi:都有,硬件级Hailo: INT4 and INT8 onlyHailo: มีแค่ INT4 กับ INT8Hailo:只有 INT4 和 INT8
THE HAT'S 8 GB IS NOT YOUR PI'S 8 GB This is the part worth being clear about. The AI HAT+ 2 carries 8 GB of its own, wired to the Hailo-10H. It is the accelerator's working memory, reached over PCIe. The processor cannot allocate from it. A Pi 5 with 8 GB and this HAT has 8 GB. Not 16. นี่คือส่วนที่ควรพูดให้ชัด AI HAT+ 2 มีหน่วยความจำ 8 GB ของตัวเอง ต่อตรงเข้ากับชิป Hailo-10H มันคือหน่วยความจำใช้งานของตัวเร่งความเร็ว เข้าถึงผ่าน PCIe และตัวประมวลผลขอใช้จากตรงนั้นไม่ได้ Pi 5 ขนาด 8 GB บวก HAT ตัวนี้ คือเครื่องที่มี 8 GB ไม่ใช่ 16 这一点值得说清楚。AI HAT+ 2 自带 8 GB,接在 Hailo-10H 上。那是加速器的工作内存,经 PCIe 访问,处理器没法从里面分配。一台 8 GB 的 Pi 5 加上这个 HAT,是一台有 8 GB 的机器,不是 16。
YOUR TURN
  1. Run it on the Pi. Check fast mode says yes.
  2. If huge pages says 0, that is a third of your speed missing.
  3. sudo sysctl -w vm.nr_hugepages=1280, then run it again.
  4. Notice nothing in the output mentions the HAT. There is nothing to say.
  1. รันบน Pi แล้วเช็กว่า fast mode ขึ้นว่า yes
  2. ถ้า huge pages ขึ้น 0 แปลว่าคุณเสียความเร็วไปราวหนึ่งในสาม
  3. sudo sysctl -w vm.nr_hugepages=1280 แล้วรันใหม่
  4. สังเกตว่าไม่มีอะไรในผลลัพธ์พูดถึง HAT เลย เพราะไม่มีอะไรจะพูด
  1. 在 Pi 上跑。确认 fast mode 是 yes。
  2. 如果 huge pages 是 0,你少了大约三分之一的速度。
  3. sudo sysctl -w vm.nr_hugepages=1280,再跑一次。
  4. 注意输出里没有一句提到 HAT。因为没什么可说的。

💷 Tutorial 2 — The arithmetic · บทที่ 2 — การคำนวณ · 教程 2 —— 算一笔账

🇬🇧 English

Two numbers decide everything: what a hashrate earns, and what the power costs. Both are small.

Fetched live, so this is today's answer and not a forum post from four years ago.

🇹🇭 ไทย

มีสองตัวเลขที่ตัดสินทุกอย่าง คือแฮชเรตหาเงินได้เท่าไหร่ กับค่าไฟเท่าไหร่ ทั้งคู่เล็กมาก

ดึงสดมา นี่จึงเป็นคำตอบของวันนี้ ไม่ใช่โพสต์ในเว็บบอร์ดเมื่อสี่ปีก่อน

🇨🇳 中文

两个数字决定一切:算力赚多少,电费花多少。两个都很小。

实时取的,所以这是今天的答案,不是四年前论坛上的帖子。

2 What it earns, against what it costs · หาได้เท่าไหร่ เทียบกับจ่ายเท่าไหร่ · 赚多少,对上花多少

🇬🇧 English

Your share of the reward is your share of the work. That is the whole of mining economics in one sentence.

The default hashrate here is a guess. Replace it with yours and the answer becomes about your machine.

🇹🇭 ไทย

ส่วนแบ่งรางวัลของคุณคือส่วนแบ่งงานของคุณ นั่นคือเศรษฐศาสตร์ของการขุดทั้งหมดในประโยคเดียว

ค่าแฮชเรตเริ่มต้นตรงนี้เป็นการเดา เปลี่ยนเป็นของคุณแล้วคำตอบจะกลายเป็นเรื่องของเครื่องคุณ

🇨🇳 中文

你能分到的奖励,就是你出的力占多少。挖矿的经济学一句话说完了。

这里默认的算力是猜的。换成你自己的,答案才是关于你机器的。

📄 NEW FILE · money1.py

"""money1.py — what a given hashrate earns, against what the power costs.

Every number that moves is fetched now. Put your own measured hashrate in
and the answer is about your machine, not about a forum post from 2021.
"""
import json
import sys
import urllib.request

NETWORK = "https://localmonero.co/blocks/api/get_stats"
PRICE = "https://api.coingecko.com/api/v3/simple/price?ids=monero&vs_currencies=usd,thb"

# Measure yours with: xmrig --bench=1M
HASHRATE = float(sys.argv[1]) if len(sys.argv) > 1 else 500.0

# A Pi 5 working all four cores. Measure yours with a plug meter; this is
# the number most worth replacing with your own.
WATTS = float(sys.argv[2]) if len(sys.argv) > 2 else 9.0

# Thai household electricity, baht per kilowatt hour.
BAHT_PER_KWH = float(sys.argv[3]) if len(sys.argv) > 3 else 4.5

# Monero aims at one block every two minutes.
BLOCKS_A_DAY = 720
ATOMIC = 1e12

sys.stdout.reconfigure(encoding="utf-8")


def get(url):
    request = urllib.request.Request(url, headers={"User-Agent": "a lesson"})
    with urllib.request.urlopen(request, timeout=30) as response:
        return json.load(response)


def main():
    chain = get(NETWORK)
    price = get(PRICE)["monero"]

    network = chain["hashrate"]
    reward = chain["last_reward"] / ATOMIC

    print(f"network hashrate   {network / 1e9:10.2f} GH/s")
    print(f"block reward       {reward:10.4f} XMR")
    print(f"XMR price          {price['usd']:10.2f} USD   "
          f"{price['thb']:,.0f} THB")
    print(f"your hashrate      {HASHRATE:10.0f} H/s")
    print()

    # Mining is a lottery with tickets in proportion to work done. Over a
    # long enough time your share of the reward is your share of the work.
    share = HASHRATE / network
    xmr_a_day = BLOCKS_A_DAY * reward * share

    baht_a_day = xmr_a_day * price["thb"]
    power_kwh = WATTS * 24 / 1000
    power_baht = power_kwh * BAHT_PER_KWH

    print(f"your share of the network   1 in {1 / share:,.0f}")
    print(f"earns per day               {xmr_a_day:.8f} XMR   "
          f"{baht_a_day:6.2f} baht")
    print(f"electricity per day         {power_kwh:.3f} kWh        "
          f"{power_baht:6.2f} baht   ({WATTS:.0f} W)")
    print()

    net = baht_a_day - power_baht
    word = "makes" if net >= 0 else "loses"
    print(f"so it {word} {abs(net):.2f} baht a day, "
          f"{abs(net) * 365:.0f} baht a year")

    if net < 0:
        # The honest way to put it: how much cheaper would power have to be?
        needed = baht_a_day / power_kwh if power_kwh else 0
        print(f"to break even, electricity would have to cost "
              f"{needed:.2f} baht per kWh")
        print(f"you are paying {BAHT_PER_KWH:.2f}")


if __name__ == "__main__":
    main()

🖥️ WHAT IT PRINTED · live, at 500 H/s and 4.50 baht a unit

network hashrate         6.04 GH/s
block reward           0.6007 XMR
XMR price              556.06 USD   18,610 THB
your hashrate             500 H/s

your share of the network   1 in 12,085,486
earns per day               0.00003579 XMR     0.67 baht
electricity per day         0.216 kWh          0.97 baht   (9 W)

so it loses 0.31 baht a day, 112 baht a year
to break even, electricity would have to cost 3.08 baht per kWh
you are paying 4.50

🇬🇧 English

Run it again at 750 H/s, the optimistic end, and it makes 0.03 baht a day. Ten baht a year.

So the running cost is a coin flip. Whether it wins or loses depends on numbers you have not measured yet.

🇹🇭 ไทย

ลองรันใหม่ที่ 750 H/s ซึ่งเป็นปลายทางที่ดีที่สุด มันจะได้ 0.03 บาทต่อวัน หรือสิบบาทต่อปี

ค่าใช้จ่ายในการเดินเครื่องจึงเป็นเหมือนการโยนหัวก้อย จะได้หรือเสียขึ้นอยู่กับตัวเลขที่คุณยังไม่ได้วัด

🇨🇳 中文

换成乐观的 750 H/s 再跑一次,它一天赚 0.03 泰铢。一年十泰铢。

所以运行成本基本是掷硬币。赢还是输,取决于你还没量过的那些数字。

THE NUMBER THAT IS NOT CLOSE IS THE HARDWARE Running it roughly breaks even. Buying it does not. A Pi 5, this HAT and the bits come to about 250 dollars. At these rates the machine mines that much in 34 years. Challenge 2 does that arithmetic in full. If you already own the hardware, none of that applies. The day rate is the only question. การเดินเครื่องแทบจะเสมอตัว แต่การซื้อไม่ใช่ Pi 5 กับ HAT ตัวนี้และของจิปาถะรอบ ๆ รวมแล้วราว 250 ดอลลาร์ และด้วยอัตราแบบนี้ เครื่องจะขุดได้เท่านั้นในอีก 34 ปี โจทย์ข้อ 2 คำนวณให้ดูเต็ม ๆ ถ้าคุณมีฮาร์ดแวร์อยู่แล้ว เรื่องพวกนั้นไม่เกี่ยว เหลือแค่คำถามว่ารายวันคุ้มไหม 跑起来基本打平。买下来不是。一台 Pi 5、这个 HAT,加上周边,大约 250 美元,按这个速度,这台机器要 34 年才挖得到那么多。第 2 题把这笔账算全。如果硬件你已经有了,那些都不相干,只剩下每天划不划算这一个问题。
YOUR TURN
  1. Run it. Then run it with your own measured hashrate.
  2. Put your real electricity rate in. Check a bill, do not guess.
  3. Measure the watts with a plug meter if you have one.
  4. Whichever way it lands, you now know by how much.
  1. รันดู แล้วรันอีกครั้งด้วยค่าแฮชเรตที่คุณวัดเอง
  2. ใส่ค่าไฟจริงของคุณ ดูจากบิล อย่าเดา
  3. วัดกำลังไฟด้วยมิเตอร์เสียบปลั๊ก ถ้ามี
  4. ไม่ว่าผลจะออกทางไหน ตอนนี้คุณรู้แล้วว่าต่างกันเท่าไหร่
  1. 运行。然后用你自己量到的算力再跑一次。
  2. 填你真实的电价。去看账单,别猜。
  3. 有功率计的话,量一下瓦数。
  4. 不管结果落在哪边,你现在知道差多少了。

3 Actually running it · ลงมือรันจริง · 真的把它跑起来

🇬🇧 English

If you want to do it anyway, and there are good reasons to, this is the setup.

Mine into a pool. Step 4 shows what solo mining on a Pi actually means.

🇹🇭 ไทย

ถ้ายังอยากทำอยู่ดี ซึ่งก็มีเหตุผลดี ๆ อยู่ นี่คือวิธีตั้งค่า

ให้ขุดเข้าพูล ส่วนขั้นที่ 4 จะแสดงว่าการขุดเดี่ยวบน Pi หมายความว่าอะไรจริง ๆ

🇨🇳 中文

如果你还是想做——这有不少正当理由——设置是这样的。

挖进矿池。第 4 步会告诉你在 Pi 上单独挖矿到底意味着什么。

💻 ON THE PI · build the miner, then measure before you commit

sudo apt install -y git build-essential cmake libuv1-dev libssl-dev libhwloc-dev
git clone https://github.com/xmrig/xmrig && cd xmrig
mkdir build && cd build && cmake .. && make -j4

# Huge pages first. Without them you lose about a third.
sudo sysctl -w vm.nr_hugepages=1280

# The number this whole page is waiting for:
./xmrig --bench=1M

📄 NEW FILE · pool.json

{
  "autosave": true,
  "cpu": {
    "enabled": true,
    "huge-pages": true,
    "max-threads-hint": 75,
    "priority": 1
  },
  "opencl": false,
  "cuda": false,
  "randomx": {
    "mode": "fast",
    "1gb-pages": false
  },
  "pools": [
    {
      "url": "pool.supportxmr.com:3333",
      "user": "YOUR_MONERO_ADDRESS",
      "pass": "pi5",
      "keepalive": true,
      "tls": true
    }
  ]
}
LineWhat it does · ทำอะไร · 做什么
"max-threads-hint": 75Three of the four cores. The fourth keeps the Pi answering you.ใช้สามในสี่คอร์ คอร์ที่เหลือไว้ให้ Pi ยังตอบคุณได้四个核用三个。剩下那个让 Pi 还能理你。
"mode": "fast"Uses the 2 GB table. Needs the memory, and is worth it.ใช้ตาราง 2 GB ต้องมีหน่วยความจำพอ และคุ้มค่า用那张 2 GB 的表。要有内存,而且值得。
"opencl": false,There is nothing to offload to. The HAT is not an option here.ไม่มีอะไรให้ส่งงานไปทำ HAT ไม่ใช่ตัวเลือกตรงนี้没有可以卸载过去的东西。HAT 在这儿不是一个选项。
"tls": trueThe pool sees your address either way. Encrypt the link anyway.ยังไงพูลก็เห็นที่อยู่ของคุณ แต่ก็ควรเข้ารหัสการเชื่อมต่ออยู่ดี反正矿池会看到你的地址。链路还是加密的好。
A PI 5 UNDER FULL LOAD FOR MONTHS IS A THERMAL QUESTION RandomX runs every core flat out, continuously. Most Pi projects do not. Without the active cooler it will throttle. A throttled Pi earns less on the same power. Watch it with vcgencmd measure_temp for the first day. RandomX เร่งทุกคอร์เต็มที่ตลอดเวลา ซึ่งไม่เหมือนโปรเจกต์ Pi ส่วนใหญ่ ถ้าไม่มีพัดลมระบายความร้อน มันจะลดความเร็วลง และ Pi ที่ถูกลดความเร็วจะหาได้น้อยลงโดยใช้ไฟเท่าเดิม คอยดูด้วย vcgencmd measure_temp ในวันแรก RandomX 会让每个核心持续满载,这和大多数 Pi 项目不一样。没有主动散热它会降频,而降了频的 Pi 赚得更少、电却照吃。第一天用 vcgencmd measure_temp 盯着它。
YOUR TURN
  1. Build xmrig. Run --bench=1M and write the number down.
  2. Put that number into money1.py.
  3. Only then decide whether to point it at a pool.
  4. If you do, watch the temperature for a day.
  1. บิลด์ xmrig รัน --bench=1M แล้วจดตัวเลขไว้
  2. เอาตัวเลขนั้นใส่ใน money1.py
  3. แล้วค่อยตัดสินใจว่าจะชี้ไปที่พูลไหม
  4. ถ้าทำ ให้เฝ้าดูอุณหภูมิสักวันหนึ่ง
  1. 编译 xmrig。跑 --bench=1M,把数字记下来。
  2. 把那个数字填进 money1.py。
  3. 然后再决定要不要接上矿池。
  4. 要接的话,盯一天温度。

🎯 Tutorial 3 — Three challenges · บทที่ 3 — โจทย์สามข้อ · 教程 3 —— 三道题

🇬🇧 English

All three answer a question with a number instead of an opinion. Every one was run.

🇹🇭 ไทย

ทั้งสามข้อตอบคำถามด้วยตัวเลข ไม่ใช่ความเห็น และทุกข้อถูกรันจริง

🇨🇳 中文

三道题都用数字而不是意见来回答。每一道都跑过。

4 Try first. The answers are folded away. · ลองเองก่อน เฉลยพับซ่อนไว้ · 先自己试。答案折起来放着。

🇬🇧 English

They share the live data from step 2, so your answers will differ from mine by whatever the market did.

🇹🇭 ไทย

ทั้งสามใช้ข้อมูลสดชุดเดียวกับขั้นที่ 2 คำตอบของคุณจึงต่างจากของผมตามที่ตลาดขยับไป

🇨🇳 中文

它们共用第 2 步的实时数据,所以你的答案会因为行情变动而和我的不同。

1How long until you find a block alone? · อีกนานแค่ไหนกว่าจะเจอบล็อกด้วยตัวเอง · 自己挖,多久能挖到一个块?

🇬🇧 English

A pool pays a trickle. Solo pays nothing until it pays everything.

Difficulty is how many tries the whole network expects to need. Divide it by yours.

🇹🇭 ไทย

พูลจ่ายทีละนิด ส่วนการขุดเดี่ยวไม่จ่ายอะไรเลย จนกว่าจะจ่ายทั้งก้อน

ค่าความยากคือจำนวนครั้งที่ทั้งเครือข่ายคาดว่าต้องลอง เอามาหารด้วยของคุณ

🇨🇳 中文

矿池一点一点地付。单独挖则一分不付,直到一次付清。

难度就是整个网络预计要试多少次。拿它除以你的。

Show the answerดูเฉลย看答案

📄 solo1.py

"""solo1.py — challenge 1: how long until you find a block on your own?

Mining into a pool pays you a steady trickle. Mining alone pays nothing
at all until you find a whole block, and then it pays everything. This is
the wait, and it is the number that decides which you should do.
"""
import json
import math
import sys
import urllib.request

NETWORK = "https://localmonero.co/blocks/api/get_stats"
HASHRATE = float(sys.argv[1]) if len(sys.argv) > 1 else 500.0

sys.stdout.reconfigure(encoding="utf-8")


def main():
    request = urllib.request.Request(NETWORK, headers={"User-Agent": "a lesson"})
    with urllib.request.urlopen(request, timeout=30) as response:
        chain = json.load(response)

    difficulty = chain["difficulty"]

    # Difficulty is how many hashes the whole network expects to try per
    # block. Divide by your own rate and you get your own expected wait.
    seconds = difficulty / HASHRATE
    years = seconds / (365.25 * 24 * 3600)

    print(f"difficulty        {difficulty:,}")
    print(f"your hashrate     {HASHRATE:,.0f} H/s")
    print(f"expected wait     {years:,.1f} years")
    print()

    # It is not a countdown. Every attempt is independent, so the chance
    # of having found one by a given date follows this curve.
    print("chance of having found a block by then:")
    for months in (1, 12, 60, 120):
        chance = 1 - math.exp(-(months * 30.4 * 24 * 3600) / seconds)
        label = f"{months} month" + ("s" if months > 1 else "")
        print(f"   after {label:10}  {chance * 100:7.4f}%")

    print()
    print("A pool splits the reward by work done, so you are paid the")
    print("average instead of waiting for the whole thing.")


if __name__ == "__main__":
    main()

🖥️ WHAT IT PRINTED · at 500 H/s

difficulty        725,129,170,594
your hashrate     500 H/s
expected wait     46.0 years

chance of having found a block by then:
   after 1 month      0.1809%
   after 12 months    2.1499%
   after 60 months   10.2970%
   after 120 months  19.5337%
IT IS NOT A COUNTDOWN Forty six years is an average, not a schedule. Every hash is independent. Being ten years in tells you nothing about the next ten. Run the Pi for a decade. There is still a four in five chance of nothing. That is the argument for a pool. สี่สิบหกปีคือค่าเฉลี่ย ไม่ใช่ตารางเวลา ทุกแฮชเป็นอิสระต่อกัน การที่ผ่านไปสิบปีแล้วไม่ได้บอกอะไร เกี่ยวกับสิบปีถัดไปเลย หลังจากเปิด Pi ทิ้งไว้สิบปี ยังมีโอกาสสี่ในห้าที่จะไม่เคยเจอเลย นั่นคือเหตุผลที่ควรใช้พูล 四十六年是平均值,不是时间表。每一次哈希都是独立的,所以已经跑了十年,对接下来的十年没有任何提示。把 Pi 连着开十年之后,仍有五分之四的机会一个都没挖到。这就是该用矿池的理由。

2How long until the hardware pays for itself? · อีกนานแค่ไหนกว่าฮาร์ดแวร์จะคืนทุน · 硬件多久能回本?

🇬🇧 English

Step 2 ignored what the machine cost. Add it, and also ask the question nobody asks.

The same money, spent on the coin directly, buys how much?

🇹🇭 ไทย

ขั้นที่ 2 ไม่ได้นับค่าเครื่อง ใส่เข้าไป แล้วถามคำถามที่ไม่มีใครถามด้วย

เงินก้อนเดียวกัน ถ้าเอาไปซื้อเหรียญตรง ๆ จะได้เท่าไหร่

🇨🇳 中文

第 2 步没算机器的钱。把它加上,再问一个没人问的问题。

同样这笔钱,直接去买币,能买多少?

Show the answerดูเฉลย看答案

📄 payback1.py

"""payback1.py — challenge 2: how long until the hardware pays for itself?

The mining arithmetic in step 4 ignored what the machine cost. This does
not. It also asks the other question: what would the same money have
bought if you had simply used it to buy the coin.
"""
import json
import sys
import urllib.request

NETWORK = "https://localmonero.co/blocks/api/get_stats"
PRICE = "https://api.coingecko.com/api/v3/simple/price?ids=monero&vs_currencies=usd,thb"

# What the parts cost, in US dollars, at list price.
PARTS = {"Raspberry Pi 5, 8GB": 80.0,
         "AI HAT+ 2, 8GB": 130.0,
         "power supply, case, card": 40.0}

HASHRATE = float(sys.argv[1]) if len(sys.argv) > 1 else 500.0
WATTS = float(sys.argv[2]) if len(sys.argv) > 2 else 9.0
BAHT_PER_KWH = 4.5
BLOCKS_A_DAY = 720
ATOMIC = 1e12

sys.stdout.reconfigure(encoding="utf-8")


def get(url):
    request = urllib.request.Request(url, headers={"User-Agent": "a lesson"})
    with urllib.request.urlopen(request, timeout=30) as response:
        return json.load(response)


def main():
    chain = get(NETWORK)
    price = get(PRICE)["monero"]
    baht_per_usd = price["thb"] / price["usd"]

    spent = sum(PARTS.values())
    for what, cost in PARTS.items():
        print(f"  {what:28} {cost:7.2f} USD")
    print(f"  {'total':28} {spent:7.2f} USD  "
          f"= {spent * baht_per_usd:,.0f} baht")
    print()

    share = HASHRATE / chain["hashrate"]
    xmr_a_year = BLOCKS_A_DAY * 365 * (chain["last_reward"] / ATOMIC) * share
    earns = xmr_a_year * price["thb"]
    power = WATTS * 24 * 365 / 1000 * BAHT_PER_KWH
    net = earns - power

    print(f"mines per year    {xmr_a_year:.6f} XMR = {earns:,.0f} baht")
    print(f"power per year    {power:,.0f} baht")
    print(f"net per year      {net:,.0f} baht")
    print()

    if net <= 0:
        print("It never pays for itself. It goes backwards.")
    else:
        print(f"pays for the hardware in {spent * baht_per_usd / net:,.0f} years")

    print()
    # The comparison nobody runs. The money is the same money.
    bought = spent / price["usd"]
    print(f"The same {spent:.0f} USD spent on the coin itself buys "
          f"{bought:.4f} XMR today.")
    if xmr_a_year > 0:
        print(f"The machine mines that much in {bought / xmr_a_year:,.0f} years.")


if __name__ == "__main__":
    main()

🖥️ WHAT IT PRINTED · at list prices, 500 H/s

  Raspberry Pi 5, 8GB            80.00 USD
  AI HAT+ 2, 8GB                130.00 USD
  power supply, case, card       40.00 USD
  total                         250.00 USD  = 8,367 baht

mines per year    0.013062 XMR = 243 baht
power per year    355 baht
net per year      -112 baht

It never pays for itself. It goes backwards.

The same 250 USD spent on the coin itself buys 0.4496 XMR today.
The machine mines that much in 34 years.

🇬🇧 English

Note what is in that parts list. The HAT is more than half the cost and contributes nothing.

Take it out and the same page reads very differently.

🇹🇭 ไทย

ดูรายการอะไหล่ให้ดี HAT คิดเป็นมากกว่าครึ่งของราคา และไม่ได้ช่วยอะไรเลย

เอามันออก แล้วหน้าเดียวกันนี้จะอ่านได้ต่างไปมาก

🇨🇳 中文

看看那张零件清单。HAT 占了一半以上的成本,而且一点贡献都没有。

把它去掉,同一页读起来就很不一样。

3What would have to be true? · อะไรถึงจะทำให้มันคุ้ม · 要什么条件才成立?

🇬🇧 English

Instead of arguing about whether it is worth it, solve for the number.

Four things could change. Ask what each would have to become, with the others left alone.

🇹🇭 ไทย

แทนที่จะเถียงกันว่าคุ้มหรือไม่คุ้ม ให้แก้สมการหาตัวเลข

มีสี่อย่างที่เปลี่ยนได้ ลองถามว่าแต่ละอย่างต้องกลายเป็นเท่าไหร่ โดยที่อย่างอื่นอยู่เฉย ๆ

🇨🇳 中文

与其争论值不值,不如把那个数解出来。

有四样东西可以变。问问每一样得变成多少,其余不动。

Show the answerดูเฉลย看答案

📄 breakeven1.py

"""breakeven1.py — challenge 3: what would have to be true for this to pay?

Rather than arguing about whether it is worth it, solve for the number.
Three of the four things are fixed by the world. Ask what each one would
have to become, with the others left alone.
"""
import json
import sys
import urllib.request

NETWORK = "https://localmonero.co/blocks/api/get_stats"
PRICE = "https://api.coingecko.com/api/v3/simple/price?ids=monero&vs_currencies=usd,thb"

HASHRATE = 500.0
WATTS = 9.0
BAHT_PER_KWH = 4.5
BLOCKS_A_DAY = 720
ATOMIC = 1e12

sys.stdout.reconfigure(encoding="utf-8")


def get(url):
    request = urllib.request.Request(url, headers={"User-Agent": "a lesson"})
    with urllib.request.urlopen(request, timeout=30) as response:
        return json.load(response)


def main():
    chain = get(NETWORK)
    price = get(PRICE)["monero"]
    network, reward = chain["hashrate"], chain["last_reward"] / ATOMIC

    power_a_day = WATTS * 24 / 1000 * BAHT_PER_KWH
    earns_per_hash = BLOCKS_A_DAY * reward * price["thb"] / network
    earns_a_day = HASHRATE * earns_per_hash

    print(f"as things stand      earns {earns_a_day:.2f} baht a day, "
          f"power costs {power_a_day:.2f}")
    print()

    # Each of these leaves everything else exactly where it is.
    need_hashrate = power_a_day / earns_per_hash
    print(f"hashrate needed      {need_hashrate:,.0f} H/s   "
          f"({need_hashrate / HASHRATE:.1f} times a Pi 5)")

    xmr_a_day = BLOCKS_A_DAY * reward * (HASHRATE / network)
    need_price = power_a_day / xmr_a_day
    print(f"XMR price needed     {need_price:,.0f} baht   "
          f"({need_price / price['thb']:.1f} times today)")

    need_power = earns_a_day / (WATTS * 24 / 1000)
    print(f"electricity needed   {need_power:.2f} baht per kWh   "
          f"(you pay {BAHT_PER_KWH:.2f})")

    need_watts = earns_a_day / (24 / 1000 * BAHT_PER_KWH)
    print(f"or the same work at  {need_watts:.1f} W   "
          f"(a Pi 5 under load draws about {WATTS:.0f})")

    print()
    print("None of those four is a small change. That is the answer.")


if __name__ == "__main__":
    main()

🖥️ WHAT IT PRINTED · all four, from the same live data

as things stand      earns 0.67 baht a day, power costs 0.97

hashrate needed      729 H/s   (1.5 times a Pi 5)
XMR price needed     27,162 baht   (1.5 times today)
electricity needed   3.09 baht per kWh   (you pay 4.50)
or the same work at  6.2 W   (a Pi 5 under load draws about 9)

🇬🇧 English

Those are all half-steps, not orders of magnitude. Running a Pi at these numbers is genuinely marginal.

Which is the honest answer, and a more useful one than either yes or no.

🇹🇭 ไทย

ทั้งหมดนั้นคือครึ่งก้าว ไม่ใช่ต่างกันเป็นเท่าตัวหลายเท่า การเดิน Pi ที่ตัวเลขแบบนี้ก้ำกึ่งจริง ๆ

ซึ่งคือคำตอบที่ซื่อตรง และมีประโยชน์กว่าการตอบว่าใช่หรือไม่

🇨🇳 中文

这些都是半步之差,不是数量级的差距。在这样的数字下跑一台 Pi,确实是边缘状态。

这才是诚实的答案,也比一句「行」或「不行」更有用。

🇬🇧 English

Six files, and the useful one is the arithmetic. Mining is a lottery with tickets priced in electricity.

The HAT cannot buy tickets. It is a good piece of hardware doing something else entirely, and there are pages here about that.

A Pi 5 with 8 GB and a Hailo-10H will run a small language model locally. That is what you bought.

🇹🇭 ไทย

หกไฟล์ และไฟล์ที่มีประโยชน์คือการคำนวณ การขุดคือลอตเตอรีที่ราคาตั๋วคิดเป็นค่าไฟ

HAT ซื้อตั๋วไม่ได้ มันเป็นฮาร์ดแวร์ที่ดีซึ่งทำอย่างอื่นไปเลย และมีหน้าอื่นในเว็บนี้ที่พูดถึงเรื่องนั้น

Pi 5 ขนาด 8 GB กับ Hailo-10H รันโมเดลภาษาเล็ก ๆ ในเครื่องได้ นั่นคือสิ่งที่คุณซื้อมา

🇨🇳 中文

六个文件,有用的是那套算术。挖矿是一场彩票,票价用电费结算。

HAT 买不了票。它是一块好硬件,只是在做完全另一件事,这个站上有别的页面讲那个。

一台 8 GB 的 Pi 5 配 Hailo-10H,能在本地跑一个小的语言模型。那才是你买的东西。

You wantคุณอยากได้你想要Look upไปหาคำว่า去查
What the HAT is forHAT มีไว้ทำอะไรHAT 是干嘛的Hailo runs 1 to 1.5 billion parameter modelsHailo รันโมเดลขนาด 1 ถึง 1.5 พันล้านพารามิเตอร์Hailo 能跑 10 到 15 亿参数的模型
Your own measured hashrateแฮชเรตที่คุณวัดเอง你自己量到的算力xmrig --bench=1M
Mining something elseขุดอย่างอื่น挖点别的the same arithmetic, different constantsการคำนวณแบบเดียวกัน แค่เปลี่ยนค่าคงที่同一套算术,换几个常数
Whether it is legal where you areมันถูกกฎหมายที่คุณอยู่ไหม在你那儿合不合法mining your own hardware usually is. Check anywayการขุดด้วยเครื่องของตัวเองมักจะได้ แต่ก็ควรตรวจสอบ用自己的硬件挖通常可以。还是查一下

Fifteen lines, your own address, and an app password. That is the whole trick. · สิบห้าบรรทัด อีเมลของคุณเอง และ app password หนึ่งอัน เคล็ดลับมีแค่นี้ · 十五行代码、你自己的邮箱地址,加一个应用专用密码。诀窍就这些。

All six files on this page were run on 26 September 2026, and the network and price figures in every output were fetched live at that moment. One thing was not run: there is no Raspberry Pi on this network, so no hashrate here was measured on real Pi hardware. 500 H/s is an assumption, sitting between a measured Pi 4B at 100 to 120 H/s and a Rock 5B, which uses the same Cortex-A76 cores, at about 728. Every script takes the hashrate as an argument for that reason. The capability check in step 1 was run on an arm64 Linux machine, which is the same architecture family as a Pi 5 and reads the same flags. The hardware claims come from Raspberry Pi's own announcement: the AI HAT+ 2 is a Hailo-10H with 8 GB of dedicated on-board RAM, 40 TOPS at INT4, for 130 dollars, and it is a fixed-function neural accelerator that cannot run arbitrary code. That is why it cannot run RandomX, and why its memory is not available to the processor.