آموزش Espآموزش ESP32آموزش اینترنت اشیاپروژه های Esp

آموزش جامع کنترل پایه با وب سرور ESP32

در این مطلب، ساخت پروژه کنترل نور LED با وب سرور ESP32 را با هم می آموزیم و برای اینکار مراحلی چون راه اندازی ESP32، اتصال LEDها و ایجاد صفحه وب برای کنترل آن ها را طی میکنیم. چه به تازگی با پروژه های اینترنت اشیا آشنا شده باشید و چه یک سازنده ماهر باشید، این آموزش مهارت های شما را ارتقا خواهد داد.

پروژه های دیگر اینترنت اشیا با  ESP32 و مطالب موبوط به وب سرورهایی که با رزبری پای، NodeMCU و دیگر میکروکنترلرها ساخته ایم مانند “ساخت وب سرور با NodeMCU و کنترل نور LED از صفحه وب”، ” کار با Node.js و رزبری پای: کنترل یک LED با وب سرور Node.js”، ” ایجکس و ESP8266: به روز رسانی پویا صفحه وب بدون ریلودینگ”، ” اتصال ESP8266  با STM32F103C8 : ایجاد یک وب سرور” و “اتصال  ESP8266 با ARM7-LPC2148 : ایجاد وب سرور برای کنترل LED” را نیز مطالعه کنید.

حال بیایید نگاهی به آنچه که باید برای ساخت وب سرور و کارآمد بودن آن انجام دهیم، بیندازیم.

  1. LEDها باید به پایه های GPIO12 و GPIO14 میکروکنترلر ESP32 متصل شوند تا بتوانیم آن ها را کنترل کنیم.
  2. پس از کدنویسی، برای دسترسی به صفحه وب، آدرس IP میکروکنترلر خود را در مرورگر وارد کنید.
  3. دکمه های صفحه وب را برای روشن و خاموش کردن LED ها فشار دهید.

قطعات لازم

قطعات لازم برای ساخت این پروژه عبارتند از:

  1. بورد توسعه ESP32- این قطعه، قطعه اصلی مدار ماست و با استفاده از آن نور LED را از طریق وب سرور کنترل میکنیم.
  2. لامپ های LED- متناسب با پروژه خود، میتوانید از انواع LEDها استفاده کنید. ما در این پروژه از LEDهای 2 در 5 میلی متر استفاده کرده ایم.
  3. برد بورد- از این قطعه برای اتصال لامپ های LED به میکروکنترلر ESP32 استقاده میکنیم.
  4. سیم های جامپر- برای اتصال بورد توسعه ESP32 به کامپیوتر به این سیم ها نیاز داریم.
  5. کامپیوتر- برای اتصال و آپلود کد روی بورد توسعه ESP32 به آن نیاز داریم.
  6. مقاومت- از مقاومت برای محدوکردن جریان گذرنده از لامپ های LED استفاده میکنیم تا از سوختن آن ها جلوگیری کنیم.

سوالات متداول درباره ESP32

1- آیا ESP32 میتواند هم یک کلاینت و هم یک سرور باشد؟

بله، ESP32 میتواند در یک شبکه هم به عنوان کلاینت و هم به عنوان سرور کار کند. میتواند به عنوان سرور ریکوئست ها و درخواست های ورودی را دریافت کرده و به آن ها پاسخ دهد و همچنین میتواند به عنوان یک کلاینت، آغاز کننده درخواست ها باشد تا به داده و منابع دیگر دسترسی پیدا کند. این قابلیت ESP32 آن را به یک پلتفرم همه کاره برای کاربردهای گوناگون مانند اینترنت اشیا تبدیل میکند. ESP32 میتواند در این پروژه ها مانند یک هاب عمل کند. متصل شدن این میکروکنترلر به بلوتوث و وایفای، عملکرد آن را به عنوان یک دستگاه در شبکه بهبود میبخشد.

2- نام هاست وب سرور ESP32 چیست؟

