آردوینومتوسط۸ دقیقه مطالعهArduino IDE 2.x / Uno R3

نمایشگر LCD با بک‌پک I2C

وصل‌کردن نمایشگر کاراکتری ۱۶×۲ به آردوینو با بک‌پک I2C و تراشهٔ PCF8574؛ یافتن آدرس I2C با اسکنر، نصب کتابخانهٔ LiquidCrystal_I2C و ساخت کاراکتر سفارشی با فقط ۴ سیم.

آنچه در این درس می‌آموزید

  • کارکرد بک‌پک I2C و تراشهٔ PCF8574 را توضیح دهید
  • آدرس واقعی ماژول را با اسکنر I2C پیدا کنید
  • کتابخانهٔ LiquidCrystal_I2C را نصب و اسکچ نمایشگر را با lcd.init و lcd.backlight بنویسید
  • مشکلات آدرس اشتباه و نور پس‌زمینهٔ خاموش را عیب‌یابی کنید
نویسنده: تیم داکنامه · بازبینی: ۲۰۲۶-۱۰-۳۱
فهرست مطالب

در درس قبل سیم‌کشی نمایشگر ۱۶×۲ را یاد گرفتید و دیدید که حالت ۴ بیتی هم هنوز ۶ سیم سیگنال می‌خواهد. بک‌پک I2C (I2C Backpack) همین درد را حل می‌کند: یک برد کوچک که پشت نمایشگر لحیم می‌شود و کل گفت‌وگو با LCD را روی دو خط داده می‌بَرد؛ نتیجه، فقط ۴ سیم است و جابه‌جایی آسان ماژول در پروژه‌های بعدی.

بک‌پک I2C چیست و چطور کار می‌کند؟

I2C یک گذرگاه ارتباطی دو خطی است: SDA برای داده و SCL برای ساعت. روی برد Uno، این دو خط از پین‌های A4 (SDA) و A5 (SCL) بیرون آمده‌اند. بک‌پک، تراشه‌ای به نام PCF8574 دارد؛ یک گسترش‌دهندهٔ ورودی/خروجی که از طریق I2C کنترل می‌شود و ۸ پین خروجی موازی دارد. این ۸ پین مستقیماً به پین‌های RS، E، RW و D4 تا D7 نمایشگر لحیم شده‌اند. یعنی آردوینو به‌جای سیم‌کشی مستقیم، به PCF8574 می‌گوید «این پین‌ها را HIGH و LOW کن» و تراشه این کار را روی نمایشگر انجام می‌دهد.

هر دستگاه روی گذرگاه I2C یک آدرس عددی دارد. ماژول‌های رایج بک‌پک با آدرس 0x27 یا 0x3F کار می‌کنند، اما آدرس واقعی به تراشهٔ نصب‌شده بستگی دارد و نباید آن را حدس زد؛ در بخش بعدی با اسکنر، آدرس را می‌یابیم. تغذیهٔ ماژول هم از ۵ ولت گرفته می‌شود و تراشهٔ PCF8574 با همان سطح با آردوینو حرف می‌زند؛ پس نگرانی سطح ولتاژ منطقی نیست.

سیم‌کشی: فقط ۴ سیم

Arduino Uno بک‌پک I2C
5V VCC
GND GND
A4 SDA
A5 SCL

نور پس‌زمینه، کنتراست و خطوط دیتا همه از طریق همین ۴ سیم مدیریت می‌شوند. اگر پشت ماژول شما یک پتانسیومتر آبی کوچک هست، همان VO بک‌پک است و کنتراست را مثل قبل با پیچ‌گوشتی تنظیم می‌کنید.

نصب کتابخانهٔ LiquidCrystal_I2C

کتابخانهٔ پیش‌فرض LiquidCrystal برای بک‌پک I2C کار نمی‌کند، چون مسیر داده عوض شده است. نسخهٔ پرکاربرد و استاندارد، کتابخانهٔ LiquidCrystal I2C اثر Frank de Brabander است و از Library Manager نصب می‌شود:

  1. در Arduino IDE از نوار کناری، آیکون Books (مدیریت کتابخانه) را باز کنید.
  2. در کادر جست‌وجو بنویسید LiquidCrystal I2C.
  3. نسخهٔ Frank de Brabander را انتخاب و Install را بزنید.
  4. برای تأیید موفقیت، منوی File > Examples باید مثال‌های این کتابخانه را نشان دهد.

نکتهٔ مهم: چند کتابخانهٔ هم‌نام در Library Manager هست و امضای توابعشان کمی فرق می‌کند. اگر اسکچ این درس را با کتابخانه‌ای دیگر اجرا کنید و خطای کامپایل یا نمایش بی‌معنا گرفتید، اول مطمئن شوید همان کتابخانهٔ Frank de Brabander را انتخاب کرده‌اید.

آدرس ماژول را با اسکنر پیدا کنید

اسکنر I2C یک اسکچ کوتاه است که همهٔ آدرس‌های ممکن را یکی‌یکی صدا می‌زند و آدرس‌هایی که جواب دهند را در Serial Monitor چاپ می‌کند:

i2c-scanner.ino
#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);
  Serial.println("I2C Scanner");
}

void loop() {
  for (byte addr = 8; addr < 120; addr++) {
    Wire.beginTransmission(addr);      // start a probe at this address
    if (Wire.endTransmission() == 0) { // 0 means a device answered
      Serial.print("Found device at 0x");
      Serial.println(addr, HEX);
    }
  }
  Serial.println("Scan done.");
  delay(5000);
}

