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

آموزش کامل سنسور BMP280 با ESP32 و Arduino

راهنمای پروژه‌محور BMP280؛ خواندن دیتاشیت، تفاوت تراشه و ماژول، پایه‌ها، I2C، رجیسترها، Oversampling، فیلتر، کد ESP32 و Arduino و عیب‌یابی ارتفاع.

آموزش کامل سنسور BMP280 با ESP32 و Arduino

آموزش سنسور فشار بارومتریک

راه‌اندازی BMP280 با ESP32 و Arduino از دیتاشیت تا پروژه

در این راهنمای پروژه‌محور، تراشه و ماژول BMP280 را از هم تفکیک می‌کنیم، جدول‌های مهم دیتاشیت Bosch را می‌خوانیم، I2C را سیم‌کشی می‌کنیم، فشار و دمای جبران‌شده را با کتابخانه رسمی Adafruit می‌گیریم و خطاهای ارتفاع‌سنجی، نویز و نصب مکانیکی را عیب‌یابی می‌کنیم.

ماژول واقعی Adafruit BMP280 در کنار پایه‌ها و بردبورد
عکس واقعی ماژول Adafruit BMP280؛ اثر lady ada، با مجوز CC BY-SA 3.0، برش و تغییر اندازه برای LCENJ.
فشار کاری300 تا 1100 hPa
تغذیه تراشهVDD: 1.71 تا 3.6V
رابطI2C و SPI سه/چهارسیمه
آدرس I2C0x76 یا 0x77

BMP280 چیست و در چه پروژه‌هایی کاربرد دارد؟

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

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

چطور دیتاشیت BMP280 را درست بخوانیم؟

Operating range

بازه کامل فشار 300 تا 1100 hPa و بازه کاری دما -40 تا +85°C است. عبارت «full accuracy» برای دما به بازه 0 تا +65°C محدود شده؛ بنابراین کنار هر عدد، شرط آزمون را هم بخوانید.

Accuracy و Resolution

دقت مطلق فشار در بازه کاملِ مشخص‌شده برای 0 تا 65°C برابر ±1 hPa است، در حالی که تفکیک‌پذیری خروجی در حالت Ultra High Resolution به 0.0016 hPa می‌رسد. تفکیک‌پذیری ریز به معنی دقت مطلق هم‌اندازه آن نیست.

Relative accuracy

دقت نسبی تیپیک ±0.12 hPa در شرایط درج‌شده دیتاشیت، تقریباً معادل ±1 m تغییر ارتفاع است. این عدد را نباید با دقت مطلق ارتفاع در هر آب‌وهوا یکی دانست.

Typical و Maximum

جریان حالت خواب تیپیک 0.1 µA و حداکثر 0.3 µA ذکر شده، اما جریان پیک اندازه‌گیری فشار تا 1.12 mA می‌رسد. منبع تغذیه و خازن بای‌پس باید پیک را هم پوشش دهند.

پارامتر دیتاشیتمقدارنتیجه عملی
VDD تراشه خام1.71 تا 3.6Vتراشه خام را مستقیم به 5 ولت وصل نکنید.
VDDIO تراشه خام1.2 تا 3.6VPull-up باس I2C باید با دامنه منطقی مجاز هماهنگ باشد.
بازه فشار با دقت کامل300 تا 1100 hPaمناسب فشار جو و ارتفاع نسبی، نه اندازه‌گیری فشار مایع.
شناسه تراشهرجیستر 0xD0، مقدار 0x58پیش از شروع، مدل قطعه را با خواندن ID تأیید کنید.
زمان راه‌اندازی2 msبلافاصله پس از تغذیه، قبل از نخستین ارتباط کمی صبر کنید.
I2C / SPIتا 3.4 MHz / تا 10 MHzسرعت مجاز تراشه با سرعت مناسب ماژول و سیم‌کشی یکسان فرض نشود.

تفاوت تراشه خام با ماژول BMP280

حد ولتاژهای بالا مربوط به خود تراشه است. برد Adafruit BMP280 که در تصویر دیده می‌شود رگولاتور و مدار تغییر سطح دارد و طبق راهنمای سازنده با ورودی و منطق 3 تا 5 ولت کار می‌کند. همه ماژول‌های بازار چنین مداری ندارند؛ وجود پایه‌ای با نام VIN یا ظاهر مشابه، مدرک کافی نیست. پیش از اتصال 5 ولت، شماتیک همان برد یا قطعات رگولاتور و Level Shifter را بررسی کنید.