نام هاست وب سرور ESP32 میتواند آدرس IP میکروکنترلر یا نام دامنه اختصاص داده شده به آن باشد. به صورت پیش فرض، نام هاست دستگاه ESP32، Espressif است. هرچند که این نام میتواند با تغییر تنظیمات شبکه یا تغییر نام هاست در کد آردوینو، تغییر یابد. دستگاه های دیگر از نام هاست برای شناسایی و اتصال به وب سرور ESP32 استفاده میکنند. هنگام اتصال به وب سرور از مروروگر، میتوان نام هاست را به همراه شماره پورت مناسب در قسمت URL وارد کرد.

3- سوکت وب در ESP32 چیست؟

سوکت وب یک پروتکل ارتباطی است که ارتباط دوطرفه بین کلاینت و سرور را از طریق یک اتصال TCP ممکن میکند. در ESP32، پروتکل سوکت وب میتواند ارتباط همزمان وب سرور و یک مرورگر وب را فعال کند. به این شکل، کلاینت دیگر نیازی به درخواست مداوم برای داده جدید نداشته و وب سرور به محض اینکه داده ای در دسترس باشد، آن را به کلاینت ارسال میکند.

عملکرد وب سرور ESP32 و LED

در این پروژه، روی میکروکنترلر ESP32 یک سرور وب میسازیم. دستگاه کلاینت که برای مثال میتواند یک کامپیوتر یا تلفن همراه باشد، آن را مانند یک صفحه وب میبیند.

با این صفحه وب نور LED را کنترل کرده و آن را روشن یا خاموش میکنیم. در اینجا عملکرد پروژه کنترل نور LED با وب سرور ESP32 را مرحله به مرحله توضیح میدهیم:

  1. میکروکنترلر ESP32 به لامپ های LED متصل شده و به گونه ای کدنویسی میشود که مانند یک وب سرور عمل کند.
  2. کد وب سرور با استفاده از IDE آردوینو یا هر ابزار برنامه نویسی دیگری روی ESP32 آپلود میشود.
  3. ESP32 به شبکه وایفای متصل شده و میتواند از طریق اینترنت با دستگاه های کلاینت ارتباط برقرار کند.
  4. هنگامی که یک کلاینت به آدرس ESP32 IP متصل میشود، کد وب سرور، یک صفحه وب را به مرورگر کلاینت ارائه میدهد.
  5. این صفحه وب شامل گزینه هایی برای کنترل نور لامپ های LED است و کاربر میتواند با فشار دادن آن ها، لامپ ها را روشن و یا خاموش کند.
  6. هنگامی که کاربر با گزینه های کنترلی صفحه وب کار میکند، میکروکنترلر ESP32 دستور را دریافت کرده و متناسب با آن نور LED را تغییر میدهد.
  7. ESP32 یک پاسخ به کلاینت میفرستد و صفحه وب را با وضعیت جدید لامپ ها به روز میکند.

مدار اتصال کنترل LED با وب سرور ESP32

مدار کنترل یک لامپ LED با استفاده از وب سرور ESP32 را درپایین مشاهده میکنید.

عملکرد وب سرور ESP32 و LEDعملکرد وب سرور ESP32 و LED

میکروکنترلر ESP32 پایه های GPIO بسیاری برای اتصال به دستگاه های خارجی مانند لامپ های LED دارد. در این مثال، ما از پایه های GPIO12 و GPIO14 برای اتصال دو لامپ به ESP32 استفاده میکنیم.

اگر در مورد این مطلب سوالی دارید در قسمت نظرات بپرسید

حال اینگونه ESP32 را به دو لامپ LED متصل کنید:

یک پایه مقاومت 220 اهمی را به پایه GPIO12 میکروکنترلر و پایه دیگر مقاومت را به پایه مثبت (آند) لامپ LED متصل کنید.

پایه منفی (کاتد) لامپ LED را به زمین (GND) ESP32 متصل کنید.

