در قسمت بیست و یکم از آموزش آردوینو به بررسی ثبت اطلاعات آردوینو در یک فایل کامپیوتر و همچنین، ارسال داده به بیش از یک دستگاه سریال، پرداختیم. در این قسمت قصد داریم درباره دریافت دادههای سریال از بیش از یک دستگاه سریال و همچنین، ارسال داده به بیش از یک دستگاه سریال صحبت کنیم.
دریافت دادههای سریال از بیش از یک دستگاه سریال
در ادامه به بررسی این مطلب میپردازیم که شما چگونه میتوانید هنگامی که از پورت serial-to-USB داخلی برای ارتباط با کامپیوتر خود استفاده میکنید، دادههایی را از یک دستگاه یا ماژول سریال، مانند یک serial GPS دریافت کنید.
در یک برد با بیش از یک پورت سریال، این کار بهراحتی قابلانجام است؛ به این صورت که ابتدا باید برد را همانطور که در شکل 1 نشان داده شده، به ماژول سریال متصل کنید؛ سپس، میتوانید دو پورت سریال را مقداردهی اولیه کنید و از Serial برای ارتباط با کامپیوتر و از دیگری (معمولاً Serial1) برای دستگاه (device) استفاده کنید.
✅نکته
در آردوینو Uno و سایر بردهایی که بر پایه ATmega328 ساخته شدهاند و تنها یک پورت سریال سختافزاری دارند، باید با استفاده از کتابخانه SoftwareSerial یک پورت سریال مجازی ایجاد کنید. این کار سرعت انتقال داده را نسبت به پورت سریال سختافزاری داخلی کاهش می دهد.
اما راهحل این مشکل آسان است: اگر پورت سریال آردوینو شما به کنسول آردوینو متصل است و میخواهید یک دستگاه سریال دیگر متصل کنید، باید یک پورت سریال مجازی با استفاده از کتابخانه SoftwareSerial ایجاد کنید.
دو پین برای استفاده بهعنوان خطوط ارسال و دریافت خود انتخاب کنید. در این جا از پینهای 8 و 9 استفاده شده است؛ زیرا برخی بردها (مانند Arduino Leonardo) فقط میتوانند دریافت SoftwareSerial را روی پینهای 8، 9، 10، 11 و 14 پشتیبانی کنند. این پینها همچنین جزء پینهایی هستند که Arduino Mega و Mega 2560 برای دریافت SoftwareSerial پشتیبانی میکنند.
در عمل، شما احتمالاً از سریال سختافزاری موجود روی پینهای 0 و 1 (Serial1) در این بردها استفاده خواهید کرد (بردهای Mega دارای پینهایی هستند که سریال سختافزاری را به عنوان Serial2 و Serial3 پشتیبانی میکنند)، اما ما پینهای SoftwareSerial را انتخاب کردیم که روی گستردهترین محدوده بردها کار کنند، در صورتی که تصمیم بگیرید این کد را روی یکی از آنها آزمایش کنید.
GPS خود را مطابق شکل زیر (شکل 2) متصل کنید.
همانطور که قبلتر هم انجام دادید، یک آبجکت SoftwareSerial در کد خود ایجاد کنید و به آن بگویید که کدام پینها را کنترل کند. در مثال زیر، یک پورت سریال مجازی به نام serial_gps تعریف میکنیم و از پینهای 8 و 9 به ترتیب برای دریافت و ارسال دادهها استفاده میکنیم. حتی اگر قصد ارسال هیچ دادهای به این دستگاه سریال را نداریم، باید یک پین برای ارسال مشخص کنیم؛ بنابراین وقتی از پورت سریال نرمافزاری استفاده میکنید، نباید از پین 9 برای کار دیگری استفاده کنید!
برای استفاده از کد زیر با پورت سریال سختافزاری داخلی ، پینها را مطابق شکل 1 متصل کنید، سپس خطوط زیر را از کد حذف کنید. اما در نظر داشته باشید که اگر از بردهایی با یک پورت سریال سخت افزاری استفاده می کنید. هنگام پروگرام برد باید اتصالات را جدا کنید وگرنه برد پروگرام نخواهد شد.
1 2 3 4 | #include <SoftwareSerial.h> const int rxpin = 8; const int txpin = 9; SoftwareSerial serial_gps(rxpin, txpin); |
در نهایت، این خط را بهجای آنها اضافه کنید: (اگر از پورت دیگری استفاده میکنید، Serial1 را تغییر دهید.)
1 | #define serial_gps Serial1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /* * SoftwareSerialInput sketch * Read data from a software serial port */ #include <SoftwareSerial.h> const int rxpin = 8; // pin used to receive from GPS const int txpin = 9; // pin used to send to GPS SoftwareSerial serial_gps(rxpin, txpin); // new serial port on these pins void setup() { Serial.begin(9600); // 9600 baud for the built-in serial port serial_gps.begin(9600); // initialize the port, most GPS devices // use 9600 bits per second } void loop() { if (serial_gps.available() > 0) // any character arrived yet? { char c = serial_gps.read(); // if so, read it from the GPS Serial.write(c); // and echo it to the serial console } } |
این اسکچ یا کد کوتاه بهسادگی تمام دادههای ورودی از GPS را به سریال مانیتور آردوینو ارسال میکند. اگر GPS بهدرستی کار کند و سیمکشی شما صحیح باشد، دادههای GPS را روی سریال مانیتور مشاهده خواهید کرد.
شما یک پورت SoftwareSerial مجازی را با ارائه شماره پینها برای ارسال و دریافت تعریف میکنید. کد زیر پورت را برای دریافت داده روی پین ۸ و ارسال داده روی پین ۹ تنظیم میکند:
1 2 3 | const int rxpin = 8; // pin used to receive from GPS const int txpin = 9; // pin used to send to GPS SoftwareSerial serial_gps(rxpin, txpin); // new serial port on these pins |
سینتکس(Syntax) برای خواندن یک پورت سریال مجازی بسیار مشابه با خواندن از یک پورت سریال داخلی است. ابتدا با استفاده از تابع available() بررسی کنید که کاراکتری از GPS رسیده باشد، سپس آن را با تابع read() بخوانید.
دریافت داده از چندین پورت SoftwareSerial
با استفاده از کتابخانه SoftwareSerial، میتوان چندین پورت سریال نرمافزاری را در یک کد ایجاد کرد. این یک روش مفید برای کنترلِ چندین دستگاه یا ماژول سریال در یک پروژه است. اما نکتهای که باید توجه داشته باشید این است که در هر لحظه تنها یکی از این پورتها میتواند به طور فعال دادهها را دریافت کند. ارتباط قابلاعتماد بر روی یک پورت نرمافزاری نیازمند توجه کامل پردازنده است. به همین دلیل است که SoftwareSerial تنها میتواند با یک پورت به طور فعال در یکزمان ارتباط برقرار کند.
امکان دریافت داده از دو پورت SoftwareSerial مختلف در یک کد وجود دارد. فقط باید توجه کنید که همزمان از هر دو پورت داده دریافت نکنید. دراینخصوص، اسکچهای بسیاری وجود دارند که بهعنوانمثال، مدتی یک دستگاه serial GPS را زیر نظر دارند و سپس ورودی را از یک ماژول زیگبی XBee دریافت میکنند. نکته کلیدی این است که بهآرامی بین آنها سوئیچ کنید و تنها زمانی به دستگاه دوم متصل شوید که انتقال از دستگاه اول کامل شده باشد.
برای مثال، در کد زیر، یک ماژول XBee به آردوینو متصل است. این ماژول دستورات را از یک ماژول دیگری از نوع XBee دریافت میکند. کد به جریان دستورات از طریق پورت ‘xbee’ گوش میدهد تا زمانی که سیگنال دریافت کند که باید شروع به جمعآوری دادهها از یک ماژول GPS متصل به پورت سریال نرمافزاری دوم کند. سپس کد به مدت ۱۰ ثانیه به GPS نظارت میکند—امیدوار باشیم بهاندازه کافی طولانی باشد تا تایید اتصال به ماهواره دریافت شود—قبل از اینکه دوباره به XBee برگردد.
در سیستمی با چندین پورت مجازی یا همان ‘نرمافزاری’، تنها یکی به طور فعال دادهها را دریافت میکند. به طور پیشفرض، پورت “فعال (active)” پورتی است که آخرین بار دستور begin() بر روی آن فراخوانی شده است. بااینحال، میتوانید پورت فعال را با فراخوانی متد listen() تغییر دهید. متد listen() به سیستم SoftwareSerial دستور میدهد که از دریافت دادهها در یک پورت متوقف شده و شروع به گوشدادن برای دادهها در پورت دیگر کند.
✅نکته
کد زیر نحوه طراحی یک کد برای خواندن ابتدا از یک پورت و سپس از پورت دیگر را نشان میدهد:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* * MultiRX sketch * Receive data from two software serial ports */ #include <SoftwareSerial.h> const int rxpin1 = 8; const int txpin1 = 9; const int rxpin2 = 10; const int txpin2 = 11; SoftwareSerial gps(rxpin1, txpin1); // gps TX pin connected to Arduino pin 9 SoftwareSerial xbee(rxpin2, txpin2); // xbee TX pin connected to Arduino pin 10 void setup() { Serial.begin(9600); xbee.begin(9600); gps.begin(9600); xbee.listen(); // Set “xbee” to be the active device } void loop() { if (xbee.available() > 0) // xbee is active. Any characters available? { if (xbee.read() == 'y') // if xbee received a 'y' character? { gps.listen(); // now start listening to the gps device unsigned long start = millis(); // begin listening to the GPS while (start + 100000 > millis()) // listen for 10 seconds { if (gps.available() > 0) // now gps device is active { char c = gps.read(); Serial.write(c); // echo it to the serial console } } xbee.listen(); // After 10 seconds, go back to listening to the xbee } } } |
این کد طوری طراحی شده است که رادیو XBee را بهعنوان پورت فعال (active) در نظر بگیرد تا زمانی که کاراکتر y را دریافت کند، در این صورت GPS به دستگاه فعال برای گوشدادن تبدیل میشود. پس از پردازش دادههای GPS به مدت ۱۰ ثانیه، کد دوباره به شنیدن از پورت XBee ادامه میدهد. دادههایی که بر روی پورت غیرفعال وارد میشوند، نادیده گرفته میشوند.
توجه داشته باشید که محدودیت ‘پورت فعال’ تنها به پورتهای نرمافزاری متعدد مربوط میشود. اگر طراحی شما به گونه ای است که نیاز دارید که حتما بهطور همزمان دادهها را از چندین دستگاه سریال دریافت کنید، استفاده از بردی که از چندین پورت سریال پشتیبانی میکند، انتخاب مناسبی است.
(جدول 1 پینهای مورد استفاده برای پورتهای سریال در بردهای مختلف آردوینو و بردهای سازگار با آردوینو را نشان میدهد.)