HX711 với load cell và LCD 1602 bằng MicroPython
Hướng dẫn ESP32 đọc load cell qua HX711 và hiển thị LCD 1602 bằng MicroPython, gồm đấu dây, hiệu chuẩn và xử lý lỗi.
HX711 là bộ chuyển đổi tương tự–số 24 bit tích hợp khuếch đại vi sai, thường dùng để đọc cầu điện trở của load cell. Độ phân giải danh nghĩa 24 bit không đồng nghĩa với độ chính xác 24 bit: kết quả còn phụ thuộc load cell, kết cấu cơ khí, nguồn, nhiễu, nhiệt độ, dây dẫn và quy trình hiệu chuẩn.
1. Nguyên lý đo
Load cell biến đổi lực thành thay đổi rất nhỏ của điện áp vi sai. HX711 khuếch đại tín hiệu này và trả về số đếm thô. Chương trình cần trừ điểm không (tare) và chia cho hệ số hiệu chuẩn để quy đổi sang gam hoặc kilogam:
khối lượng = (số đếm khi có tải − số đếm điểm không) / hệ số hiệu chuẩn
Muốn đo ổn định, cần gá load cell đúng hướng lực, tránh cọ xát cơ khí, chờ hệ thống ổn định nhiệt và hiệu chuẩn bằng quả cân đã biết. Với dải đo rộng hoặc yêu cầu cao, nên kiểm tra nhiều điểm tăng/giảm tải để đánh giá tuyến tính và độ trễ.
2. Đấu nối phần cứng
| Thiết bị | Chân | ESP32 / kết nối |
|---|---|---|
| HX711 | DT/DOUT | GPIO32 |
| HX711 | SCK/CLK | GPIO33 |
| HX711 | VCC, GND | 3V3 và GND |
| Load cell | E+, E−, A+, A− | Nối theo datasheet hoặc nhãn của đúng load cell; màu dây không phải chuẩn chung |
| LCD 1602 I2C | SDA | GPIO21 |
| LCD 1602 I2C | SCL | GPIO22 |
| LCD 1602 I2C | VCC, GND | Theo điện áp module, nối GND chung |
Backpack LCD dùng PCF8574 thường có điện trở kéo lên SDA/SCL theo VCC. Không để bus I2C bị kéo lên 5 V trực tiếp vào ESP32; hãy cấp ở mức tương thích hoặc dùng bộ chuyển mức I2C hai chiều. PCF8574 tiêu chuẩn hỗ trợ I2C 100 kHz, vì vậy ví dụ đặt freq=100000.
3. Chuẩn bị thư viện MicroPython
- Dùng file
hx711_gpio.pytừ thư viện robert-hh/hx711. Constructor nhận thứ tự clock pin trước, data pin sau. - Dùng hai file MicroPython
lcd_api.pyvàmachine_i2c_lcd.pytừ dhylands/python_lcd. Filei2c_lcd.pytrong cùng repo dành cho Linux/smbus, không dùng cho ESP32. - Chép các file thư viện lên ESP32 bằng Thonny hoặc công cụ tương đương trước khi chạy
main.py.
4. Hiệu chuẩn HX711
- Gá load cell hoàn chỉnh, để không tải rồi gọi
tare(). - Đặt quả cân chuẩn có khối lượng đã biết.
- Đọc giá trị sau khi trừ điểm không và tính:
CALIBRATION_FACTOR = counts / known_mass. - Nhập hệ số vào chương trình. Hệ số có thể âm nếu A+ và A− đảo chiều; không dùng trị tuyệt đối để che lỗi đấu dây.
- Kiểm tra lại ở vài mức tải và theo cả chiều tăng/giảm.
Ví dụ lấy hệ số theo đơn vị gam sau khi đã khởi tạo hx:
KNOWN_MASS_G = 500.0
zero = hx.read_average(20) # Không tải
input("Dat qua can 500 g, roi nhan Enter")
loaded = hx.read_average(20) # Có tải chuẩn
counts_per_gram = (loaded - zero) / KNOWN_MASS_G
print("CALIBRATION_FACTOR =", counts_per_gram)
Nếu khối lượng chuẩn nhập bằng kilogam thì hệ số thu được là counts/kg và phần hiển thị cũng phải đổi sang kg. Ví dụ chính bên dưới dùng counts/g và hiển thị đơn vị g.
5. Chương trình mẫu
Đổi CALIBRATION_FACTOR thành hệ số của hệ thống thật trước khi chạy. Giá trị 0 được giữ có chủ ý để chương trình dừng thay vì hiển thị một khối lượng sai.
from machine import Pin, I2C
from time import sleep_ms
from hx711_gpio import HX711
from machine_i2c_lcd import I2cLcd
HX_DOUT_PIN = 32
HX_SCK_PIN = 33
LCD_SDA_PIN = 21
LCD_SCL_PIN = 22
LCD_ADDRESS = 0x27
CALIBRATION_FACTOR = 0.0 # Thay bằng counts trên mỗi đơn vị khối lượng
if not CALIBRATION_FACTOR:
raise ValueError("Can nhap CALIBRATION_FACTOR sau khi hieu chuan")
lcd = None
hx = None
try:
i2c = I2C(
0,
sda=Pin(LCD_SDA_PIN),
scl=Pin(LCD_SCL_PIN),
freq=100000,
)
addresses = i2c.scan()
if LCD_ADDRESS not in addresses:
raise OSError("Khong tim thay LCD tai dia chi 0x%02X" % LCD_ADDRESS)
lcd = I2cLcd(i2c, LCD_ADDRESS, 2, 16)
hx = HX711(
Pin(HX_SCK_PIN, Pin.OUT),
Pin(HX_DOUT_PIN, Pin.IN, pull=Pin.PULL_DOWN),
)
hx.set_scale(CALIBRATION_FACTOR)
hx.set_time_constant(0.1)
lcd.clear()
lcd.putstr("Dang tare...")
hx.tare(20)
lcd.clear()
while True:
mass = hx.get_units()
lcd.move_to(0, 0)
lcd.putstr("Khoi luong: ")
lcd.move_to(0, 1)
lcd.putstr(("%9.2f g" % mass).ljust(16)[:16])
sleep_ms(200)
except OSError as error:
print("HX711/LCD error:", error)
if lcd is not None:
try:
lcd.clear()
lcd.putstr("LOI CAM BIEN")
except OSError:
pass
except KeyboardInterrupt:
print("Dung chuong trinh")
finally:
if hx is not None:
hx.power_down()
6. Xử lý lỗi và cải thiện kết quả
- Số đo trôi: chờ ổn định nhiệt, kiểm tra gá cơ khí, nguồn và dây tín hiệu.
- Nhiễu lớn: rút ngắn dây, tránh dây công suất, kiểm tra mass và tăng lọc nhưng không che mất đáp ứng cần đo.
- Giá trị ngược dấu: kiểm tra A+/A− hoặc giữ hệ số hiệu chuẩn âm nếu hướng lực được định nghĩa như vậy.
- LCD không hiện: quét I2C, xác nhận 0x27/0x3F và đúng thư viện.
- Cần độ chính xác cao: dùng nhiều điểm hiệu chuẩn, kiểm tra creep, hysteresis, nhiệt độ và quá tải; không chỉ tăng số chữ số hiển thị.
Tham khảo thêm bài đo biến dạng bằng strain gauge và LCD 1602 I2C với Arduino Uno.
Xem thêm