فشار، وزن و جریان

ساخت ترازو با لودسل و HX711؛ آموزش ESP32 و آردوینو

ساخت ترازو با لودسل و HX711: سیم‌کشی ESP32 و آردوینو، کالیبراسیون با جرم معلوم، کد نمونه، عیب‌یابی و لینک خرید در ایران.

ساخت ترازو با لودسل و HX711؛ آموزش ESP32 و آردوینو

پروژه سنجش وزن • لودسل و HX711 • ESP32 / Arduino

از تغییر شکل لودسل تا عدد وزن

برای ساخت یک ترازوی رومیزی، خواندن عدد خام کافی نیست: نصب مکانیکی، سیم‌بندی پل، تغذیه و کالیبراسیون باید کنار هم درست باشند. در این آموزش یک لودسل چهار سیمه را با HX711 می‌خوانیم، صفر و ضریب تبدیل را با جرم مرجع تعیین می‌کنیم و خطاهای رایج را قدم‌به‌قدم جدا می‌کنیم.

این پروژه برای نمونه‌سازی ترازو، پایش مقدار مواد و آموزش ابزار دقیق است؛ دقت تضمین‌شده یا تأییدیه ترازوی تجاری ندارد.

نمای واقعی ماژول Adafruit HX711 با ترمینال لودسل، پایه‌های DATA و SCK و کلید انتخاب نرخ نمونه‌برداری
عکس واقعی نسخه Adafruit؛ چیدمان آن با بردهای عمومی بازار یکسان نیست. تصویر: Liz Clark / Adafruit، CC BY-SA 3.0؛ تغییر اندازه متناسب، حاشیه‌گذاری و تبدیل به WebP بدون برش. تصویر مشتق با همین مجوز ارائه می‌شود.

۱. این پروژه کجا به کار می‌آید؟

در یک نمونه اولیه می‌توان جرم قطعات کوچک روی سینی، تغییر مقدار مواد داخل یک ظرف سبک یا تکرارپذیری یک سازوکار توزین را ثبت کرد. اگر هدف فروش محصول است، اول بازه بار، خطای مجاز، شرایط دمایی و روش نصب را مشخص کنید؛ بعد ظرفیت لودسل را انتخاب کنید. اضافه کردن چند رقم اعشار به نمایشگر جای این مرحله را نمی‌گیرد.

دلیل انتخاب این موضوع برای بازار ایران فقط نام آشنا نیست: ماژول HX711 و لودسل مکمل در ECA عرضه می‌شوند و صفحه ماژول پرسش‌های دارای نشان خریدار درباره راه‌اندازی با ESP32 دارد. این نشانه کاربرد و تقاضاست، نه آمار فروش یا تضمین مشتری. لینک دقیق و تاریخ بررسی پایین مقاله آمده است.

۲. لودسل و HX711 چه تفاوتی دارند؟

لودسل تغییر شکل مکانیکی را به تغییر سیگنال الکتریکی پل تبدیل می‌کند. HX711 خودِ حسگر وزن نیست؛ تقویت‌کننده و مبدل آنالوگ به دیجیتال برای خواندن سیگنال کوچک پل است. خروجی آن ابتدا یک عدد خام است و برای تبدیل به گرم به صفر و ضریب کالیبراسیون نیاز داریم.

زنجیره پروژه چنین است: بار روی سازه → لودسل → ورودی تفاضلی HX711 → عدد خام → کالیبراسیون → جرم تخمینی. خرابی یا خطای هر مرحله می‌تواند نتیجه نهایی را تغییر دهد. دسته فشار، وزن و جریان را برای ادامه این مسیر ببینید.

۳. چند مشخصه ضروری از دیتاشیت

مشخصه تراشهمقدارنتیجه برای پروژه
خروجی ADC۲۴ بیت علامت‌دارتعداد بیت، دقت تضمین‌شده ترازو نیست.
بهره ورودیA: ۱۲۸ یا ۶۴؛ B: ۳۲کد این مقاله کانال A و بهره ۱۲۸ را به کار می‌برد.
نرخ خروجی با نوسان‌ساز داخلی۱۰ یا ۸۰ نمونه در ثانیهپایه RATE تعیین‌کننده است؛ همه ماژول‌ها کلید ندارند.
زمان نشست خروجی۴۰۰ میلی‌ثانیه در ۱۰ SPS؛ ۵۰ در ۸۰ SPSپس از روشن‌شدن یا تغییر تنظیمات، خروجی فوراً پایدار نیست.

