[ Materials I bought from Core Electronics ]
/ if I soldered components I will just mark with ‘+’ /
- Raspberry Pi Pico (Without Headers) + Male Pin Header 2.54mm (1 * 40)
→ I soldered all - Makerverse Load Cell Amplifier
→ I soldered all - Makerverse Load Cell Mounting Kit
→ ## But i don’t use this for my project; I will explain below ## - 10kg Beam Load Cell
- Seeed XIAO RP2040 - Supports Arduino, MicroPychon and CircuitPython
→ ## I bought but I don’t know the purpose of this ## - PiicoDev LiPo Expansion Board for Raspberry Pi Pico
→ ## I bought but I don’t know the purpose of this ## - USB 2.0 Cable Type A to Micro B (1m)
[ Materials for baseboard ]
As I attached the drawing above:
- 2 * Plywoods ( width: 400mm / length: 345mm / thickness: 12mm )
→ for top board and bottom board - 4 * small woods (height: 10mm)
→ for spacers on the bottom board
[ Breadboard & Raspberry Pico Pi & Amplifier & Beam Load Cell Structure ]
-
Beam Load Cell → Amplifier
*****I followed the Makerverse Mounting Kit instruction video- Red cable → Red
- Black cable → Black
- White cable → White
- Green cable → Green
-
Amplifier → Raspberry Pico Pi
**** I’ve already followed the structure from the Makerverse Mounting Kit instruction video but Thony (Python) kept giving me irregular numbers so I asked chatGPT to give me another version; which means this structure is different from Makerverse Mounting Kit instruction!- Vcc → 3V3 Out
- Dout → GP2
- Sclk → GP3
- GND → Ground (GND)
-
Code in Thony (Python)
**** This code is what ChatGPT made for me to make this work[main.py]
HX710 → RP2040 robust test with dynamic thresholds (MicroPython)
- Wiring check
- Idle characterization
- Press test
- Noise-robust live “TAP” detector (AND logic + persistence + re-arm)
import machine, utime
---------- PINS ----------
DT = machine.Pin(2, machine.Pin.IN) # HX710 DOUT → GP2SCK = machine.Pin(3, machine.Pin.OUT, value=0) # HX710 SCK → GP3 (idle LOW)
def ready():return DT.value() == 0
def read_raw(timeout_ms=800):t0 = utime.ticks_ms()while not ready():if utime.ticks_diff(utime.ticks_ms(), t0) > timeout_ms:return Nonev = 0for _ in range(24):SCK.value(1); utime.sleep_us(2)v = (v << 1) | DT.value()SCK.value(0); utime.sleep_us(2)# 25th pulse: A,128SCK.value(1); utime.sleep_us(2)SCK.value(0); utime.sleep_us(2)if v & 0x800000: # sign extend (24-bit two’s comp)v |= ~0xFFFFFFreturn v
def sample_n(n=50, delay_ms=20):vals, tout = , 0for _ in range(n):r = read_raw()if r is None:tout += 1else:vals.append(r)utime.sleep_ms(delay_ms)return vals, tout
def mean(xs): return sum(xs)/len(xs) if xs else 0def stats(xs):if not xs: return (0,0,0,0)mn, mx = min(xs), max(xs); mu = mean(xs)s2 = sum((x-mu)**2 for x in xs)/len(xs)try:import math; sd = math.sqrt(s2)except: sd = 0return mn, mx, mu, sd
---------- 1) WIRING ----------
print(“HX710/Pico quick test”)print(“1) Wiring sanity…”)SCK.value(0)vals, timeouts = sample_n(20, 20)if timeouts >= 10:print(“❌ FAIL: Too many timeouts. Check VCC(3V3), GND, DOUT(GP2), SCK(GP3).”)raise SystemExitif not any(v != 0 for v in vals):print(“❌ FAIL: Only zeros. Ensure SCK idles LOW and pins are correct.”)raise SystemExitprint(f"✅ Wiring looks alive. Timeouts={timeouts}, sample_count={len(vals)}")
---------- 2) IDLE NOISE ----------
print(“\n2) Idle noise check… (hands off)”)utime.sleep_ms(800)idle_vals, _ = sample_n(120, 30) # ~3.6si_mn, i_mx, i_mu, i_sd = stats(idle_vals)i_span = i_mx - i_mnprint(f"Idle: min={i_mn}, max={i_mx}, mean≈{int(i_mu)}, std≈{i_sd:.1f}, span={i_span}")if i_span > 2000:print(“⚠️ Big idle span → improve mounting/cable clamp; but we’ll gate it in software.”)
---------- 3) PRESS TEST ----------
print(“\n3) PRESS TEST: When I say ‘PRESS NOW’, press/place a rock and hold ~3s.”)utime.sleep_ms(1000)print(“PRESS NOW…”)press_vals, _ = sample_n(100, 30)p_mn, p_mx, p_mu, p_sd = stats(press_vals)p_span = p_mx - p_mndelta_vs_idle = abs(p_mu - i_mu)print(f"Press: min={p_mn}, max={p_mx}, mean≈{int(p_mu)}, span={p_span}“)print(f"Δ(mean press vs idle) ≈ {int(delta_vs_idle)}”)if delta_vs_idle > 1000 or p_span > 1500:print(“✅ MECHANICAL RESPONSE: GOOD.”)else:print(“❌ MECHANICAL RESPONSE: WEAK. Fix load path/rigidity.”)
---------- 4) LIVE STREAM with robust TAP detection ----------
Derive thresholds from your actual idle:
- diff must beat idle span by margin
- slope must beat a multiple of idle std (converted to cps roughly)
DELTA_ON = max(int(i_span * 1.5), 3000) # absolute movement vs baselineSLOPE_ON = max(int(i_sd * 30), 8000) # counts/sec; raise if still false-tapping
PERSIST_MS = 140 # must stay hot this long to count as TAPREFRACT_MS = 1200 # ignore new taps for 1.2s after a TAPQUIET_MS = 600 # require quiet period to re-arm (prevents drift retriggers)ALPHA = 0.18 # smoothingFOLLOW_DB = DELTA_ON * 0.4 # deadband for baseline followFOLLOW_RATE = 180 # bigger = slower follow
print(“\n4) Live stream (Ctrl+C to stop).”)print(" Thresholds → DELTA_ON:“, DELTA_ON, " SLOPE_ON:”, SLOPE_ON)print(" Watching for (|diff| > DELTA_ON) AND (|slope| > SLOPE_ON) with persistence.")
filt = Nonebase = int(i_mu) # start near idle meanlast_t = utime.ticks_ms()over_since = Nonerefrac_until = 0quiet_since = utime.ticks_ms() # track quiet time for re-arm
def armed(now):# must be past refractory AND have been quiet long enoughreturn (utime.ticks_diff(refrac_until, now) <= 0) and (utime.ticks_diff(now, quiet_since) >= QUIET_MS)
try:while True:r = read_raw()if r is None:print(“timeout”)utime.sleep_ms(30)continue
t = utime.ticks_ms()
dt = max(1, utime.ticks_diff(t, last_t))
last_t = t
if filt is None:
filt = r
prev = filt
# IIR smoothing
filt = int(prev + ALPHA * (r - prev))
diff = filt - base
slope = (filt - prev) * 1000 // dt # counts/sec
# baseline follow only when inside a deadband
if abs(diff) < FOLLOW_DB:
base = base + (filt - base) // FOLLOW_RATE
quiet_since = t # inside deadband = quiet
# trigger logic: BOTH conditions required + persistence + armed
hot = (abs(diff) > DELTA_ON) and (abs(slope) > SLOPE_ON)
if hot and armed(t):
if over_since is None:
over_since = t
if utime.ticks_diff(t, over_since) >= PERSIST_MS:
print("TAP filt:", filt, " base:", base, " slope:", slope, " diff:", diff)
# lock out new taps for a while; re-arm only after quiet period
refrac_until = utime.ticks_add(t, REFRACT_MS)
over_since = None
# snap baseline toward current so long presses don’t cause re-triggers
base = filt
quiet_since = t
else:
over_since = None
# print a lightweight stream line
print("RAW:", filt)
utime.sleep_ms(30)
except KeyboardInterrupt:
print(“\nStopped.”)
** I literally copied and pasted the code from Thony but the code above could seem weird, please bear with me!!
[ PROBLEMS!!! ]
1. The cables from beam load cells keep coming out of the amplifier, even though I tightened hard and almost clamped. Is there any way that I can fix those cables to amplifiers, since I need to keep placing rocks on the top baseboard??
2. Even though I touch top of the beam load cell or press the top board, it doesn’t read well WHILE when i touch amplifier board or the cables from beam load cell, it reads…..(crying)
3. So I ended up putting a small chunk of clay underneath the amplifier board so that it doesn’t move on the breadboard. HOWEVER, is there any recommendations that yous want to give me?
4. I had to use plywoods for the weight measuring baseboard instead of using Makerverse Mounting Kit acrylic plates, since I need to place 5 pieces of real stones; each stones have different weights (approx 500g ~ 2.3kg; in total, its still below 10kg but about 9kg?).
** I need to stack up the rocks each scene on my website; from the lightest stones to the heavier ones one by one
However, I thought the fabric or materials of the plates/boards for the beam load cell ain’t matter. But my professor just told me today that one little 10kg beam load cell wouldn’t have been able to hold 400mm*345mm top plywood.
So he recommended me to buy 3 more 10kg beam load cells and 3 more amplifiers to place each side of the bottom plywood baseboard, what do yous think?
- Everytime I interact with the top plywood baseboard, the screws get loosen and sometimes thony gives me more irregular results, even though I put flat washer & thicker washer (or locker? i forgot the terminology, my apologies…) or sometimes I used split lock washers. I don’t know if i can ask yous this question, but do yous have any recommendations?
** I made sure the top board screws don’t touch the bottom board!
* The reason why I twisted the cables from beam load cell is to make sure it delivers the numbers properly to amplifier and to raspberry pico pi, but if yous have any recommendations, please give me!
If there are anything to buy, I need to buy asap. I hope yous can find my post asap!!
Thank you!