در طراحی با تراشه خام، Bosch برای VDD و VDDIO خازن 100 nF نزدیک پایه‌ها توصیه می‌کند. پایه CSB برای انتخاب I2C باید به VDDIO وصل باشد. اگر CSB هنگام راه‌اندازی Low تشخیص داده شود، رابط تا Power-on Reset بعدی در حالت SPI قفل می‌شود.

پایه‌ها، آدرس I2C و سیم‌کشی با ESP32 و Arduino

پایه ماژول AdafruitESP32 عمومیArduino Unoتوضیح
VIN3V35V یا 3.3Vاین انتخاب فقط برای برد Adafruit با رگولاتور/Level Shifter مستند است.
GNDGNDGNDزمین مشترک تغذیه و داده
SCKGPIO22 / SCL بردA5 / SCLدر حالت I2C همان خط SCL است.
SDIGPIO21 / SDA بردA4 / SDAدر حالت I2C همان خط SDA است.
CS و SDOطبق ماژولطبق ماژولدر برد Adafruit برای I2C بدون اتصال خارجی رها می‌شوند؛ در تراشه خام نقش آن‌ها متفاوت است.

مستندات Arduino-ESP32 می‌گوید پایه پیش‌فرض به برد وابسته است؛ GPIO21 برای SDA و GPIO22 برای SCL فقط پیش‌فرض برد Generic ESP32 است. در کد، پایه‌ها را صریح با Wire.begin(SDA_PIN, SCL_PIN) تعیین کنید. خطوط I2C به Pull-up نیاز دارند؛ برد آماده ممکن است این مقاومت‌ها را داشته باشد.

در تراشه خام، SDO به GND آدرس هفت‌بیتی 0x76 و SDO به VDDIO آدرس 0x77 می‌دهد و نباید شناور بماند. بسیاری از کتابخانه‌ها یک آدرس را پیش‌فرض می‌گیرند؛ اگر سنسور پیدا نشد، هر دو را اسکن کنید.

رجیسترها، Oversampling، فیلتر و حالت‌های کاری

رجیسترآدرسکاربرد
id0xD0شناسه تراشه؛ مقدار مورد انتظار 0x58
reset0xE0نوشتن 0xB6 برای Soft Reset
status0xF3بیت‌های فعال بودن تبدیل و کپی داده NVM
ctrl_meas0xF4Oversampling فشار و دما و انتخاب Mode
config0xF5زمان Standby، ضریب IIR و SPI سه‌سیمه
press / temp0xF7 تا 0xFCداده خام 20 بیتی فشار و دما

در Sleep تبدیل انجام نمی‌شود. Forced یک بار اندازه‌گیری می‌کند و سپس خودکار به Sleep برمی‌گردد؛ این حالت برای دیتالاگر باتری‌خور مناسب است. Normal چرخه اندازه‌گیری و Standby را تکرار می‌کند. Oversampling بیشتر نویز را کم می‌کند اما زمان تبدیل و مصرف را بالا می‌برد. فیلتر IIR داخلی برای حذف تغییرات کوتاه ناشی از باد یا بسته‌شدن در مفید است، ولی پاسخ واقعی به تغییر سریع فشار را هم کند می‌کند.

راه‌اندازی گام‌به‌گام در Arduino IDE

  1. برد و پورت درست ESP32 یا Arduino را انتخاب کنید.
  2. از Library Manager کتابخانه Adafruit BMP280 Library و وابستگی‌های پیشنهادی آن را نصب کنید.
  3. سیم‌کشی I2C را با زمین مشترک انجام دهید و ولتاژ مجاز همان ماژول را کنترل کنید.
  4. ابتدا اسکنر I2C داخل بسته دانلود را اجرا کنید و وجود 0x76 یا 0x77 را ببینید.
  5. کد اصلی را آپلود و Serial Monitor را روی 115200 baud باز کنید.
  6. فشار سطح دریا را برای مکان و زمان پروژه کالیبره کنید؛ مقدار ثابت عمومی، ارتفاع دقیق تولید نمی‌کند.