مراحل بالا را برای پایه GPIO14 و لامپ LED دیگر تکرار کنید.

نصب بورد ESP32 روی IDE آردوینو

IDE آردوینو یک رابط کاربرپسند برای نوشتن و آپلود کد روی ESP32 است بدون اینکه به سواد بالای برنامه نویسی نیازی داشته باشیم و هم کاربران مبتدی و هم کاربران حرفه ای میتوانند از آن استفاده کنند.

میتوانید مطلب “شروع کار با ESP32 با استفاده از IDE آردوینو و پروژه LED چشمک زن” را که یک آموزش عمیق و جامع است مطالعه کنید.

تصحیح کد

پیش از آپلود کد، مطمئن شوید که مشخصات شبکه در کد را با SSID و رمزعبور خود عوض کرده اید.

const char* ssid = " REPLACE_WITH_YOUR_SSID";
const char* password = " REPLACE_WITH_YOUR_PASSWORD";

کد کامل این پروژه را میتوانید در انتهای این مطلب بیابید.

آپلود کد روی بورد ESP32

برای آپلود کردن کد روی بورد ESP32 مراحل زیر باید طی شوند.

  1. با استفاده از کابل USB بورد ESP32 را به کامپیوتر متصل کنید.
  2. IDE آردوینو را باز کرده و از منوی Tools به Board  رفته و بورد ESP32 خود را انتخاب کنید.
  3. همچنین پورت درست را از منوی Tools و قسمت Port  انتخاب کنید.
  4. کد خود را در IDE آردوینو نوشته یا در آن کپی کنید.
  5. با کلیک بر Verify یا آیکون تیک در گوشه بالا سمت چپ، کد خود را کامپایل و ترجمه کنید. اگر خطایی وجود داشت، آن را تصحیح کنید.

آپلود کد روی بورد ESP32

  1. با کلیک بر Upload یا علامت فلش راست در گوشه بالا سمت چپ، کد را روی ESP32 آپلود کنید. IDE کد شما را کامپایل کرده و روی بورد ESP32 آپلود میکند. پیشرفت آپلود کد در پایین IDE نشان داده میشود.

آپلود کد روی بورد ESP32

هنگامی که آپلود کد به پایان رسید، بورد ESP32 به صورت خودکار ریست شده و کد شما را اجرا خواهد کرد.

توجه داشته باشید که پیش از آپلود کد، ممکن است نیاز باشد که کلید Boot یا Reset بورد ESP32 را فشار داده تا وارد مد  “بوت لودر” شویم. ممکن است مراحل دقیق رفتن به مد بوت لودر در ESP32 شما متفاوت باشد. لطفا برای اطلاعات بیشتر در این زمینه به داکیومنت های بورد خود مراجعه کنید.

پیدا کردن آدرس IP بورد ESP32

  1. با کلیک بر آیکون یا علامت ذره بین در گوشه سمت راست و بالای پنجره IDE، سریال مانیتور را باز کنید.
  2. نرخ باد 115200 را از لیست موجود در گوشه سمت راست و پایین پنجره سریال مانیتور انتخاب کنید.
  3. با فشار دادن کلید EN یا RST روی بورد ESP32 آن را ریست کنید.
  4. صبر کنید تا بورد ESP32 به شبکه وایفای متصل شود. بر روی سریال مانیتور پیام هایی نوشته خواهد شد که پیشرفت در اتصال را نشان میدهد.

پیدا کردن آدرس IP بورد ESP32

سپس میتوانید آدرس آی پی برد ESP32 خود را مشاهده کنید.

آدرس آی پی برد ESP32

به عنوان روش جایگزین، میتوانید از یک ابزار جست و جوی شبکه مانند Advanced IP Scanner  برای یافتن دستگاه های متصل شده و آدرس IP بورد ESP32 استفاده کنید.

اتصال به وب سرور ESP32 و آزمایش آن

  1. با یک دستگاه به همان شبکه وایفای متصل شوید.
  2. یک مرورگر را روی کامپیوتر یا تلفن همراه باز کرده و آدرس IP بورد را در قسمت URL وارد کنید.