مرجع: دیتاشیت HX711، شرکت AVIA، نسخه ۲، جدول‌های ۱ تا ۳. مشخصات تراشه را با ظرفیت و دقت لودسل یا کیفیت برد فروشگاهی یکی نگیرید.

۴. وسایل لازم و انتخاب ظرفیت

  • برد ESP32 یا Arduino Uno، یک ماژول HX711 و سیم‌های کوتاه.
  • لودسل چهار سیمه با پل کامل، ظرفیت مناسب و اطلاعات سیم‌بندی معتبر.
  • پایه و سینی محکم، پیچ و فاصله‌دهنده متناسب با نقشه مکانیکی حسگر.
  • جرم مرجع معلوم برای کالیبراسیون و چند جرم دیگر برای کنترل نتیجه.
  • مولتی‌متر برای بررسی اتصال‌ها و ولتاژها پیش از اتصال پایه‌های داده.

وزن خود سینی هم بخشی از بار مکانیکی است؛ صفر کردن نرم‌افزاری آن را از ظرفیت فیزیکی حذف نمی‌کند. این متن ظرفیت یا حد اضافه‌بار تازه‌ای برای حسگر تعیین نمی‌کند. لودسل سه سیمه نیم‌پل را هم نباید بدون ساخت پل مناسب، جای نمونه چهار سیمه فرض کرد.

۵. تغذیه؛ حساس‌ترین نکته اتصال به ESP32

ابتدا شماتیک و نوشته‌های همان ماژول را بررسی کنید. برای نمونه سازگار با ۳٫۳ ولت، تغذیه و منطق HX711 را با ESP32 هم‌سطح نگه دارید. در Uno می‌توان از ماژول سازگار با ۵ ولت استفاده کرد. در بردهایی با تغذیه آنالوگ و دیجیتال جدا، هر پایه وظیفه خودش را دارد؛ VIN، VCC و VIO الزاماً مترادف نیستند.

خروجی DATA با سطح ۵ ولت را مستقیم به ESP32 وصل نکنید. اگر ماژول یا لودسل به تحریک بالاتر نیاز دارد، بردی با تغذیه دیجیتال مستقل و شماتیک روشن انتخاب کنید؛ صرفاً جابه‌جا کردن سیم VCC راه‌حل مطمئنی نیست.

روی بعضی بردهای عمومی، رگولاتور تحریک لودسل با ورودی ۳٫۳ ولت به ولتاژ نامی خودش نمی‌رسد. بنابراین هم ولتاژ E+ نسبت به E− و هم سازگاری آن با لودسل را کنترل کنید. راهنمای پایه‌های نسخه Adafruit یک مثال مستند است، نه نقشه همه بردهای بازار.

۶. سیم‌کشی HX711 به لودسل و میکروکنترلر

پایه ماژولESP32 در این کدArduino Uno در این کدنکته
VCC / VIN۳V۳ برای ماژول سازگار۵V برای ماژول سازگارشرایط بخش تغذیه را اول بررسی کنید.
GNDGNDGNDزمین مشترک
DOUT / DT / DATAGPIO19D2خروجی داده از HX711
PD_SCK / SCKGPIO18D3کلاک از میکروکنترلر
E+ و E−تحریک مثبت و منفی لودسلمطابق سند همان حسگر
A+ و A−خروجی سیگنال مثبت و منفی پلکانال مورد استفاده این برنامه

این شماره‌ها انتخاب نرم‌افزاری مثال‌اند؛ روی ESP32-S3، بردهای خاص یا بردی که پایه‌ها مصرف دیگری دارند، پایه آزاد مناسب انتخاب و ثابت‌های ابتدای کد را اصلاح کنید. رنگ سیم‌ها استاندارد همگانی نیست. اگر تنها راهنمای شما یک عکس مشابه است، قبل از روشن‌کردن اطلاعات مدل واقعی را پیدا کنید.

۷. HX711، I2C نیست

دو خط DATA و SCK به معنی I2C نیستند؛ این تراشه آدرس I2C ندارد و اسکنر I2C آن را پیدا نمی‌کند. پروتکل اختصاصی آن خروجی ۲۴ بیتی و پالس‌های انتخاب کانال و بهره دارد. بالا ماندن PD_SCK بیش از ۶۰ میکروثانیه، تراشه را وارد حالت کم‌مصرف می‌کند؛ نوشتن درایور بدون توجه به زمان‌بندی می‌تواند خواندن را مختل کند.

