10kg Beam Load Cell + Amplifier + Raspberry Pico Pi Problem

[ 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:

  1. 2 * Plywoods ( width: 400mm / length: 345mm / thickness: 12mm )
    → for top board and bottom board
  2. 4 * small woods (height: 10mm)
    → for spacers on the bottom board

[ Breadboard & Raspberry Pico Pi & Amplifier & Beam Load Cell Structure ]

  1. Beam Load Cell → Amplifier
    *****I followed the Makerverse Mounting Kit instruction video

    • Red cable → Red
    • Black cable → Black
    • White cable → White
    • Green cable → Green
  2. 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)
  3. 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?

  1. 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!

1 Like

Hey @Yoonji302974 ,

Looks like you are making good progress! I have a few suggestions that may help.

For the screw terminals that don’t hold your wires securely, I would suggest loosening the screws all the way, reinserting the wires and then tightening them back down. Sometimes you can accidentally insert the wires around the sides of the clamping plate inside the connector, which looks like they are correctly in place, but won’t actually be secured.

Another handy tip is to strip back the wires further from the ends so that you can fold/twist/compact the wire strands back onto themselves to give the connector more surface area to clamp onto.

The issues you are describing with inconsistent readings when touching the cables or amplifier board sounds like you may have a loose connection somewhere that is responding to slight movements in the setup. I wouldn’t be surprised if this fixes itself when you solve your issues with the wire connection to the amplifier board. Otherwise, it may be a good idea to check over your whole system and ensure every connection is solid.

Load cells, in general, will perform best when you avoid the upper end of the load rating. For a 10Kg load cell like this one, you will have the most accurate results around or under 5Kg. If you are expecting to have about 2Kg of rocks on your board, the weight of this and the board is probably around the 3Kg mark. This is assuming that your load is evenly applied directly to the top of the load cell, which it likely won’t be.

As the load moves further away from the load cell, the plywood board will act as a lever and multiply the force down on the load cell and have it pick up a larger weight than is actually placed on it.

I think your professor’s suggestion is a good one. For a platform of this size, multiple load cells would be ideal. I would probably try and have a load cell on each corner of the platform and average the readings you get from these four cells.

For the screws that loosen as you go, some blue Loctite on the threads to keep them from wiggling loose may do the trick?

Hope this helps!

1 Like