اتصال به وب سرور ESP32 و آزمایش آن

اگر دقیق تر نگاه کنید، میتوانید داده هایی را که به سریال مانیتور اضافه شده اند ببینید. این داده ها شامل جزئیاتی درباره وب سرور مانند درخواست های HTTP، آدرس هاست و غیره است. بعد از دسترسی به صفحه کنترلی در مرورگر خود، میتوانید با کلیک بر دکمه های ON و OFF عملکرد آن را بررسی کرده و وضعیت لامپ ها را مشاهده کنید. حال اگر بر دکمه مربوط به GPIO12 کلیک کنید، خواهید دید که سریال مانیتور یک درخواست 12/on دریافت کرده و سپس لامپ LED روشن میشود.

اتصال به وب سرور ESP32 و آزمایش آن

پس از این مراحل، ESP32 وضعیت ON یا OFF را در صفحه وب به روز میکند. تمام این گفته ها درباره پایه GPIO14 هم صدق میکند.

توضیحات کد کنترل LED با وب سرور ESP32

#include <WiFi.h>

در اینجا فایل هدر کتابخانه WiFi.h را فراخوانی میکنیم که برای اتصال به وایفای و ارتباط با دستگاه های دیگر  استفاده میشود.

// Replace with your network credentials
const char* ssid = "Replace with your SSID";
const char* password = "Replace with your password";

این خطوط از کد، SSID و رمز عبور شبکه وایفای ای که ESP32 به آن متصل خواهد شد را تعریف میکنند. شما باید این مقادیر را با SSID و رمزعبور شبکه خود عوض کنید.

WiFiServer server(80);

در این خط یک شی از کلاس WiFiServer تعریف میکنیم. این شی درخواست های HTTP ورودی را از پورت 80 دریافت میکند. پورت 80، پورت پیش فرض  درنظر گرفته شده برای ترافیک پروتکل HTTP است.

String header;

یک متغیر رشته ای به نام header تعریف میکنیم که درخواست HTTP دریافت شده از یک کلاینت را در خود ذخیره میکند.

// Auxiliar variables to store the current output state
String output12State = "off";
String output14State = "off";

دو متغیر رشته ای دیگر به نام های output12State و output14State را تعریف میکنیم که وضعیت فعلی (روشن/خاموش بودن) دو پایه خروجی ESP32 را در خود ذخیره میکنند.

// Assign output variables to GPIO pins
const int output12 = 12;
const int output14 = 14;

دو ثابت به نام های output12 و output14 که نشانگر خروجی پایه های GPIO12 و GPIO14 بورد ESP32 هستند تعریف میکنیم که برای کنترل وضعیت دستگاه های خارجی استفاده میشوند.

// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0;
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;

در این سه خط، متغیرهایی برای اندازه گیری زمان سپری شده از آغاز کار سرور تعریف میکنیم. همچنین برای درخواست های کلاینت بازه زمانی مشخص میکنیم. ( پس از 2000 میلی ثانیه، زمان ارسال درخواست به پایان میرسد.)