در این پروژه از کتابخانه bogde/HX711 نسخه ۰٫۷٫۵ استفاده می‌کنیم. پیش از هر خواندن، آماده‌شدن داده را با مهلت محدود بررسی می‌کنیم تا نبود ماژول به انتظار بی‌پایان در مرحله آماده‌شدن منجر نشود. فقط همین حلقه برنامه باید مسئول خواندن ADC باشد.

۸. نصب مکانیکی قبل از کالیبراسیون

برای لودسل تیرکی تک‌نقطه‌ای، طبق نقشه سازنده یک سمت روی پایه و سمت دیگر به سینی متصل می‌شود و ناحیه تغییر شکل باید آزاد بماند. این روش را به همه شکل‌های لودسل تعمیم ندهید. تماس سینی با بدنه، کابل کشیده، پیچ نامناسب یا بار خارج از محل تعیین‌شده می‌تواند بخشی از نیرو را از مسیر حسگر خارج کند.

آزمون اولیه را با بار کم و کنترل‌شده انجام دهید؛ با فشار دست یا ضربه، ظرفیت ایمن معلوم نمی‌شود. قبل از تغییر سیم‌بندی، تغذیه را قطع کنید. اگر ماژول داغ شد، ادامه آزمایش با روشن‌وخاموش کردن مکرر مناسب نیست؛ اتصال کوتاه و قطبیت تغذیه را بررسی کنید.

۹. صفر و کالیبراسیون با جرم معلوم

  1. سازه را کامل ببندید و بدون بار، پایداری عدد خام را مشاهده کنید.
  2. با سینی خالی فرمان t بفرستید. میانگین خام به عنوان صفر ثبت می‌شود.
  3. جرم مرجع معلوم را قرار دهید و پس از سکون، فرمانی مانند c 500 بفرستید؛ فقط اگر جرم مرجع واقعاً ۵۰۰ گرم است.
  4. جرم را بردارید؛ بازگشت به صفر را بررسی کنید. سپس با جرم‌های دیگر و چند بار برداشتن و گذاشتن، خطا را بسنجید.
countsPerGram = (rawKnown - rawZero) / knownMassGrams
massGrams = (rawNow - rawZero) / countsPerGram

ضریب منفی الزاماً خطا نیست؛ جهت سیگنال پل می‌تواند علامت را عوض کند. ضریب نمونه اینترنتی را کپی نکنید. صفر کردن خطای ضریب را اصلاح نمی‌کند و کالیبراسیون تک‌نقطه‌ای هم به‌تنهایی خطی‌بودن کل بازه را اثبات نمی‌کند.

۱۰. کد کالیبراسیون و خواندن وزن

کتابخانه HX711 با نویسنده bogde را نصب کنید؛ نسخه مبنای این مثال ۰٫۷٫۵ است. Serial Monitor را روی ۱۱۵۲۰۰ و پایان خط Newline تنظیم کنید. برنامه عمداً در شروع خودکار صفر نمی‌کند تا بار موجود روی سینی پنهان نشود. ابتدا فقط عدد خام نمایش داده می‌شود.

#include <Arduino.h>
#include <HX711.h>  // bogde/HX711 0.7.5
#include <math.h>
#include <stdlib.h>
#include <string.h>

#if defined(ARDUINO_ARCH_ESP32)
const uint8_t DATA_PIN = 19, CLOCK_PIN = 18;
#else
const uint8_t DATA_PIN = 2, CLOCK_PIN = 3; // Arduino Uno
#endif

HX711 adc;
double zeroRaw = 0, countsPerGram = 0;
bool zeroValid = false, calibrated = false;
char line[48];
uint8_t used = 0;
bool overflowed = false;
unsigned long lastReport = 0;

// Each sample has its own timeout. One task owns the ADC.
bool averageRaw(uint8_t count, double &value) {
  int64_t sum = 0;
  for (uint8_t i = 0; i < count; ++i) {
    if (!adc.wait_ready_timeout(1200, 1)) {
      Serial.println(F("ERROR: HX711 timeout; check power / DATA / SCK."));
      return false;
    }
    long raw = adc.read();
    if (raw == 8388607L || raw == -8388608L) {
      Serial.println(F("ERROR: ADC saturated; check bridge wiring / load."));
      return false;
    }
    sum += raw;
  }
  value = (double)sum / count;
  return true;
}

