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

ماژول بلوتوث HC-05

ماژول بلوتوث HC-05 را به آردوینو وصل می‌کنید و با SoftwareSerial از راه دور و بدون کابل، LED را با یک اپلیکیشن ترمینال بلوتوث کنترل می‌کنید.

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

  • تفاوت بلوتوث کلاسیک (Classic) و BLE را توضیح دهید و بدانید HC-05 به کدام گروه تعلق دارد
  • پین‌های HC-05 را بشناسید و تفاوت ولتاژ تغذیه و ولتاژ منطقی را در سیم‌کشی رعایت کنید
  • با SoftwareSerial یک پل ارتباطی میان گوشی و آردوینو بسازید و با فرمان متنی LED را کنترل کنید
نویسنده: تیم داکنامه · بازبینی: ۲۰۲۶-۱۰-۳۱
فهرست مطالب

تا حالا برای فرمان‌دادن به برد همیشه از کابل USB استفاده کرده‌اید؛ ولی پروژهٔ واقعی که در اتاق دیگر یا داخل جعبه نصب شده باشد چطور؟ ماژول بلوتوث HC-05 همین مشکل را حل می‌کند: یک پیوند بی‌سیم دوطرفه میان گوشی یا رایانه و آردوینو، در برد حدود ۱۰ متر. با چند خط کد و کتابخانهٔ SoftwareSerial — که در درس ارتباط سریال با مفهومش آشنا شده‌اید — برد شما بی‌سیم می‌شود. این درس کامل‌ترین ماژول سری «بی‌سیم» است؛ با دقت بخوانید، چون درس بعدی (تنظیمات AT) مستقیماً روی آن سوار می‌شود.

بلوتوث کلاسیک یا BLE؟

«بلوتوث» یک نام خانوادگی است، نه یک فناوری واحد. دو شاخهٔ اصلی آن را از هم تشخیص دهید:

ویژگی بلوتوث کلاسیک (Classic) بلوتوث کم‌مصرف (BLE)
مصرف انرژی بیشتر بسیار کم؛ مناسب باتری
ارتباط داده جریان پیوستهٔ داده (مثل پورت سریال مجازی SPP) بسته‌های کوتاه مشخصه‌محور (GATT)
کاربرد نمونه پخش صدا، ترمینال دادهٔ پیوسته سنسورهای پوشیدنی، برچسب‌ها
ماژول نمونه HC-05 HM-10

HC-05 چیپ BC417 را دارد و روی بلوتوث کلاسیک نسخهٔ 2.0 کار می‌کند؛ یعنی مثل یک کابل سریال بی‌سیم رفتار می‌کند و برای جریان پیوستهٔ متن عالی است. ماژول HM-10 با چیپ CC2541 از خانوادهٔ BLE است و با اسکچ و اپلیکیشن‌های همین درس سازگار نیست. پیش از خرید، نام ماژول را چک کنید؛ بسیاری از عیب‌یابی‌های اینترنتی از همین اشتباه ساده شروع می‌شود.

پین‌های ماژول HC-05

نمونهٔ رایج بازشکن (Breakout) HC-05 شش پین دارد:

پین نام کامل نقش
EN / KEY Enable / Key ورود به حالت فرمان (AT)؛ در حالت عادی آزاد گذاشته می‌شود
VCC تغذیه ورودی تغذیهٔ 3.6 تا 6 ولت (روی بازشکن با رگولاتور)
GND زمین اتصال به زمین مشترک با آردوینو
TXD ارسال داده خروجی سریال ماژول — به RX آردوینو می‌رود
RXD دریافت داده ورودی سریال ماژول — از TX آردوینو می‌گیرد
STATE وضعیت خروجی؛ هنگام اتصال بلوتوث روشن (HIGH) می‌شود

تغذیه و سطح ولتاژ منطقی — نکتهٔ حیاتی