کد عملی BMP280 برای ESP32 و Arduino

#include <Wire.h>
#include <Adafruit_BMP280.h>

#if defined(ESP32)
constexpr int SDA_PIN = 21;   // Generic ESP32 only
constexpr int SCL_PIN = 22;   // Generic ESP32 only
#endif
constexpr uint8_t BMP280_ADDRESS = 0x76;
constexpr float SEA_LEVEL_HPA = 1013.25f; // Replace with a local value

Adafruit_BMP280 bmp;

void setup() {
  Serial.begin(115200);
#if defined(ESP32)
  Wire.begin(SDA_PIN, SCL_PIN);
#else
  Wire.begin();
#endif
  Wire.setClock(100000);

  if (!bmp.begin(BMP280_ADDRESS, 0x58)) {
    Serial.println("BMP280 not found; check 0x76/0x77 and wiring");
    while (true) delay(10);
  }

  bmp.setSampling(
    Adafruit_BMP280::MODE_NORMAL,
    Adafruit_BMP280::SAMPLING_X2,
    Adafruit_BMP280::SAMPLING_X16,
    Adafruit_BMP280::FILTER_X16,
    Adafruit_BMP280::STANDBY_MS_500
  );
}

void loop() {
  const float temperatureC = bmp.readTemperature();
  const float pressurePa = bmp.readPressure();
  const float pressureHpa = pressurePa / 100.0f;
  const float altitudeM = bmp.readAltitude(SEA_LEVEL_HPA);

  Serial.print(F("T="));
  Serial.print(temperatureC, 2);
  Serial.print(F(" C | P="));
  Serial.print(pressureHpa, 2);
  Serial.print(F(" hPa | altitude="));
  Serial.print(altitudeM, 2);
  Serial.println(F(" m"));
  delay(1000);
}

شرط کامپایل #if defined(ESP32) باعث می‌شود همین فایل روی ESP32 پایه‌های صریح و روی Arduino Uno پایه‌های سخت‌افزاری I2C یعنی SDA/A4 و SCL/A5 را به‌کار بگیرد. خروجی سریال نیز با Serial.print نوشته شده تا به Serial.printf مخصوص برخی هسته‌ها وابسته نباشد.

تحلیل کد: هر بخش چه کاری انجام می‌دهد؟

  • Wire.begin روی ESP32 باس I2C را با پایه‌های صریح و روی Uno با پایه‌های سخت‌افزاری راه می‌اندازد؛ setClock(100000) نیز سرعت محافظه‌کارانه 100kHz را انتخاب می‌کند.
  • bmp.begin(..., 0x58) هم آدرس را تعیین می‌کند و هم شناسه مورد انتظار BMP280 را کنترل می‌کند؛ به این ترتیب BME280 یا قطعه اشتباه بی‌صدا پذیرفته نمی‌شود.
  • setSampling حالت Normal، Oversampling و IIR را مطابق نمونه رسمی کتابخانه تنظیم می‌کند.
  • readPressure فشار جبران‌شده را بر حسب پاسکال برمی‌گرداند؛ تقسیم بر 100 آن را به هکتوپاسکال تبدیل می‌کند.
  • readAltitude ارتفاع را از نسبت فشار فعلی به فشار سطح دریا تخمین می‌زند. ورودی SEA_LEVEL_HPA باید با داده محلی به‌روز شود.

چرا ارتفاع اشتباه است و چطور آن را کالیبره کنیم؟

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

اگر ارتفاع مرجع محل را دقیق می‌دانید، تابع seaLevelForAltitude در کتابخانه Adafruit می‌تواند فشار معادل سطح دریا را از فشار اندازه‌گیری‌شده و ارتفاع معلوم محاسبه کند. کالیبراسیون را پس از گرم‌شدن سیستم و دور از جریان باد مستقیم انجام دهید.

خطاهای رایج و عیب‌یابی BMP280

