🔌 LED زنده با WebSocket روی ESP32

صفحه و برد یک اتصال باز نگه می‌دارند؛ دکمه‌ی صفحه یا دکمه‌ی روی مدار را بزن و وضعیت فوراً همه‌جا عوض شود.

سطح: چالشی ⭐⭐⭐ · مود: آردوینو (سه‌بعدی + کد)

قطعات لازم

کد کامل پروژه

// ESP32 + WebSocket: the page and the board keep one connection open, so
// the board can tell the page about a change without being asked.
// Run it, open the «مرورگر» tab and press Toggle — or the real button on the board.
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

const char* ssid = "MyHome";
const char* password = "12345678";
const int LED = 4;
const int BUTTON = 15;
bool ledOn = false;
bool lastButton = HIGH;

AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width, initial-scale=1">
<style>body{font-family:sans-serif;text-align:center}#b{font-size:22px;padding:12px 30px}</style></head>
<body><h2>ESP32 WebSocket</h2>
<p>LED: <b id="state">...</b></p>
<button id="b" onclick="toggle()">Toggle</button>
<p id="log" style="color:#888"></p>
<script>
var socket = new WebSocket("ws://" + window.location.host + "/ws");
socket.onopen = function () { document.getElementById("log").innerText = "connected"; };
socket.onclose = function () { document.getElementById("log").innerText = "disconnected"; };
socket.onmessage = function (event) {
  document.getElementById("state").innerText = event.data == "1" ? "ON" : "OFF";
};
function toggle() { socket.send("toggle"); }
</script></body></html>
)rawliteral";

void notifyClients() {
  ws.textAll(ledOn ? "1" : "0");
}

void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
  AwsFrameInfo *info = (AwsFrameInfo*)arg;
  if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
    data[len] = 0;
    if (strcmp((char*)data, "toggle") == 0) {
      ledOn = !ledOn;
      digitalWrite(LED, ledOn ? HIGH : LOW);
      notifyClients();
    }
  }
}

void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
             void *arg, uint8_t *data, size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("client #%u connected\n", client->id());
      client->text(ledOn ? "1" : "0");   // tell the new page the current state
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("client #%u left\n", client->id());
      break;
    case WS_EVT_DATA:
      handleWebSocketMessage(arg, data, len);
      break;
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
  pinMode(BUTTON, INPUT_PULLUP);
  WiFi.begin(ssid, 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_P(200, "text/html", index_html);
  });
  server.begin();
}

void loop() {
  ws.cleanupClients();
  bool now = digitalRead(BUTTON);
  if (now == LOW && lastButton == HIGH) {   // the board's own button
    ledOn = !ledOn;
    digitalWrite(LED, ledOn ? HIGH : LOW);
    notifyClients();
  }
  lastButton = now;
  delay(20);
}

چطور اجرایش کنم؟

  1. شبیه‌ساز تینکرکد فارسی را باز کن و «مود آردوینو» را انتخاب کن.
  2. از پنل «نمونه‌ها»، «LED زنده با WebSocket روی ESP32» را بارگذاری کن — مدار و کد با هم می‌آیند.
  3. دکمه‌ی اجرا ▶ را بزن و خروجی Serial و رفتار قطعات را تماشا کن.
  4. حالا کد را تغییر بده — عددها، پین‌ها، ترتیب — و دوباره اجرا کن!
این پروژه را رایگان در شبیه‌ساز اجرا کن 🤖