اینجا پرتکرارترین اشتباهِ آسیب‌زنندهٔ این ماژول است، پس دو مفهوم را جدا کنید:

  • ولتاژ تغذیه (VCC): بازشکن رایج HC-05 روی برد خودش رگولاتور دارد و با 3.6 تا 6 ولت تغذیه می‌شود؛ پس اتصال VCC به پین 5V آردوینو بلامانع است.
  • ولتاژ منطقی (TXD/RXD): خودِ چیپ با 3.3 ولت کار می‌کند. خروجی TXD ماژول حدود 3.3 ولت است که آردوینو آن را درست می‌خواند، اما پین TX آردوینو با 5 ولت حرف می‌زند و ورودی RXD ماژول برای این ولتاژ ساخته نشده است.

پس خط آردوینو ← ماژول باید با یک مقسوم ولتاژ (Voltage Divider) از دو مقاومت پایین آورده شود. خروجی این مدار از رابطهٔ Vout = 5 × R2 / (R1 + R2) به‌دست می‌آید؛ با R1 برابر ۱ کیلواهم و R2 برابر ۲ کیلواهم، ولتاژ RXD به حدود 3.3 ولت می‌رسد:

cpp
// Voltage divider: Arduino TX -- R1 (1k) --+-- R2 (2k) -- GND
//                                          |
//                                       HC-05 RXD

سیم‌کشی با SoftwareSerial

برد Uno فقط یک UART سخت‌افزاری دارد که پین‌های 0 و 1 آن را اشغال کرده — همان که آپلود و سریال مانیتور از آن می‌گذرد. پس HC-05 را با UART دومِ نرم‌افزاری، یعنی کتابخانهٔ SoftwareSerial، به پین‌های دلخواه وصل می‌کنیم:

آردوینو Uno ماژول HC-05
5V VCC
GND GND
D10 (SoftwareSerial RX) TXD
D11 → مقسوم (۱ کیلواهم/۲ کیلواهم) → RXD
— (آزاد) EN / KEY
— (آزاد) STATE

چرا پین‌های 0 و 1؟ چون اگر ماژول روی آن‌ها باشد، هم‌زمان با آپلود اسکچ، UART سخت‌افزاری مشغول گفت‌وگو با ماژول است و آپلود به خطا می‌خورد. قاعدهٔ ثابت: ماژول‌های سریال خارجی همیشه روی SoftwareSerial و پین‌های دلخواه.

اسکچ کامل: کنترل LED از گوشی

برای گوشی، اپلیکیشن ترمینال بلوتوثی مثل Serial Bluetooth Terminal (اندروید) نصب کنید؛ برای رایانه، مدیریت بلوتوث ویندوز یا macOS ماژول را با پین 1234 یا 0000 جفت می‌کند و یک پورت سریال مجازی می‌سازد. این اسکچ را آپلود کنید:

bt-led.ino
#include <SoftwareSerial.h>

const int ledPin = 12;
const int btRxPin = 10;  // Arduino RX <- HC-05 TXD
const int btTxPin = 11;  // Arduino TX -> HC-05 RXD (through divider)

SoftwareSerial bt(btRxPin, btTxPin);

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);   // Serial Monitor
  bt.begin(9600);       // HC-05 default data-mode baud rate
  bt.println("Bluetooth ready. Send: on / off");
  Serial.println("Waiting for Bluetooth commands");
}

void loop() {
  if (bt.available() > 0) {
    String command = bt.readStringUntil('\n');
    command.trim();
    if (command == "on") {
      digitalWrite(ledPin, HIGH);
      bt.println("LED turned on");
      Serial.println("Command from phone: on");
    } else if (command == "off") {
      digitalWrite(ledPin, LOW);
      bt.println("LED turned off");
      Serial.println("Command from phone: off");
    } else if (command.length() > 0) {
      bt.println("Unknown command");
    }
  }
}

توضیح نکته‌های تازه:

  1. SoftwareSerial bt(btRxPin, btTxPin); — یک پورت سریال نرم‌افزاری می‌سازد؛ ترتیب آرگومان‌ها RX و سپس TX است و خطای رایج، جابه‌جاشدن همین دو پین است.
  2. bt.begin(9600); — ماژول HC-05 در حالت داده به‌صورت پیش‌فرض با نرخ ۹۶۰۰ حرف می‌زند؛ همین نرخ را در ترمینال گوشی هم انتخاب کنید.
  3. bt.available() و bt.readStringUntil — دقیقاً همان الگوی درس سریال، این بار روی خط بلوتوث. trim() کاراکتر پایانی خط و فاصله‌های اضافی گوشی را حذف می‌کند.
  4. مسیر دوم، یعنی آردوینو ← گوشی، همین‌قدر ساده است: هر bt.println در گوشی نمایش داده می‌شود. مثلاً می‌توانید وضعیت یک سنسور را هر ثانیه برای گوشی بفرستید.