void command(char *text) {
  double raw;
  if (strcmp(text, "t") == 0) {
    Serial.println(F("Tare: keep platform empty and still..."));
    if (averageRaw(20, raw)) {
      zeroRaw = raw;
      zeroValid = true;
      Serial.print(F("zeroRaw=")); Serial.println(zeroRaw, 2);
    }
  } else if (text[0] == 'c' && text[1] == ' ') {
    char *end;
    double grams = strtod(text + 2, &end);
    while (*end == ' ') ++end;
    if (!zeroValid || end == text + 2 || *end != '\0' ||
        !isfinite(grams) || grams <= 0) {
      Serial.println(F("First send t empty; then c <known mass in grams>."));
      return;
    }
    Serial.println(F("Calibration: keep known mass still..."));
    if (!averageRaw(20, raw)) return;
    double factor = (raw - zeroRaw) / grams;
    if (!isfinite(factor) || fabs(factor) < 0.000001) {
      Serial.println(F("ERROR: no useful span; check known load / wiring."));
      return;
    }
    countsPerGram = factor; // Negative sign is legitimate.
    calibrated = true;
    Serial.print(F("countsPerGram=")); Serial.println(countsPerGram, 6);
    Serial.println(F("Verify with OTHER known masses; not saved after reset."));
  } else if (strcmp(text, "p") == 0) {
    Serial.print(F("zeroRaw=")); Serial.println(zeroRaw, 2);
    Serial.print(F("countsPerGram=")); Serial.println(countsPerGram, 6);
    Serial.print(F("calibrated=")); Serial.println(calibrated);
  } else {
    Serial.println(F("Commands: t (empty tare), c 500 (known 500 g), p"));
  }
}

void setup() {
  Serial.begin(115200);
  adc.begin(DATA_PIN, CLOCK_PIN, 128); // Channel A, gain 128
  delay(500);
  Serial.println(F("HX711: no automatic tare. Send t only with EMPTY platform."));
  Serial.println(F("Then place a known mass and send c <grams>; newline enabled."));
}

void loop() {
  while (Serial.available()) {
    char ch = (char)Serial.read();
    if (ch == '\r') continue;
    if (ch == '\n') {
      line[used] = '\0';
      if (overflowed) Serial.println(F("ERROR: command too long."));
      else if (used) command(line);
      used = 0;
      overflowed = false;
    } else if (used < sizeof(line) - 1 && !overflowed) {
      line[used++] = ch;
    } else overflowed = true;
  }
  if (millis() - lastReport >= 1000) {
    double raw;
    if (averageRaw(5, raw)) {
      Serial.print(F("raw=")); Serial.print(raw, 1);
      if (calibrated) {
        Serial.print(F("  grams="));
        Serial.print((raw - zeroRaw) / countsPerGram, 1);
      } else Serial.print(F("  NOT CALIBRATED"));
      Serial.println();
    }
    lastReport = millis();
  }
}

فرمان p پارامترها را چاپ می‌کند. کالیبراسیون این مثال پس از ریست ذخیره نمی‌ماند؛ در محصول نهایی ذخیره‌سازی معتبر، کنترل بازه بار و سیاست صفر کردن لازم است. خواندن میانگین و فرمان کالیبراسیون چند تبدیل زمان می‌برد؛ این حلقه برای کنترل بلادرنگ موتور طراحی نشده است.

دانلود مثال کامل و برنامه تشخیص داده خام. هر فایل ino را در پوشه مستقل هم‌نام خودش قرار دهید. کدها برای Uno و ESP32 کامپایل شده‌اند؛ آزمایش روی سخت‌افزار فیزیکی انجام نشده است.

۱۱. نویز، دقت و آزمون قابل تکرار

اول عدد خام را با سینی خالی، سپس با جرم ثابت ثبت کنید. دامنه تغییرات، برگشت به صفر و تفاوت قرائت در نقاط مختلف سینی را جداگانه یادداشت کنید. اگر جابه‌جایی محل بار نتیجه را عوض می‌کند، قبل از افزایش میانگین‌گیری، سراغ مکانیک بروید.

سیم سیگنال را کوتاه و دور از مسیر موتور، رله و مبدل سوئیچینگ نگه دارید. برای بررسی منشأ اختلال، مصرف‌کننده‌های مزاحم را موقتاً از پروژه آزمایشی جدا و همان آزمون را تکرار کنید. میانگین‌گیری بیشتر ممکن است خروجی را آرام‌تر کند، اما پاسخ را کند می‌کند و خطای مکانیکی یا ضریب غلط را حذف نمی‌کند.

برای ثبت اثر دما می‌توانید مسیر سنجش دما با DS18B20 را اضافه کنید؛ صرف ثبت دما به معنی جبران‌سازی خودکار خطای وزن نیست.

