برقراری ارتباط با شیلد اترنت در آردوینو
در بخش قبلی، آموختید که چگونه می توان اپلیکیشن های شبکه را با یک بورد آدوینو با استفاده از انتصال شبکه ی رایانه ی خود ایجاد کنید. این روش به خوبی کار می کند اما معایب خاص خود را دارد. بزرگترین مشکل این است که برای این کار با به یک رایانه نیاز داریم، درحالیکه قابلیت های سخت افزار آردوینو برای بیشتر اپلیکیشن ها کافی است.
در این بخش، یاد خواهید گرفت که چگونه با استفاده از یک شیلد اترنت(Ethernet) این مشکل را حل کنید. معمولاً ما نمی توانیم یک بورد آردوینوی عادی را به یک شبکه(network) متصل کنیم. نه تنها قابلیت های سخت افزاری آن بسیار محدود است، بلکه اکثر بردهای آردوینو پورت اترنت ندارند. این یعنی ما نمی توانیم یک کابل اترنت را به بورد آردوینو متصل کنیم و برای غلبه بر این محدودیت، ما باید از یک شیلد اترنت(Ethernet shield) استفاده کنیم.
در چنین شیلدهایی، یک چیپ اترنت و کانکتورهای اترنت قرار دارند و آردوینوی ما را بلافاصله به یک دستگاه شبکه تبدیل می کنند. ما تنها باید این شیلد را به بورد آردوینو متصل کنیم. شما می توانید یک شیلد را از میان محصولات مختلف انتخاب کنید(در تصویر زیر برخی از آنها نشان داده شده اند)؛ همه ی آنها خوب هستند و به خوبی به هدف خود عمل می کنند. برای نمونه، من ترجیح می دهم از شیلد رسمی آردوینو استفاده کنم، زیرا برای تمام پین ها سوکت دارد و از یک شیار کارت microSD برخوردار است. بعنوان یک جایگزین، می توانیم از اترنت آردوینو استفاده کنیم؛ یعنی یک بورد آردوینو که یک پورت اترنت دارد و به شیلد مجزا نیاز ندارد.
سخت افزار تنها یکی از جنبه های تبدیل آردوینو به یک دستگاه شبکه است. ما همچنین به برخی نرم افزارها برای ارتباطات شبکه نیاز داریم. در IDE آردوینو یک کتابخانه ی مناسبِ اترنت وجود دارد که حاوی تعدادی کلاسِ مناسب شبکه است. ما اکنون می خواهیم از آن کتابخانه برای دسترسی به یک سرویس Daytime در اینترنت استفاده کنیم. یک سرویس Daytime ، تاریخ فعلی و زمان را بعنوان رشته های اَسکی(ASCII) برمی گرداند. سرورهای Daytime از پورت های TCP یا UDP استفاده می کنند. ما می توانیم سرویس های Daytime مختلفی را در اینترنت پیدا کنیم. یکی از آنها سرویس time.nist.gov است.
قبل از اینکه ما از این سرویس به صورت برنامه نویسی با آردوینو استفاده کنیم، مشاهده کنید که این سرویس چگونه با استفاده از فرمان telnet کار می کند:
maik> telnet time.nist.gov 13
Trying 192.43.244.18...
Connected to time.nist.gov.
Escape character is '^]'.
56965 14-11-04 20:33:03 00 0 0 867.4 UTC(NIST) *
Connection closed by foreign host.
به محض اینکه فرمان telnet به سرور Daytime متصل شود، این فرمان زمان و تاریخ فعلی را برمی گرداند. برای اطلاعات بیشتر اینجا کلیک کنید. سپس این سرویس، بلافاصله اتصال را قطع می کند. در زیر، دقیقا یک پیاده سازی از همین رفتار برای یک آردوینو با یک شیلد اترنت انجام شده است:
#include <SPI.h>
#include <Ethernet.h>
const unsigned int BAUD_RATE = 9600;
const unsigned int DAYTIME_PORT = 13;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress my_ip(192, 168, 2, 120);
IPAddress time_server(192, 43, 244, 18); // time.nist.gov
EthernetClient client;
void setup() {
Serial.begin(BAUD_RATE);
Ethernet.begin(mac, my_ip);
}
void loop() {
delay(1000);
Serial.print("Connecting...");
if (client.connect(time_server, DAYTIME_PORT) <= 0) {
Serial.println("connection failed.");
} else {
Serial.println("connected.");
delay(300);
while (client.available()) {
char c = client.read();
Serial.print(c);
}
Serial.println("Disconnecting.");
client.stop();
}
}
این کدها در آدرس زیر قرار دارد:
Ethernet/TimeServer/TimeServer.ino
ابتدا ما کتابخانه ی اترنت را اضافه(include) می کنیم و یک ثابت(constant) را برای پورت سرویس Daytime تعریف می کنیم. ما همچنین باید کتابخانه ی SPI را اضافه(include) کنیم، زیرا کتابخانه ی اترنت ما به آن بستگی دارد. سپس ما تعدادی متغیر سراسری(global variables) تعریف می کنیم:
متغیر mac : این متغیر حاوی مک آدرسی(MAC address) است که می خواهیم از آن برای شیلد اترنت استفاده کنیم. یک مک آدرس، در حقیقت یک عدد 48 بیتی است که به صورت یکتا یک دستگاه شبکه را مشخص می کند. معمولاً سازنده ی دستگاه، این شناسه را تنظیم می کند اما برای شیلد اترنت، خودمان باید آن را تنظیم کنیم؛ برای این کار ما از یک عدد دلخواه(arbitrary) استفاده می کنیم.
نکته مهم: مک آدرس در شبکه ی ما باید یکتا(unique) باشد.
اگر شما بیش از یک آردوینو را متصل کنید، مطمئن شوید که همه ی آنها مک آدرس های متفاوتی داشته باشند. همچنین توجه داشته باشید که اترنت آردوینو و آخرین نسخههای شیلد اترنت دارای یک مک آدرس هستند که میتوانید آن را روی برچسبی در پشت آنها پیدا کنید.
وقتی که ما رایانه ی خود را به اینترنت متصل کنیم، احتمالاً رایانه ی ما یک آدرس IP جدید از طریق DHCP (پروتکل پیکربندی هاست پویا) دریافت می کند. برای اکثر اپلیکیشن های آردوینو، پیاده سازی یک DHCP نسبتاً گران است. بنابراین ما معمولاً به صورت دستی یک آدرس IP را برای آنها مشخص می کنیم.(برای مشاهده ی اینکه چگونه از DHCP استفاده کنیم، مقاله ی استفاده از DHCP و DNS را در صفحه 177 مشاهده کنید). در اکثر موارد، این IP یک آدرس محلی(local) است که در محدوده ی 192.168.x.y قرار دارد. ما این آدرس را با استفاده از کلاس آردوینوی IPAddress در متغیر my_ip ذخیره می کنیم.
در نسخه های قدیمی تر IDE آردوینو، ما باید از یک آرایه ی بایت(byte array) برای ذخیره ی آدرس های IP استفاده کنیم. (در نسخه های جدید آردوینو) نیز هنوز هم می توانیم این کار را انجام دهیم؛ زیرا آرایه های بایت در صورت نیاز، به طور اتوماتیک به آبجکت های IPAddress تبدیل می شوند.
برای تبدیل نام های دامنه، مانند دامنه ی time.nist.go به یک آدرس IP نیاز داریم به یک DNS (سیستم نام دامنه) دسترسی داشته باشیم. کتابخانه ی استاندارد آردوینو از DNS استفاده می کند اما ما خودمان آدرس IP را پیدا خواهیم کرد. (برای مشاهده ی چگونگی استفاده از DNS ، مقاله ی استفاده از DHCP و DNS را در صفحه ی 177 مشاهده کنید). ما این نام دامنه را به متغیر time_server انتساب می دهیم. فرمان telnet از قبل نام دامنه ی سرویس Daytime را برای ما به یک آدرس IP تبدیل کرده است. به طور جایگزین، ما می توانیم از یکی از فرمان های زیر برای مشخص کردن آدرس IP یک نام دامنه استفاده کنیم:
maik> host time.nist.gov
time.nist.gov has address 192.43.244.18
maik> dig +short time.nist.gov
192.43.244.18
maik> resolveip time.nist.gov
IP address of time.nist.gov is 192.43.244.18
maik> ping -c 1 time.nist.gov
PING time.nist.gov (192.43.244.18): 56 data bytes
64 bytes from 192.43.244.18: icmp_seq=0 ttl=48 time=173.598 ms
--- time.nist.gov ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 173.598/173.598/173.598/0.000 ms
به سورس کدها برمی گردیم! در خط شماره 9 ما یک آبجکت جدید EthernetClient را ایجاد می کنیم. این کلاس، بخشی از کتابخانه ی Ethernet است و به ما امکان می دهد تا کلاینت های شبکه ای ایجاد کنیم که به یک آدرس IP و پورت معین متصل می شوند. در نسخه های قبلی IDE آردوینو، نام این کلاس، Client بوده است.
اکنون ما باید شیلد اترنت را مقدار دهی اولیه(initialize) کنیم؛ ما این کار را در خط 13 در تابع setup انجام می دهیم. ما در این خط دستور Ethernet.begin را فراخوانی می کنیم و مک آدرس و آدرس IP را به آن می دهیم. سپس ما (در خط 18) پورت سریال را مقدار دهی اولیه(initialize) می کنیم، به طوری که می توانیم برخی پیغام های دیباگ را در خروجی نشان دهیم. در این نقطه، ما تمام اجزاء را مقدار دهی اولیه(initialize) کرده ایم؛ بنابراین در نهایت می توانیم به سرور Daytime متصل شویم و خروجی آن را قرائت کنیم.
لطفا توجه داشته باشید که ما همچنین می توانیم آدرس IP گیت وی(gateway) و subnet mask از شبکه ی خود را نیز به متد Ethernet.begin پاس بدهیم. اگر ما آردوینو را مستقیماً به اینترنت متصل نکنیم، و به جای آن از یک روتر(router) یا مودم کابلی استفاده کنیم، این کار ضروری است. در این مورد، ما می توانیم آدرس گیت وی را به صورت زیر پاس دهیم:
// ...
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress my_ip(192, 168, 2, 120);
IPAddress time_server(192, 43, 244, 18); // time.nist.gov
// Insert IP address of your domain name system below:
IPAddress dns(8, 8, 8, 8);
// Insert IP address of your cable or DSL router below:
IPAddress gateway(192, 168, 13, 254);
EthernetClient client(time_server, DAYTIME_PORT);
void setup() {
Ethernet.begin(mac, my_ip, dns, gateway);
Serial.begin(BAUD_RATE);
}
// ...
تابع loop از اسکچ ما با یک وقفه ی کوتاه(short delay) شروع می شود، و به تمام اجزاء امکان می دهد تا به درستی مقدار دهی اولیه(initialize) شوند. این کار ضروری است زیرا شیلد اترنت یک دستگاه مستقل(autonomous) است که قابلیت کار موازی با آردوینو را دارد. در خط شماره 20، ما سعی می کنیم به سرویس Daytime متصل شویم. اگر اتصال نتواند ایجاد شود، ما یک پیغام خطا(error) را چاپ(print) می کنیم. در غیر این صورت، ما 300 میلی ثانیه منتظر می شویم تا سرویس مورد نظر کمی آماده سازی شود و سپس ما خروجی را کاراکتر به کاراکتر قرائت و چاپ(print) می کنیم.
رابط کلاینت مشابه کلاس Serial است. تابع available بررسی می کند که آیا برخی بایت ها هنوز در دسترس هستند یا نه و بایت بعدی را قرائت کرده و برمی گرداند. در انتها، ما متد stop را فراخوانی می کنیم تا از سرویس مورد نظر قطع(disconnect) شویم و سپس دوباره شروع می کنیم. توجه کنید که برنامه ی ما خیلی قدرتمند نیست. اگر سرور ما برای تحویل دادن داده های خود به زمانی بیش از 300 میلی ثانیه نیاز داشته باشد، برنامه ی ما آن را قرائت نخواهد کرد.
در مورد ما، این مسئله ی سختی نیست اما برای اپلیکیشن های مهم، بهتر است صبر کنیم تا داده ها در دسترس قرار گیرند(available) و یک مکانیزم وقفه(timeout) اضافه شود. اکنون، برنامه را در آردوینو کامپایل و آپلود کنید. سپس سریال مانیتور(serial monitor) را باز کنید، و باید چیزی شبیه زیر را مشاهده کنید:
Connecting...connected.
56807 14-11-04 16:34:18 50 0 0 259.2 UTC(NIST) *
Disconnecting.
Connecting...connected.
56807 14-11-04 16:34:20 50 0 0 515.5 UTC(NIST) *
Disconnecting.
کار تمام شد! اکنون آدوینوی ما مستقیماً به اینترنت متصل شده است و حتی یک کار مفید نیز انجام می دهد: سک ساعت بسیار دقیق را به ما نشان می دهد. در مجموع، اگر ما از شیلد اترنت استفاده کنیم، شبکه کردن با آردوینو با شبکه کردن در یک رایانه تفاوت زیادی ندارد؛ در بخش بعدی، یاد می گیریم که چگونه از سرویس هایی مثل DHCP و DNS در آدوینو استفاده کنیم.
1. سعی کنید نظرات شما مرتبط با مقاله ی مورد نظر باشد، در غیر این صورت پاسخ داده نخواهد شد.
2. سوالات خود را به صورت کوتاه بیان کنید و از پرسیدن چند سوال به طور همزمان خودداری کنید.
3. سوال خود را به طور واضح بیان کنید و از کلمات مبهم استفاده نکنید.