ارتباط سریال (UART)
با پروتکل UART و سریال مانیتور داده بین برد و رایانه رد و بدل میکنید و LED را با دستور متنی کنترل میکنید.
آنچه در این درس میآموزید
- اصول UART و مفهوم نرخ باود را توضیح دهید
- با Serial.print داده را در سریال مانیتور ببینید
- دستور متنی از رایانه دریافت و در برنامه بهکار ببرید
فهرست مطالب
آردوینو صفحهنمایش ندارد؛ پس چطور بفهمید داخل برنامه چه میگذرد؟ پاسخ ارتباط سریال است: یک خط ارتباط دوطرفه میان برد و رایانه که از همان کابل USB رد میشود. سریال هم «چشم شما به ذهن برد» است و هم ابزار فرماندادن به آن؛ در تمام پروژههای بعدی — بهویژه کار با سنسورها — به آن وابستهاید.
UART چطور کار میکند؟
UART روشی قدیمی و ساده برای انتقال بیتبهبیت داده است و دو خط دارد:
- TX (Transmit): فرستنده، داده را روی این خط میگذارد.
- RX (Receive): گیرنده، داده را از این خط میخواند.
ATmega328P یک UART سختافزاری دارد که پینهای D0 (RX) و D1 (TX) برد را اشغال کرده و همان از طریق تراشهٔ رابط USB با رایانه حرف میزند. دو طرف باید روی «نرخ باود» (Baud Rate) توافق کنند: تعداد بیت در ثانیه. مقدار مرسوم ۹۶۰۰ است و در همهٔ درسهای این دوره از همین استفاده میکنیم.
فرستادن داده به رایانه
پیش از هر استفاده، Serial.begin(9600) ارتباط را با نرخ ۹۶۰۰ بائود شروع میکند. سریال مانیتور را با دکمهٔ ذرهبینی در بالای IDE باز کنید و همانجا نرخ را روی 9600 baud بگذارید. خروجی سریال مانیتور پس از چند ثانیه چنین است:
int counter = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
counter++;
Serial.print("Counter: ");
Serial.println(counter);
delay(1000);
}Counter: 1 Counter: 2 Counter: 3
تفاوت Serial.print و Serial.println فقط در پایاندادن خط جدید است؛ برای خوانا بودن دادهها تقریباً همیشه println بهکار میرود.
دریافت دستور از رایانه
جهت مقابل هم به همین سادگی است: Serial.available() میگوید دادهای در صف دریافت هست یا نه، و Serial.readStringUntil تا رسیدن خط جدید منتظر میماند. کد زیر LED پین ۱۲ را با دو دستور متنی کنترل میکند:
const int ledPin = 12;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
Serial.println("Send a command: on or off");
}
void loop() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
command.trim(); // Remove spaces and the newline character
if (command == "on") {
digitalWrite(ledPin, HIGH);
Serial.println("LED turned on");
} else if (command == "off") {
digitalWrite(ledPin, LOW);
Serial.println("LED turned off");
} else {
Serial.println("Unknown command");
}
}
}اگر در سریال مانیتور تایپ کنید on و بفرستید، خروجی سریال مانیتور یک خط است:
LED turned on
تمرینها
تمرین
تمرین ۱ — فرمان پرسش وضعیت
به کد led-command فرمان سومی اضافه کنید: اگر کاربر status بفرستد، برد وضعیت فعلی LED را با Serial.println چاپ کند. برای نگهداشتن وضعیت از متغیر bool استفاده کنید.
// Write your code hereنمایش راهحل
const int ledPin = 12;
bool ledState = false;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
Serial.println("Send a command: on, off or status");
}
void loop() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
command.trim();
if (command == "on") {
ledState = true;
digitalWrite(ledPin, HIGH);
Serial.println("LED turned on");
} else if (command == "off") {
ledState = false;
digitalWrite(ledPin, LOW);
Serial.println("LED turned off");
} else if (command == "status") {
Serial.println(ledState ? "Status: on" : "Status: off");
} else {
Serial.println("Unknown command");
}
}
}:::
خلاصه
- UART داده را بیتبهبیت روی دو خط TX و RX جابهجا میکند و دو طرف باید همنرخ باشند؛ مقدار مرسوم این دوره ۹۶۰۰ بائود است.
Serial.beginارتباط را شروع میکند؛printوprintlnداده میفرستند وprintlnخط را میبندد.- سریال مانیتور در IDE تنظیم نرخ و ارسال متن دارد و برای رفع اشکال برنامه حیاتی است.
Serial.availableوreadStringUntilدریافت فرمان از کاربر را ممکن میکنند.
حالا برد با شما حرف میزند و شما با برد؛ در درس آخر این گفتوگو را برای خواندن سنسورها بهکار میگیرید و پروژهٔ پایانی خود را میسازید.