۱۲. عیب‌یابی بر اساس نشانه

نشانهبررسی اولاقدام بعدی
TIMEOUTتغذیه، زمین مشترک، شماره DATA/SCKشماتیک برد و وضعیت کلاک را کنترل کنید؛ اسکن I2C کاربرد ندارد.
SATURATEDسیم‌های پل، اتصال A و E، بار واردشدهبار را ایمن بردارید؛ اشباع را با ضریب نرم‌افزاری پنهان نکنید.
با بار عدد تغییر نمی‌کندمسیر انتقال نیرو و اتصال پلبرنامه خام را اجرا کنید و تماس سینی با بدنه را بررسی کنید.
پس از برداشتن بار صفر برنمی‌گرددگیر مکانیکی، ناپایداری و تغییر شرایطچند چرخه بارگذاری کنترل‌شده ثبت کنید؛ دائماً صفر نکنید.
وزن چند برابر یا با علامت غلط استواحد جرم مرجع و ضریبکالیبراسیون را با جرم معلوم تکرار کنید؛ علامت را بی‌دلیل حذف نکنید.
اعشار زیاد ولی نتیجه ناپایدارکیفیت نصب و دامنه نویز واقعیتفکیک نمایش را متناسب با آزمون واقعی انتخاب کنید.

۱۳. خرید در ایران؛ ماژول را با لودسل اشتباه نگیرید

بررسی در : دو صفحه زیر وضعیت موجود و امکان افزودن به سبد خرید نشان می‌دادند. موجودی ممکن است تغییر کند؛ مشخصات نسخه ارسالی، ولتاژ، پایه‌ها و ظرفیت را هنگام سفارش دوباره کنترل کنید. قیمت ثابت درج نشده است.

وجود سؤال‌های خریداران در صفحه ماژول نشانه استفاده عملی است، اما تعداد نظرها را معادل تعداد فروش یا تضمین تقاضا نمی‌گیریم. توضیح پروتکل و مقادیر الکتریکی این آموزش از اسناد سازنده گرفته شده، نه متن تبلیغاتی فروشگاه.

۱۴. پرسش‌های متداول

آیا HX711 از I2C استفاده می‌کند؟

خیر. رابط آن دو سیمه اختصاصی با DATA و PD_SCK است و آدرس I2C ندارد؛ اسکنر I2C برای پیدا کردن آن مناسب نیست.

آیا خروجی ۲۴ بیتی یعنی دقت میلی‌گرم؟

خیر. دقت نهایی به لودسل، ظرفیت، مکانیک، نویز و کالیبراسیون وابسته است و باید با جرم‌های مرجع آزمایش شود.

برای ESP32 می‌توان ماژول را با ۵ ولت تغذیه کرد؟

تنها اگر طراحی همان برد سطح دیجیتال سازگار با ۳٫۳ ولت را تضمین کند. خروجی DATA پنج‌ولتی نباید مستقیم به ESP32 متصل شود.

چرا ضریب کالیبراسیون منفی است؟

جهت سیگنال پل می‌تواند ضریب را منفی کند. اگر جرم‌های مرجع درست خوانده می‌شوند، منفی بودن ضریب به‌تنهایی ایراد نیست.

آیا با ریست کالیبراسیون حفظ می‌شود؟

در مثال این مقاله خیر. پس از ریست باید دوباره صفر و کالیبراسیون انجام شود؛ ذخیره پارامترها در حافظه پایدار مرحله توسعه جداگانه است.

۱۵. ادامه پروژه و منابع

برای ساخت سامانه ثبت چندحسگری، سنجش نور با BH1750 یا فشار هوا با BMP280 را به مسیر وزن اضافه کنید؛ تفاوت رابط این حسگرهای I2C با HX711 را حفظ کنید. مرور پایه‌ها از راهنمای سنسورها و دوره سنسورها در ۷ قدم در دسترس است.

متن و مثال پروژه: LCENJ. کامپایل نرم‌افزاری جای آزمون فیزیکی، کالیبراسیون قابل ردیابی یا ارزیابی یک محصول نهایی را نمی‌گیرد.

پرسش و پاسخ مقاله

سوال فنی خود را مطرح کنید

پرسش‌ها و پاسخ‌ها پس از بررسی مدیر منتشر می‌شوند. نویسنده، پیش‌نویس در انتظار بررسی را می‌بیند.

هنوز پرسش تاییدشده‌ای برای این مقاله ثبت نشده است.