void setup() {
  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(output12, OUTPUT);
  pinMode(output14, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output12, LOW);
  digitalWrite(output14, LOW);
  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

نام این تابع، تابع ()setup است که تنها یکبار فراخوانی میشود. سرعت ارتباط سریال، پیکربندی دو پایه GPIO به عنوان خروجی و تنظیم آن ها در وضعیت LOW، در این تابع انجام میشود. سپس با استفاده از SSID و رمزعبوری که پیش تر تعریف کرده ایم، به شبکه وایفای متصل شده و تا زمان برقراری ارتباط، صبر میکند. به محض اینکه ارتباط برقرار شد، آدرس IP ESP32 را در سریال مانیتور چاپ کرده و وب سرور را آغاز میکند.

void loop(){

تابع ()loop، تابع اصلی کد آردوینوست که از زمان روشن شدن ESP32 به صورت مداوم اجرا میشود.

WiFiClient client = server.available();   // Listen for incoming client

این خط، دردسترس بودن کلاینت ها را بررسی میکند. اگر کلاینتی در دسترس بود، یک نمونه جدید از کلاس WiFiClient ساخته و آن را به کلاینت موجود منتسب میکند.

if (client) {

اینجا متصل شدن یک کلاینت جدید به وب سرور را بررسی میکنیم. اگر کلاینت متصل شده بود، کد درون جمله شرطی if اجرا میشود.

currentTime = millis();
    previousTime = currentTime;

این دو خط از کد، با استفاده از تابع ()millis زمان فعلی را بر حسب میلی ثانیه دریافت کرده و آن را در دو متغیر currentTime و previousTime دخیره میکند.

Serial.println("New Client.");

پیامی را روی سریال مانیتور چاپ کرده و متصل شدن کلاینت جدید را خبر میدهیم.

String currentLine = "";

در اینجا، یک متغیر رشته ای خالی به نام currentLine ایجاد میکنیم که داده ورودی را از کلاینت دریافت کند.

 while (client.connected() && currentTime - previousTime <= timeoutTime) {  // loop while the client's connected

      currentTime = millis();

حلقه while، مادامی که اتصال کلاینت برقرار است و زمان سپری شده از حلقه تکرار قبلی، کمتر یا مساوی متغیر timeoutTime است، اجرا میشود.

 if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;

این بلوک کد، موجود بودن یا نبودن داده ای از طرف کلاینت برای خواندن را مشخص میکند. اگر داده ای برای خواندن موجود است، یک بایت از آن را خوانده، آن را سریال مانیتور چاپ کرده و به متغیر header  اضافه میکند.

if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {

این بلوک کد، شروع شدن کاراکتر فعلی از سر خط را بررسی میکند. (n/) اگر کاراکتر فعلی از سرخط شروع میشود، خالی بودن خط فعلی بررسی شده و اگر این شرط هم برقرار بود و خط فعلی خالی بود، به پایان درخواست HTTP رسیده ایم و ESP32 باید پاسخی به کلاینت ارسال کند.

// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

این کد، هدرهای HTTP را به کلاینت ارسال میکند. به این معنی که پاسخ در قالب یک صفحه HTML است.

 // turns the GPIOs on and off
            if (header.indexOf("GET /12/on") >= 0) {
              Serial.println("GPIO 12 on");
              output12State = "on";
              digitalWrite(output12, HIGH);
            } else if (header.indexOf("GET /12/off") >= 0) {
              Serial.println("GPIO 12 off");
              output12State = "off";
              digitalWrite(output12, LOW);
            } else if (header.indexOf("GET /14/on") >= 0) {
              Serial.println("GPIO 14 on");
              output14State = "on";
              digitalWrite(output14, HIGH);
            } else if (header.indexOf("GET /14/off") >= 0) {
              Serial.println("GPIO 14 off");
              output14State = "off";
              digitalWrite(output14, LOW);
            }

این بخش از کد، درخواست های دریافت شده سرور را مدیریت میکند و براساس این درخواست ها پایه های GPIO را روشن و یا خاموش میکند.

توضیحات HTML کنترل LED با وی سرور ESP32

client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
These lines create the HTML header of the web page, including the viewport meta tag and an empty favicon link.
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
client.println(".button2 {background-color: #555555;}</style></head>");
This block of code defines the CSS styles that will be applied to the buttons in the web page.
client.println("<body><h1>ESP32 Web Server</h1>");
This line sets the main heading of the web page.
client.println("<p>GPIO 12 - State " + output12State + "</p>");
if (output12State=="off") {
  client.println("<p><a href=\"/12/on\"><button class=\"button\">ON</button></a></p>");
} else {
  client.println("<p><a href=\"/12/off\"><button class=\"button button2\">OFF</button></a></p>");
}
client.println("<p>GPIO 14 - State " + output14State + "</p>");
if (output14State=="off") {
  client.println("<p><a href=\"/14/on\"><button class=\"button\">ON</button></a></p>");
} else {
  client.println("<p><a href=\"/14/off\"><button class=\"button button2\">OFF</button></a></p>");
}

این خطوط، حالت فعلی پایه های GPIO12 و GPIO14 را نشان داده و یکی از دکمه های ON یا OFF را متناسب با حالت پایه ها نشان میدهد.

client.println("</body></html>");

در اینجا داکیومنت HTML را میبندیم.

client.println();

هدرهای پاسخ HTTP را پایان میدهیم.

client.stop();
Serial.println("Client disconnected.");
Serial.println("");

اتصال کلاینت را متوقف کرده و پیام هایی در این خصوص روی سریال مانیتور چاپ میکنیم.

موارد موجود در فایل : سورس کامل

5 (2 نفر)

برای دریافت مطالب جدید کانال تلگرام یا پیج اینستاگرام ما را دنبال کنید.

محمد رحیمی

محمد رحیمی هستم. سعی میکنم در آیرنکس مطالب مفید قرار بدهم. سوالات مربوط به این مطلب را در قسمت نظرات همین مطلب اعلام کنید. سعی میکنم در اسرع وقت به نظرات شما پاسخ بدهم.

13 نظر

  1. من یه برد ESP32 دارم میخوام به مدار خونه ببندم و از شهر های دیگه هم کنترلش کنم
    شما میگین با گوشی میتونم اینگونه تنظیمش کنم؟
    خیالم راحت باشه اگه شدنیه من دوره رو ثبت نام کنم

    1. سلام عزیز
      ما با کامپیوتر پروژه ها را تست کردیم و اگر پروژه شما سنگین باشد استفاده از موبایل مناسب نیست. خیلی از پروژه ها با موبایل هم قابل اجرا هست و خیلی از کاربران هم تست کرده اند اما ما تضمینی نمیدهیم و پیشنهاد ما قطعا استفاده از کامپیوتر هست.

  2. سلام خسته نباشید
    من کامپیوتر ندارم آردینو در گوشی استفاده میکنم
    آموزشات دوره اینترنت اشیاء رو میتونم با گوشی انجام بدم ؟

    1. سلام عزیز
      اکثرا با موبایل هم میشود اما قطعا بهتر هست از کامپیوتر استفاده کنید

  3. سلام
    در دوره اینترنت اشیا حرفه ای تغییر گرافیکی نور هم آموزش داده شده؟

  4. سلام
    یه سوال داشتم
    اگر همین پروژه را با رله بخواهیم در مدار ساختمان ببندیم و برد را همیشه روشن بگذاریم لزومی داره که یک فن کوچک روی آن قرار دهیم؟
    سوال دیگه اینکه آمپر آداپتور ۵ ولت که به برد وصل میشه در عمر برد تاثیر داره؟
    اگر تاثیر داره بهتره شارژر با چه آمپری به آن وصل کنیم؟

    1. سلام عزیز
      خیر نیازی نیست
      خیر تاثیری ندارد کمبود جریان نداشته باشید کافی هست

  5. سلام خسته نباشید
    ممنون از توضیحات تون
    من کد را در برد آپلود کردم جواب داد
    سوالم اینه که میشه دو کیلد را در کنار هم قرار داد؟
    من ۱۰ تا کلید درست کردم باید صفحه وب را پایین و بالا کنم میخواستم ببینم اگه میشه دو ردیف ش کنم.

    1. سلام عزیز
      میتوانید با استایل دهی هر طور که میخواهید صفحه را ایجاد کنید. دوره ESP32 و اینترنت اشیا حرفه ای را مشاهده کنید

  6. سلام من با این ارور برخوردمsketch_feb۲۱i.ino:3:22: fatal error: AsyncTCP.h: No such file or directory باید چکار کنم

    1. سلام عزیز
      کتابخانه را نصب کنید

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *