힘·무게 · 난이도 어려움
로드셀과 HX711 저울을 영점과 보정 계수부터 한 단계씩 맞춰 g 단위로 재기
로드셀은 무게를 받으면 아주 조금 휘는 금속이고 HX711은 그 작은 전압을 24비트 숫자로 바꿔요. DT·SCK 배선과 선 색 확인, 빈 상태로 영점을 잡고 무게를 아는 물건으로 보정 계수를 구하는 두 단계 코드, 값이 흔들리는 이유, 최대 하중을 지키는 탐구를 정리했어요.
이 센서로 무엇을 잴 수 있나
로드셀과 HX711을 함께 쓰면 g 단위로 무게를 재는 저울을 만들 수 있어요. 막대 모양 로드셀은 1kg, 5kg, 20kg처럼 견디는 무게(정격 하중)가 정해져 있고, 보통 몸통에 적혀 있어요. HX711은 로드셀의 아주 작은 신호를 피코가 읽을 수 있는 숫자로 바꾸는 증폭기·ADC 칩이에요.
이 저울로는 물이 증발하며 줄어드는 무게, 화분이 하루 동안 잃는 물의 양, 소금이나 설탕을 정해진 만큼 덜어 내는 일처럼 시간에 따른 무게 변화를 기록할 수 있어요. 시중의 저울과 견주며 "직접 만든 저울은 얼마나 맞을까"를 재는 것도 좋은 탐구예요.
어렵게 느껴지는 까닭은 하나예요. 이 저울은 처음 켰을 때 g을 모르고 숫자만 알아요. 아무것도 없을 때의 숫자(영점)와, 1g이 숫자 몇 칸인지(보정 계수) 두 가지를 우리가 알려 줘야 g이 나와요. 이 글은 그 두 가지를 한 단계씩 정하는 데 집중해요.
원리
로드셀 몸통에는 스트레인 게이지라는 얇은 저항이 붙어 있어요. 금속이 무게를 받아 아주 조금 휘면 게이지가 늘어나거나 줄어들고, 저항이 조금 바뀌어요. 게이지 네 개를 다리처럼 엮은 회로(휘트스톤 브리지)에 E+와 E−로 전압을 걸면, 무게에 비례하는 아주 작은 전압이 A+와 A− 사이에 나와요.
이 전압은 정말 작아요. HX711 데이터시트에 따르면 A 채널을 증폭률 128로 쓸 때, 전원(AVDD)이 5V여도 다 쓸 수 있는 입력 범위가 ±20mV예요. 일반식은 ±0.5 × AVDD ÷ 증폭률이라 3.3V 쪽이면 범위가 더 좁아요. HX711은 이 전압을 24비트 2의 보수 숫자로 바꿔요.
피코와는 선 두 개로 이야기해요. 변환이 끝나면 HX711이 DT(데이터)를 LOW로 내려 알리고, 피코가 SCK(시계)로 펄스를 25~27번 보내면 한 비트씩 내보내요. 25번이면 다음 측정도 A 채널·증폭률 128이에요. 데이터시트는 SCK가 60µs 넘게 HIGH로 머물면 HX711이 절전 상태로 들어간다고 적어요. 그래서 robert-hh 라이브러리는 펄스를 보내는 짧은 순간에 인터럽트를 잠시 막아요.
측정 속도는 RATE 핀에 따라 초당 10번 또는 80번이에요. 10번일 때 전원을 켜거나 채널을 바꾼 뒤 값이 자리 잡기까지 400ms가 걸려요.
g을 구하는 식은 이것뿐이에요.
무게(g) = (지금 숫자 − 영점) ÷ 보정 계수
보정 계수 = (아는 물건을 올린 숫자 − 영점) ÷ 그 물건의 무게(g)
준비물
- 라즈베리파이 피코와 USB 케이블
- HX711 모듈(VCC·GND·DT·SCK, E+·E−·A−·A+ 단자), 막대형 로드셀(1kg 또는 5kg)
- 받침판과 윗판(두꺼운 합판이나 아크릴), 로드셀 구멍에 맞는 나사, 사이띄개(와셔)
- 무게를 아는 물건: 주방 저울로 잰 물건이나, 빈 컵을 올린 뒤 눈금실린더로 붓는 물
- 멀티미터(선 확인용), 탐구용으로 넓이가 다른 그릇
배선
브레드보드 따라 꽂기 순서 (9단계)
- 피코를 브레드보드 가운데 홈에 걸쳐 꽂아요. USB 단자가 왼쪽을 보게 하고, 1번 핀이 f2, 40번 핀이 e2에 들어가요. 다리가 홈 양쪽에 모두 들어갔는지 옆에서 봐요.
- 주황 선: 피코 36번 핀(3V3(OUT)) 옆 칸 a6 → 위쪽 + 줄(3.3V). 이제 이 줄 전체가 3.3V예요.
- 검은 선: 피코 38번 핀(GND) 옆 칸 a4 → 위쪽 − 줄(GND). 이제 이 줄 전체가 GND예요.
- 로드셀 + HX711 무게 꽂기: 다리 VCC · GND · DT · SCK를 위쪽 a24 · a25 · a26 · a27에 차례로 꽂아요. 다리가 브레드보드에 바로 안 들어가면 암-수 점퍼선으로 같은 칸에 이어요.
- 주황 선(3.3V 전원): 로드셀 + HX711 VCC 줄 b24 → 위쪽 + 줄(3.3V)
- 검은 선(GND): 로드셀 + HX711 GND 줄 b25 → 위쪽 − 줄(GND)
- 초록 선(신호): 로드셀 + HX711 DT 줄 b26 → 피코 19번 핀(GP14) 옆 칸 j20
- 초록 선(신호): 로드셀 + HX711 SCK 줄 b27 → 피코 20번 핀(GP15) 옆 칸 j21
- 마지막 확인: ① 위쪽 + 줄(3.3V)과 아래쪽 + 줄(5V)이 서로 이어지지 않았나요? ② 모든 부품의 GND가 − 줄에 이어졌나요? ③ 5V 신호 다리는 저항을 거쳐 피코에 이어졌나요? ④ 긴 브레드보드는 + − 줄이 가운데에서 끊긴 것도 있어요(빨간·파란 선이 끊겨 있으면 짧은 선으로 이어요). ⑤ 그림과 한 칸씩 비교한 뒤 USB를 꽂아요.
| 모듈 핀 | 피코 핀 | 비고 |
|---|---|---|
| VCC | 3V3 (36번) | DT가 3.3V로 나오게 |
| GND | GND (38번) | 피코와 접지를 함께 써요 |
| DT | GP14 (19번) | HX711이 보내는 데이터 |
| SCK | GP15 (20번) | 피코가 보내는 시계 |
| 로드셀 선(흔한 색) | HX711 단자 | 비고 |
|---|---|---|
| 빨강 | E+ | 브리지 전원 + |
| 검정 | E− | 브리지 전원 − |
| 흰색 | A− | 신호 − |
| 초록 | A+ | 신호 + |
데이터시트는 디지털 전원(DVDD)을 마이크로컨트롤러와 같은 전원으로 쓰라고 해요. 그래서 VCC는 3V3에 이어요. VBUS(5V)에 이으면 DT도 5V로 나와 피코 핀에 무리가 가요.
로드셀 선 색은 제품마다 달라요. 위 표는 시나브로 PICO 안내에 적힌 흔한 색이에요. 판매처 자료가 있으면 그 표를 먼저 따르고, 없으면 멀티미터로 확인해요. 전원 쌍(E+·E−)과 신호 쌍(A+·A−)은 각각 짝끼리 잰 저항이 판매처 자료의 입력 저항·출력 저항과 맞아요. A+와 A−를 바꿔 물리면 무게를 올릴 때 숫자가 줄어드는데, 이것은 고장이 아니라 부호만 바뀐 거예요.
로드셀은 이렇게 고정해요.
- 한쪽 끝을 받침판에, 다른 쪽 끝을 윗판에 나사로 고정해요. 두 판은 서로 닿지 않아요.
- 몸통의 화살표가 무게가 누르는 방향(아래)을 보게 해요.
- 로드셀과 판 사이에 사이띄개를 끼워, 가운데 흰 덮개(게이지 자리)가 판에 닿지 않게 해요.
- 나사가 너무 길어 몸통 반대편으로 튀어나오지 않는지 봐요.
코드
라이브러리는 robert-hh/hx711의 hx711_gpio.py(MIT)예요. 시나브로 PICO에서 실행하면 커밋을 고정한 파일을 /lib에 자동으로 넣어요. 다른 편집기라면 저장소의 hx711_gpio.py를 피코의 /lib에 복사해요. 코드는 두 개로 나눴어요. 1단계는 보정 계수를 한 번 구하고, 2단계는 그 계수로 무게를 재요.
1단계 코드: 보정 계수 구하기
from machine import Pin
import time
from hx711_gpio import HX711 # robert-hh/hx711 (MIT)
sck = Pin(15, Pin.OUT) # SCK → GP15 (피코가 보내는 시계)
dt = Pin(14, Pin.IN) # DT → GP14 (HX711이 보내는 데이터)
hx = HX711(sck, dt) # 순서 주의: (시계, 데이터)
KNOWN_G = 200 # 올릴 물건의 실제 무게(g)로 바꿔요
print("1) 판 위를 비우고 손을 떼세요. 5초 뒤 영점을 재요")
time.sleep(5)
offset = hx.read_average(30) # 빈 상태 30번 평균 = 영점
print(f"영점: {offset:.0f}")
print(f"2) {KNOWN_G}g 물건을 판 가운데에 올리고 손을 떼세요. 10초 기다려요")
time.sleep(10)
loaded = hx.read_average(30)
diff = loaded - offset
print(f"DATA: offset={offset:.0f}, loaded={loaded:.0f}, diff={diff:.0f}")
if abs(diff) < 1000:
print("차이가 너무 작아요. 물건을 올렸는지, 로드셀 방향과 선을 확인해요")
else:
scale = diff / KNOWN_G
print(f"보정 계수 SCALE = {scale:.2f} (1g당 칸 수). 2단계 코드에 적어요")
HX711(sck, dt)의 순서는 시계가 먼저예요. README의 생성자도HX711(clock_pin, data_pin, gain=128)이에요. 기본 증폭률 128은 A 채널을 뜻해요.- README 예제는 DT에 내부 풀다운을 켜지만, 피코 2(RP2350)는 내부 풀다운에 알려진 문제(RP2350-E9)가 있어 이 글은 켜지 않았어요.
read_average(30)은 숫자를 30번 읽어 평균을 내요. 초당 10번 재는 모듈이라면 약 3초 걸려요. 영점과 올린 뒤의 숫자를 같은 방법으로 재야 공정해요.- 차이가 1000칸보다 작으면 보정 계수를 만들지 않고 이유를 알려 줘요. 차이가 음수로 나오면 계수도 음수가 되는데, 그대로 써도 무게는 양수로 나와요.
2단계 코드: 무게 재기
from machine import Pin
import time
from hx711_gpio import HX711
sck = Pin(15, Pin.OUT)
dt = Pin(14, Pin.IN)
hx = HX711(sck, dt)
SCALE = 420.0 # 예시 값. 1단계에서 나온 내 값으로 바꿔요
hx.set_scale(SCALE)
print("판 위를 비우세요. 3초 뒤 영점을 잡아요")
time.sleep(3)
hx.tare(30) # 켤 때마다 영점은 새로 잡아요
while True:
vals = []
for i in range(5):
vals.append(hx.get_units()) # get_units() = (값 − 영점) ÷ SCALE
vals.sort()
g = vals[2] # 다섯 번 중 가운데 값
print(f"DATA: weight_g={g:.1f}")
time.sleep(0.5)
tare(30)은 빈 상태 30번 평균을 영점으로 저장해요. 영점은 켤 때마다, 판 위의 그릇을 바꿀 때마다 새로 잡고, 보정 계수는 한 번 구하면 계속 써요.get_units()는 라이브러리 안의 저역 통과 필터를 거친 값이에요. 원본 코드를 보면 새 값이 들어올 때마다 남은 차이의 25%씩 따라가요(time_constant = 0.25). 8번 읽으면 남은 차이가 약 10%, 16번이면 약 1%라서, 초당 10번 재는 모듈은 물건을 올린 뒤 2초쯤 지나야 값이 거의 다 따라와요.- 다섯 번 읽어 가운데 값을 쓰면 가끔 튀는 값에 덜 흔들려요.
값 해석과 보정
처음 저울을 만들 때는 아래 순서를 그대로 따라 해요.
- 켜고 몇 분 기다려요. 2단계 코드를 빈 상태로 돌려
weight_g가 한쪽으로 계속 흘러가는지 봐요. 데이터시트에도 온도에 따른 영점·증폭 변화가 적혀 있어요. 흐름이 멈춘 뒤 시작해요. - 무게를 아는 물건을 준비해요. 주방 저울로 잰 물건이 가장 쉬워요. 저울이 없다면 빈 컵을 판에 올린 채 영점을 잡고, 눈금실린더로 물 200mL를 부어요. 물 1mL는 20℃에서 약 0.998g이라 200mL는 약 199.6g이에요.
- 1단계 코드를 돌려요. 화면 안내대로 비우고, 올리고, 손을 떼요. 판에 손이 닿아 있으면 그 힘까지 숫자에 들어가요.
- SCALE을 적어요. 2단계 코드의
SCALE에 1단계 값을 넣어요. - 다른 무게로 확인해요. 보정에 쓰지 않은 물건(예: 100g, 400g)을 올려 오차가 몇 %인지 봐요. 보정 무게는 앞으로 주로 잴 무게와 비슷한 크기로 고르는 것이 좋아요.
- 기록해요. 보정한 날짜, 로드셀 정격, 보정에 쓴 물건과 SCALE을 기록장에 남겨요(센서 값의 신뢰도).
해상도는 직접 재요. 빈 판에서 weight_g를 50줄 모아 가장 큰 값과 작은 값의 차이를 봐요. 그 폭의 절반이 이 저울이 구별하는 대략의 크기예요. 0.1g 단위로 출력되어도 폭이 2g이라면 2g보다 작은 차이는 믿지 않아요.
같은 물건을 오래 두면 값이 조금씩 움직일 수 있어요. 로드셀 금속과 접착제가 천천히 늘어나는 현상과 온도 변화 때문이에요. 하루 동안 재는 탐구라면 빈 판(또는 무게가 변하지 않는 물건)을 함께 기록해 그 흐름을 빼요.
자주 하는 실수
- 로드셀 양 끝을 모두 받침에 고정하기. 휘지 않으니 숫자가 거의 안 변해요. 한쪽은 받침, 다른 쪽은 윗판이에요.
- 화살표를 거꾸로 두거나 A+·A−를 바꿔 물리기. 무게를 올리면 숫자가 줄어요. 선을 바꾸거나 음수 SCALE을 그대로 써요.
- DT와 SCK를 바꿔 꽂기. 라이브러리가 데이터를 기다리다
OSError를 일으키거나 엉뚱한 숫자가 나와요. 두 출력 핀이 서로 맞물린 상태이니 바로 USB를 뽑고 표대로(GP14 DT, GP15 SCK) 고쳐요. - 영점을 잡는 동안 판을 만지기. 손의 힘이 영점에 들어가 이후 모든 값이 어긋나요.
- 정격 하중보다 무거운 물건을 올리기. 사람이 올라서거나 5kg 로드셀에 무거운 가방을 올리면 금속이 영구히 휘어 다시 보정해도 맞지 않을 수 있어요.
이 센서로 잴 수 있는 탐구
1. 200g으로 맞춘 저울은 다른 무게에서도 맞을까
- 질문: 200g으로 보정한 저울은 50g, 100g, 400g에서 몇 %씩 틀릴까?
- 바꾸는 것: 확인용 물의 양(빈 컵에 50mL, 100mL, 400mL)
- 재는 것: weight_g(g), 참값(물 부피 × 0.998g)과의 오차(%)
- 방법: 빈 컵을 올리고 영점을 잡은 뒤 물을 부어요. 양마다 컵을 비우고 3번 반복해요. 작은 무게에서 오차(%)가 커지는지 봐요.
2. 판 위 놓는 자리에 따라 값이 달라질까
- 질문: 같은 물건을 윗판의 가운데와 네 모서리에 놓으면 weight_g가 얼마나 다를까?
- 바꾸는 것: 놓는 자리(가운데, 앞·뒤·왼쪽·오른쪽 모서리)
- 재는 것: weight_g(g), 가운데와의 차이(g)
- 방법: 판에 자리 표시를 하고 200g 물건을 차례로 옮겨요. 자리마다 3번 재요. 차이가 크다면 판의 크기와 로드셀 고정 방법을 함께 적어요.
3. 컵과 접시의 물은 하루에 몇 g씩 날아갈까
- 질문: 같은 양의 물도 입구가 넓은 그릇에서 더 빨리 증발할까?
- 바꾸는 것: 그릇(컵, 넓은 접시). 물은 각각 100mL
- 재는 것: 10분마다의 weight_g(g), 시간당 줄어든 무게(g/시간)
- 방법: 바람이 없는 같은 자리에서 그릇마다 하루씩 재요. 시작 전에 빈 판을 1시간 기록해 저울 자체의 흐름을 먼저 확인하고, 그 흐름보다 작은 변화는 결론에서 빼요. 피코와 노트북은 물에서 떨어뜨려요.
안전
- 로드셀에 적힌 정격 하중을 넘기지 않아요. 저울 위에 올라서거나 기대지 않아요.
- 나사로 판을 고정할 때 손을 다치지 않게 하고, 판 모서리가 날카로우면 테이프로 감싸요.
- 물을 쓰는 탐구는 쟁반 위에서 하고, 물을 쏟으면 먼저 USB를 뽑아요.
- 직접 만든 저울은 거래나 약 무게처럼 정확해야 하는 곳에 쓰지 않아요.
더 알아보기
- 데이터시트: Avia Semiconductor "HX711 24-Bit Analog-to-Digital Converter for Weigh Scales"(24비트 2의 보수, 증폭률 128·64·32, AVDD 5V에서 ±20mV, 초당 10·80번, 자리 잡는 시간 400ms, 펄스 25~27번, SCK 60µs 절전, 전원 2.6~5.5V, DVDD는 MCU와 같은 전원)
- 라이브러리: robert-hh/hx711(MIT)의
hx711_gpio.py와 README(HX711(clock_pin, data_pin, gain=128),tare(times=15),read_average(),get_units(),set_scale(), 저역 통과time_constant0.25) - 기초 글: 센서 값의 신뢰도, 잴 수 있는 탐구 주제 만들기, 브레드보드 처음 쓰기, 피코 핀 지도
- 함께 쓰는 글: FSR402 압력 센서