⚡ داده‌ی زنده با WebSocket روی ESP32

✍️ تیم ووکوی فارسی ·

در صفحه‌ی دماسنج، مرورگر هر چند ثانیه یک بار صفحه را دوباره می‌خواست. این روش کار می‌کند، ولی کند است و کلی داده‌ی تکراری جابه‌جا می‌کند. WebSocket یک خط ارتباطی همیشه باز بین مرورگر و ESP32 است: هر وقت عدد عوض شد، برد خودش آن را می‌فرستد و هر وقت دکمه‌ای زدی، فرمان در یک چشم به هم زدن به برد می‌رسد. در این آموزش با کتابخانه‌ی ESPAsyncWebServer این کار را می‌کنیم و در شبیه‌ساز ESP32 فارسی، مثل ووکوی (Wokwi)، نتیجه را می‌بینیم.

چه می‌سازیم؟

صفحه‌ای که درصد چرخش یک ولوم را با عدد بزرگ و زنده نشان می‌دهد (دو بار در ثانیه) و یک دکمه دارد که LED را خاموش و روشن می‌کند. اگر صفحه را در دو مرورگر باز کنی، هر دو هم‌زمان به‌روز می‌شوند.

قطعه‌ها و سیم‌کشی

قطعهاتصال
پتانسیومترکناری‌ها به 3V3 و GND، وسط به GPIO34
LED + مقاومت ۲۲۰ اهمGPIO4 و GND

کد کامل

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

const int LED = 4;
const int KNOB = 34;
bool ledOn = false;
unsigned long lastSend = 0;

AsyncWebServer server(80);
AsyncWebSocket ws("/ws");                    // the socket lives at /ws

const char page[] PROGMEM = R"rawliteral(<!DOCTYPE html><html>
<head><meta name="viewport" content="width=device-width, initial-scale=1"></head>
<body style="font-family:sans-serif;text-align:center">
<h2>Live knob</h2>
<p style="font-size:48px" id="v">--</p>
<button onclick="ws.send('toggle')">Toggle LED</button>
<p id="led">LED: ?</p>
<script>
var ws = new WebSocket('ws://' + location.host + '/ws');
ws.onmessage = function (e) {
  if (e.data.indexOf('led:') === 0) {
    document.getElementById('led').innerText = 'LED: ' + e.data.substring(4);
  } else {
    document.getElementById('v').innerText = e.data + ' %';
  }
};
</script></body></html>
)rawliteral";

void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
             void *arg, uint8_t *data, size_t len) {
  if (type == WS_EVT_CONNECT) {
    Serial.print("client connected: ");
    Serial.println(client->id());
    client->text(ledOn ? "led:ON" : "led:OFF");
  } else if (type == WS_EVT_DATA) {
    AwsFrameInfo *info = (AwsFrameInfo *)arg;
    if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
      String msg = "";
      for (size_t i = 0; i < len; i++) msg += (char)data[i];
      if (msg == "toggle") {
        ledOn = !ledOn;
        digitalWrite(LED, ledOn ? HIGH : LOW);
        ws.textAll(ledOn ? "led:ON" : "led:OFF");   // tell every open page
      }
    }
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
  WiFi.begin("Wokwi-GUEST", "");             // simulator network, no password
  while (WiFi.status() != WL_CONNECTED) delay(200);
  Serial.println(WiFi.localIP());

  ws.onEvent(onEvent);
  server.addHandler(&ws);
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(200, "text/html", page);
  });
  server.begin();
}

void loop() {
  ws.cleanupClients();                       // forget closed pages
  if (millis() - lastSend > 500) {
    lastSend = millis();
    int percent = map(analogRead(KNOB), 0, 4095, 0, 100);
    ws.textAll(String(percent));
  }
}

توضیح بخش‌های مهم

WebSocket کجا به کار می‌آید؟

هر جا که سرعت مهم است، WebSocket برنده است: کنترل یک ماشین رباتیک با دکمه‌های جهت، بازی‌های دونفره که روی دو گوشی اجرا می‌شوند، یا نمایش لحظه‌ای فاصله‌سنج. چون اتصال همیشه باز است، لازم نیست برای هر پیام یک درخواست تازه ساخته شود و تأخیر خیلی کم می‌ماند. یک تمرین خوب: یک اسلایدر به صفحه اضافه کن که عددش را با ws.send بفرستد و در C++ با ledcWrite نور LED را تنظیم کند.

امتحانش کن

در تینکرکد فارسی دو مثال آماده هست: LED زنده با WebSocket روی ESP32 و عدد زنده با WebSocket. اگر می‌خواهی اول خود ESPAsyncWebServer را بدون WebSocket ببینی، وب‌سرور سریع ESP32 را باز کن. خواندن مثال‌ها رایگان است و اجرای ESP32 با اشتراک Plus؛ شبیه‌ساز WebSocket را کامل شبیه‌سازی می‌کند. توضیح درسی در درس «به‌روزرسانی زنده با WebSocket».

اشکال‌های رایج

اگر فقط داده از برد به مرورگر می‌رود و برعکسش لازم نیست، راه ساده‌تری هم هست: نمودار زنده با EventSource (SSE). قبل از این، وب‌سرور ساده‌ی ESP32 را هم ببین. پروژه‌های بیشتر در وای‌فای و اینترنت اشیا.

LED زنده با WebSocket را باز کن ⚡

مقاله‌های مرتبط

📈

نمودار زنده‌ی سنسور با EventSource (SSE) روی ESP32

🗂️

صفحه‌ی وب از فایل SPIFFS روی ESP32

📡

پروژه‌ی اینترنت اشیا با MQTT روی ESP32

🎛️

ADC رزبری پای پیکو با میکروپایتون: خواندن پتانسیومتر با read_u16 و تبدیل به ولتاژ

همه‌ی آموزش‌های ESP32 و اینترنت اشیا ← · همه‌ی مقاله‌ها