نشانهعلت‌های محتملبررسی پیشنهادی
هیچ آدرسی پیدا نمی‌شودSDA/SCL جابه‌جا، زمین مشترک نیست، تغذیه نامناسب، CSB در حالت SPIولتاژ را اندازه بگیرید، اسکنر I2C را اجرا و Power Cycle کنید.
آدرس هست ولی begin شکست می‌خوردآدرس 0x76/0x77 اشتباه یا تراشه BME280/قطعه دیگررجیستر ID در 0xD0 را بخوانید؛ BMP280 باید 0x58 باشد.
فشار پرنویز استOversampling یا IIR کم، تغذیه نویزی، باد مستقیمفیلتر و نمونه‌برداری را متناسب تنظیم و خازن‌ها و جانمایی را بررسی کنید.
ارتفاع چند متر خطا داردفشار سطح دریا ثابت یا قدیمی، تغییر آب‌وهوامرجع محلی هم‌زمان بدهید یا ارتفاع نسبی را گزارش کنید.
دما بالاتر از محیط استگرمای MCU/رگولاتور و خود PCBسنسور را از منابع گرما دور کنید و نرخ نمونه‌برداری را بی‌دلیل بالا نبرید.
خطای تصادفی روی کابلPull-up نامناسب، ظرفیت باس یا EMIکابل را کوتاه، سرعت را کم و شکل موج SDA/SCL را با اسیلوسکوپ بررسی کنید.

نکات طراحی PCB و نصب مکانیکی

  • روی منفذ فلزی سنسور را با چسب، پوشش محافظ یا بدنه محصول مسدود نکنید و برای رسیدن فشار محیط مسیر تهویه در نظر بگیرید.
  • طبق دیتاشیت، حداقل 0.1 mm فضای خالی بالای درپوش فلزی حفظ شود و مایع با قطعه تماس مستقیم نداشته باشد.
  • تابش شدید نور می‌تواند اندازه‌گیری را تحت تأثیر قرار دهد؛ منفذ سنسور را از منبع نوری قوی دور نگه دارید.
  • سنسور را از رگولاتور، پردازنده، نمایشگر و مسیرهای پرجریان که گرما یا تنش مکانیکی می‌سازند فاصله دهید.
  • خازن‌های 100 nF توصیه‌شده را نزدیک VDD و VDDIO قرار دهید و مسیر زمین را کوتاه نگه دارید.
  • برای محصول جدید، علاوه بر مشخصات فنی، وضعیت Not recommended for new designs و جایگزین BMP390 را در BOM ثبت کنید.

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

آدرس درست BMP280 چیست؛ 0x76 یا 0x77؟

هر دو ممکن‌اند. در تراشه خام SDO=GND آدرس 0x76 و SDO=VDDIO آدرس 0x77 می‌دهد. اتصال روی ماژول آماده را با اسکنر I2C مشخص کنید.

آیا BMP280 رطوبت را هم اندازه می‌گیرد؟

خیر. BMP280 فشار و دمای داخلی را اندازه می‌گیرد. برای رطوبت، BME280 یا سنسور رطوبت جداگانه را با توجه به شماره قطعه واقعی انتخاب کنید.

آیا می‌توان ماژول BMP280 را به 5 ولت وصل کرد؟

فقط اگر سازنده همان ماژول وجود رگولاتور و تغییر سطح 5 ولت را مستند کرده باشد. خود تراشه BMP280 حداکثر تغذیه کاری 3.6 ولت دارد.

چرا 1013.25 برای ارتفاع دقیق کافی نیست؟

این عدد مرجع استاندارد است. فشار سطح دریا با آب‌وهوا و زمان تغییر می‌کند؛ برای ارتفاع بهتر باید فشار محلی تصحیح‌شده و به‌روز را وارد کنید.

برای باتری Forced بهتر است یا Normal؟

Forced اجازه می‌دهد یک اندازه‌گیری انجام شود و سنسور خودکار به Sleep برگردد؛ برای نمونه‌برداری آرام معمولاً انتخاب مناسب‌تری است. تنظیم نهایی باید با نرخ، نویز و بودجه توان پروژه سنجیده شود.

منابع دقیق و ادامه مسیر

همه اعداد فنی با Datasheet BMP280، سند BST-BMP280-DS001-26، Revision 1.26 (اکتبر 2021) تطبیق داده شده‌اند. مشخصات برد آماده فقط برای مدل مستند Adafruit بیان شده و به ماژول‌های ناشناس تعمیم داده نشده است.

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

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

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

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