منطق کد: beginTransmission گفت‌وگو با یک آدرس را آغاز می‌کند و endTransmission وضعیت را برمی‌گرداند؛ مقدار صفر یعنی دستگاهی آن آدرس را پاسخ داده. پس از آپلود، Serial Monitor (با باود 9600) را باز کنید: باید سطری شبیه Found device at 0x27 و سپس Scan done. ببینید. اگر به‌جای 0x27 آدرس دیگری دیدید — مثلاً 0x3F — همان عدد، آدرس واقعی ماژول شماست و در اسکچ اصلی جایگزین می‌کنید.

اسکچ اصلی نمایشگر

lcd-i2c-hello.ino
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);  // address from the scanner, columns, rows

void setup() {
  lcd.init();          // initialize the display and the I2C backpack
  lcd.backlight();     // turn the backlight on
  lcd.setCursor(0, 0);
  lcd.print("Hello, I2C!");
  lcd.setCursor(0, 1);
  lcd.print("DocNameh LCD");
}

void loop() {}

سه تفاوت مهم با درس قبل: اول، سازندهٔ کلاس به‌جای شمارهٔ پین‌ها، آدرس I2C را می‌گیرد. دوم، به‌جای lcd.begin از lcd.init() استفاده می‌شود که هم تراشهٔ PCF8574 و هم کنترلر LCD را راه می‌اندازد. سوم، نور پس‌زمینه خودکار روشن نمی‌شود؛ باید صریحاً lcd.backlight() را صدا بزنید (و برای خاموش‌کردنش lcd.noBacklight()).

توابع آشنای درس قبل اینجا هم کار می‌کنند: setCursor و print و clear همان رفتار را دارند. کاراکتر سفارشی هم بدون تغییر؛ کافی است همان آرایهٔ قلب را تعریف کنید:

cpp
byte heart[8] = {0b00000, 0b01010, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000, 0b00000};
lcd.createChar(0, heart);
lcd.setCursor(7, 1);
lcd.write(byte(0));

رفتار قابل مشاهده: پس از آپلود، سطر اول Hello, I2C! و سطر دوم DocNameh LCD را می‌بینید و قلب سفارشی در ستون ۷ سطر پایین می‌ایستد.

چند دستگاه روی یک گذرگاه

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

نشانه علت رایج راه‌حل
هیچ اتفاقی نمی‌افتد و اسکنر هم چیزی پیدا نمی‌کند سیم‌کشی SDA/SCL جابه‌جاست یا تغذیه وصل نیست A4→SDA و A5→SCL را دوباره چک کنید؛ VCC باید ۵ ولت باشد
اسکنر آدرسی مثل 0x3F می‌دهد ولی نمایشگر کار نمی‌کند آدرس در اسکچ با آدرس واقعی نمی‌خواند همان عدد اسکنر را در سازندهٔ LiquidCrystal_I2C بگذارید؛ آدرس را حدس نزنید
متن هست ولی نور پس‌زمینه خاموش است فراخوان‌نشدن backlight یا باز بودن جامپر نور پس‌زمینه روی بک‌پک lcd.backlight() را در setup() بنویسید؛ جامپر (پد لحیمی) پشت بک‌پک را بررسی کنید
حروف بی‌معنا و تصادفی (garbage) کتابخانهٔ ناهمسان با اسکچ یا آدرس اشتباه همان کتابخانهٔ Frank de Brabander را نصب کنید و آدرس را با اسکنر تأیید کنید
متن تار یا پیدایش نمی‌شود کنتراست ماژول تنظیم نیست پتانسیومتر روی بک‌پک را با پیچ‌گوشتی بچرخانید

تمرین‌ها

تمرین

تمرین ۱ — پیام چشمک‌زن روی نمایشگر I2C

اسکچ اصلی را طوری تغییر دهید که پیام DocNameh سه بار با فاصلهٔ زمانی روشن و خاموش شود: پیام یک ثانیه بماند، یک ثانیه خاموش شود و این چرخه سه بار تکرار شود و بعد برنامه تمام شود. کدام توابع کتابخانه به کار می‌آیند؟

نمایش راه‌حل

برای پاک‌کردن صفحه lcd.clear() و برای تکرار سه‌باره یک حلقهٔ for لازم است؛ کار در setup() انجام می‌شود و loop() خالی می‌ماند:

cpp
void setup() {
  lcd.init();
  lcd.backlight();
  for (int i = 0; i < 3; i++) {
    lcd.setCursor(0, 0);
    lcd.print("DocNameh");
    delay(1000);
    lcd.clear();
    delay(1000);
  }
}

void loop() {}

پس از آپلود، عبارت DocNameh روی سطر اول سه بار ظاهر و ناپدید می‌شود و بعد نمایشگر در حالت خالی می‌ماند.

:::

خلاصه

  • بک‌پک I2C با تراشهٔ PCF8574، گفت‌وگوی موازی با LCD را به دو خط SDA و SCL می‌کاهد؛ روی Uno این دو، پین‌های A4 و A5 هستند.
  • سیم‌کشی کامل فقط ۴ سیم است: VCC، GND، SDA و SCL.
  • آدرس I2C را با اسکنر پیدا کنید؛ آدرس‌های رایج 0x27 و 0x3F هستند ولی حدس‌زدن جای اسکن را نمی‌گیرد.
  • کتابخانهٔ LiquidCrystal I2C از Library Manager نصب می‌شود و راه‌اندازی آن با lcd.init() و lcd.backlight() انجام می‌شود.
  • چند ماژول I2C می‌توانند روی یک جفت سیم مشترک کار کنند، به شرط آدرس‌های متفاوت.

نمایشگرها را تمام کردید؛ در درس بعدی به دنیای حسگرها می‌رویم و با MQ-2، حضور گازهای قابل اشتعال را می‌سنجیم.

منابع و ارجاع‌ها