پس از اتصال ماژول (LED کوچک روی آن از چشمک‌زن سریع به دو چشمک در دو ثانیه تغییر حالت می‌دهد)، اگر در ترمینال گوشی بنویسید on و بفرستید، خروجی سریال مانیتور چنین است:

خروجی کد

Waiting for Bluetooth commands Command from phone: on

اشتباهات رایج و عیب‌یابی

نشانه علت رایج راه‌حل
ماژول در گوشی پیدا نمی‌شود ماژول در حالت داده است یا قبلاً جفت نشده LED ماژول باید سریع چشمک بزند؛ پین 1234 یا 0000 را امتحان کنید
حروف آشفته در گوشی یا مانیتور ناهمسان بودن نرخ باود هر دو طرف را روی 9600 بگذارید (نرخ پیش‌فرض حالت داده)
اتصال برقرار می‌شود اما بعداً می‌افتد تغذیهٔ ناپایدار یا برد زیاد تغذیهٔ تمیز 5V بدهید؛ HC-05 هنگام ارسال جریان بیشتری می‌کشد
آپلود اسکچ خطا می‌دهد ماژول روی پین‌های 0 و 1 وصل است ماژول را به D10 و D11 منتقل کنید و هنگام آپلود سیم TXD را جدا کنید
فرمان اجرا نمی‌شود ولی اتصال هست گزینهٔ پایان خط در ترمینال تنظیم نشده پایانهٔ Newline را انتخاب کنید؛ readStringUntil منتظر کاراکتر خط جدید است

تمرین‌ها

تمرین

تمرین ۱ — فرمان چشمک از گوشی

به اسکچ bt-led فرمان سومی اضافه کنید: اگر از گوشی blink بفرستد، LED سه بار با فاصلهٔ ۳۰۰ میلی‌ثانیه چشمک بزند و سپس پیام Blink done را به گوشی برگرداند.

نمایش راه‌حل

یک شاخهٔ else if با حلقهٔ کوتاه کافی است؛ ساختار بقیهٔ کد دست‌نخورده می‌ماند:

cpp
} else if (command == "blink") {
  for (int i = 0; i < 3; i++) {
    digitalWrite(ledPin, HIGH);
    delay(300);
    digitalWrite(ledPin, LOW);
    delay(300);
  }
  bt.println("Blink done");
  Serial.println("Command from phone: blink");
}

اگر در ترمینال گوشی blink بفرستید، خروجی سریال مانیتور این خط است:

خروجی کد

Command from phone: blink

::: :::

خلاصه

  • HC-05 روی بلوتوث کلاسیک 2.0 کار می‌کند و مثل یک پورت سریال بی‌سیم رفتار می‌کند؛ HM-10 از خانوادهٔ BLE است و با این روش کار نمی‌کند.
  • تغذیهٔ بازشکن 3.6 تا 6 ولت است، اما منطق ماژول 3.3 ولت است؛ خط TX آردوینو باید با مقسوم ولتاژ ۱ و ۲ کیلواهم به RXD برسد.
  • ماژول را روی SoftwareSerial (مثلاً D10 و D11) وصل کنید، نه پین‌های 0 و 1.
  • نرخ پیش‌فرض حالت داده 9600 است و الگوی available و readStringUntil درس سریال عیناً روی خط بلوتوث کار می‌کند.
  • اپلیکیشنی مثل Serial Bluetooth Terminal گوشی را به ترمینال سریال بی‌سیم تبدیل می‌کند.

حالا می‌توانید نام ماژول، نرخ باود و رمز آن را از راه خود ماژول تغییر دهید؟ این دقیقاً کار حالت فرمان AT است — موضوع درس بعدی.

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

درس‌های مرتبط