📡 پروژهی اینترنت اشیا با MQTT روی ESP32
وبسرورهایی که تا اینجا ساختیم فقط داخل همان شبکهی وایفای کار میکنند و هر وسیله باید آدرس IP برد را بداند. در پروژههای واقعی اینترنت اشیا، دهها وسیله باید با هم حرف بزنند. راهحل محبوب، MQTT است. در این آموزش ESP32 با MQTT عدد یک ولوم را میفرستد و از روی داشبورد فرمان روشن و خاموش LED میگیرد. این پروژه را، مثل نمونههایی که در ووکوی (Wokwi) دیدهای، در شبیهساز ESP32 فارسی امتحان میکنیم که یک داشبورد MQTT داخلی هم دارد.
MQTT چطور کار میکند؟
MQTT مثل یک گروه پیامرسان است. وسط کار یک «کارگزار» یا بروکر هست. هر وسیله پیامش را با یک «موضوع» یا تاپیک به بروکر میدهد (publish) و هر کس آن تاپیک را دنبال کرده باشد (subscribe)، پیام را میگیرد. هیچکس لازم نیست آدرس بقیه را بداند.
| تاپیک | چه کسی میفرستد | محتوا |
|---|---|---|
home/knob | ESP32 | درصد ولوم، هر ثانیه |
home/led | داشبورد | ON یا OFF |
home/status | ESP32 | online بعد از وصل شدن |
قطعهها و سیمکشی
- LED با مقاومت ۲۲۰ اهم روی GPIO4، پایهی کوتاه به GND
- پتانسیومتر: کناریها به 3V3 و GND، وسط به GPIO34
کد کامل
#include <WiFi.h>
#include <PubSubClient.h>
const char* ssid = "Wokwi-GUEST"; // simulator network
const char* password = ""; // no password
const char* broker = "broker.local"; // the simulator's built-in broker
const int LED = 4;
const int KNOB = 34;
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastSend = 0;
// Runs when a message arrives on a topic we subscribed to.
void callback(char* topic, byte* payload, unsigned int length) {
String message = "";
for (unsigned int i = 0; i < length; i++) message += (char)payload[i];
Serial.println("message on " + String(topic) + ": " + message);
if (message == "ON") digitalWrite(LED, HIGH);
if (message == "OFF") digitalWrite(LED, LOW);
}
void reconnect() {
while (!client.connected()) {
Serial.println("connecting to MQTT...");
String id = "esp32-" + String((uint32_t)ESP.getEfuseMac(), HEX);
if (client.connect(id.c_str())) {
client.subscribe("home/led");
client.publish("home/status", "online");
} else {
delay(1000);
}
}
}
void setup() {
Serial.begin(115200);
pinMode(LED, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(200);
Serial.println("Wi-Fi connected");
client.setServer(broker, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) reconnect();
client.loop(); // let PubSubClient do its work
if (millis() - lastSend > 1000) {
lastSend = millis();
int percent = map(analogRead(KNOB), 0, 4095, 0, 100);
client.publish("home/knob", String(percent).c_str());
}
}
توضیح بخشهای مهم
WiFiClient espClient; PubSubClient client(espClient);PubSubClient از اتصال وایفای برای حرف زدن با بروکر استفاده میکند.broker.localبروکر داخلی شبیهساز است. روی برد واقعی آدرس بروکر خودت را بگذار؛ مثلاً یک Mosquitto روی کامپیوتر خانه. خیلیها در Wokwi.com از بروکرهای عمومی آزمایشی استفاده میکنند، ولی یادت باشد هر کسی میتواند پیامهای آنها را ببیند.1883درگاه استاندارد MQTT است.- تابع
callbackهر بار که پیامی روی تاپیکهای دنبالشده برسد اجرا میشود. محتوای پیام بایتبهبایت میرسد و با حلقه به یکStringتبدیلش میکنیم. - در
reconnect، شناسهی هر برد را از شمارهی سختافزاریاش (ESP.getEfuseMac()) میسازیم. اگر دو وسیله با یک شناسه وصل شوند، بروکر اولی را بیرون میاندازد. client.subscribe("home/led")باید بعد از هر بار وصل شدن تکرار شود؛ برای همین داخلreconnectاست.client.loop()را در هر دورloopصدا بزن؛ پیامهای رسیده و زنده نگه داشتن اتصال به آن بستگی دارد.
امتحانش کن
مثال آماده در تینکرکد فارسی: اینترنت اشیاء با MQTT (ESP32). وقتی اجرایش کنی، زبانهی «اینترنت اشیاء» زیر کد، پیامهای هر تاپیک را نشان میدهد و دکمههایی برای فرستادن ON و OFF دارد. نسخهی درسیاش پیامرسان MQTT است و توضیح قدمبهقدم در درس «MQTT: پیامرسان اشیا». خواندن مثالها رایگان است و اجرای ESP32 با اشتراک Plus. یک مقالهی مفهومیتر هم در وبلاگ تینکرکد فارسی هست.
اشکالهای رایج
- مدام «connecting to MQTT...» چاپ میشود: آدرس بروکر یا درگاه اشتباه است.
client.state()را چاپ کن؛ عدد منفی یعنی اصلاً به بروکر نرسیدهای. - پیامهای داشبورد به برد نمیرسند:
client.loop()را جا انداختهای یا اسم تاپیک یکی نیست (home/ledباHome/LEDفرق دارد). - برد هر چند ثانیه قطع و وصل میشود: دو برد با یک شناسه وصلاند، یا با
delayطولانیclient.loop()را دیر صدا میزنی. - خطای «PubSubClient.h: No such file»: کتابخانهی PubSubClient نوشتهی Nick O'Leary را نصب کن. برای راهنمای کتابخانهها این صفحه را ببین.
حالا میتوانی چند حسگر و چراغ را با MQTT به هم وصل کنی، یا همه را در یک صفحه جمع کنی: داشبورد خانهی هوشمند روی گوشی. پروژههای بیشتر در وایفای و اینترنت اشیا.
پروژهی MQTT ESP32 را باز کن 📡