آموزش آردوینو

آموزش افزایش پورت سریال UART در بردهای آردوینو – بخش اول

آموزش افزایش پورت سریال در آردوینو
نوشته شده توسط علیرضا قربانی

تمام بردهای آردوینو از یک پورت سریال بر روی پین‌های ۰ و ۱ خود پشتیبانی می‌کنند ( که این پورت اغلب اوقات به پورت usb کامپیوتر متصل  است) . آیا برای شما پیش آمده است که نیاز به یک پورت سریال دیگر داشته باشید ؟ دیجی اسپارک ، مرکز تخصصی آردوینو در این پست به شما آموزش می‌دهد که چگونه می‌توانید از پین‌های‌ دیجیتال به عنوان پورت سریال استفاده کنید. در ادامه با مرجع تخصصی آردوینو به زبان فارسی، دیجی اسپارک همراه باشید.

با استفاده از سخت افزاری به نام UART که در دل میکروکنترلرهای AVR تعبیه شده است می‌توان از پورت‌های دیجیتال به عنوان پورت سریال استفاده کرد که این امر کمک می‌کند که با وسایلی که درای پروتکل ارتباطی سریال می‌باشند توسط پین‌های دیجیتال میکرو ارتباط سریال برقرار کنید .پلت فرم آردوینو دارای کتابخانه‌ای به نام SoftwareSerial می‌باشد که کار با سخت‌افزار UART را بسیار آسان کرده و به کمک آن قادر خواهید بود از پین‌های دیجیتال برای برقراری ارتباط سریال استفاده نمایید.

 

الزامی به یادگیری این کتابخانه

همانطور که گفته شد برخی از برد‌های آردوینو مانند Arduino Uno , Pro و . . . دارای یک عدد پورت سریال می‌باشند.فرض کنید قصد راه‌اندزای ماژول HC05 ( این ماژول با استفاده از پرونکل سریال کار می‌کند  )  را با آردوینو Uno دارید و علاوه برا آن قصد دارید اطلاعاتی را بر روی سریال مانیتور نرم افزار نمایش دهید. هم اکنون شما نیاز به دو پورت سریال دارید و برای اینکه بتوانید یک ارتباط سریال دیگر داشته باشید باید از کتابخانه SoftwareSerial استفاده کنید.

 

 

محدودیت‌های کتابخانه SoftWareSerial

  • اگر با استفاده از این کتابخانه ، چند پورت سریال نرم افزاری راه اندازی کنید ، در یک زمان خاص فقط از یکی از آن ها می‌توانید دیتا دریافت کنید.
  • تمام پین‌های آردوینو‌های سری مگا از این کتابخانه پشتیبانی نمی‌کند . فقط از پین‌های۰, ۱۱, ۱۲, ۱۳, ۱۴, ۱۵, ۵۰, ۵۱, ۵۲, ۵۳, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69) می‌توان به عنوان Rx استفاده نمود و برای Tx محدودیتی وجود ندارد.
  •  تمام پین‌های  آردوینو Leonardo و Micro از این کتابخانه پشنیبانی نمی‌کند و فقط از پین‌های ۸ , ۹ , ۱۰ , ۱۱ , ۱۴ , ۱۵ ,  ۱۶ می‌توان به عنوان Rx استفاده نمود و برای Tx محدودیتی وجود ندارد.

 

توابع کتابخانه سریال آردوینو

برای شروع کار با این کتابخانه ابتدا باید کتابخانه را همانند دستور زیر به نرم ‌افزار معرفی کنید.

#include <SoftwareSerial.h>

 

SoftwareSerial(rxPin, txPin, inverse_logic)

برای کار با این کتابخانه ابتدا باید به ازای هر پورت سریالی که می‌خواهیم راه‌اندازی کنیم ، یک شی از SoftwareSerial بسازیم و سازنده‌های آن را وارد کنیم. پارامترها :

rxPin : شماره پینی است که می‌خواهیم از آن به عنوان گیرندهاستفاده کنیم.

txPin : شماره پینی است که می‌خواهیم از آن به عنوان فرستنده استفاده کنیم.

inverse_logic : سطح منطق راا هنگام دریافت اطلاعات مشخص می‌‌کند. (الزامی به وارد کردن این آرگمان نمی‌باشد )

تذکر: به هیچ عنوان نباید وسیله‌ای که دارای سطح منطق متفاوت ارتباط سریال می‌باشد به آردوینو متصل نمود.برای آردوینوهایی که در ولتاژ ۵ ولت کار می‌کنند ،سطح منطق ۰ و ۵ ولت می‌باشد و برای آردوینو‌هایی که در ولتاژ ۳٫۳ ولت کار می‌کنند ، سطح منطق ۰ و ۳٫۳ ولت می‌باشد. برای مثال نباید وسیله‌جانبی که سطح ولتاژ پروتکل سریال آن ۰ و ۵ ولت می‌باشد به آردوینویی متصل نمود که سطح ولتاز ارتباط سریال آن ۰ و ۳٫۳ ولت می‌باشد. در مثال زیر یک ارتباط سریال بر روی پین ۲ و ۳ راه‌اندازی نموده‌ایم :

#include <SoftwareSerial.h>

const byte rxPin = 2; //پین گیرنده
const byte txPin = 3; //پین فرستنده

// set up a new serial object
SoftwareSerial mySerial (rxPin , txPin);

 

begin(speed)

با استفاده از این تابع سرعت انتقال اطلاعات را مشخص می‌کنیم. مقادیر بادریت مجاز عبارت‌اند از: ۳۰۰, ۶۰۰, ۱۲۰۰, ۲۴۰۰, ۴۸۰۰, ۹۶۰۰, ۱۴۴۰۰, ۱۹۲۰۰, ۲۸۸۰۰, ۳۱۲۵۰, ۳۸۴۰۰, ۵۷۶۰۰ و ۱۱۵۲۰۰ مثال:

#include <SoftwareSerial.h>
int rxPin 10
int txPin 11

//	ساخت یک شی از کتابخانه
SoftwareSerial mySerial = SoftwareSerial (rxPin, txPin);

void setup ()
  {
  //	به عنوان ورودیrx تنظیم
  pinMode (rxPin, INPUT);

  //به عنوان خروجی tx تنظیم
  pinMode (txPin, OUTPUT);
  // تنظیم بادریت
  mySerial.begin (9600);
  }

void loop ()
  {

  }

 

listen()

این تابع پورت سریال ساخته شده را برای دریافت اطلاعات فعال می‌کند.در یک لحظه فقط یک پورت می‌تواند آماده دریافت اطلاعات باشید و اگر در یک زمان بر روی پورت دیگری اطلاعات ارسال شود، آن اطلاعات از بین می‌روند. به عنوان مثال در قطعه کد زیر وقتی برنامه به خط ۲۳ می‌رسد عملیات فعال بودن portOne متوقف می‌شود و portTwo را فعال می‌کند و همچنین در سریال مانیتور نرم افزار هنگام تست کردن برنامه برای portOne پیغام Port One is not listening! و برای portTwo پیغام Port Two is not listening! را نمایش می‌دهد.

#include <SoftwareSerial.h>

// software serial : TX = digital pin 10, RX = digital pin 11
SoftwareSerial portOne(10, 11);

// software serial : TX = digital pin 8, RX = digital pin 9
SoftwareSerial portTwo(8, 9);

void setup()
{
  // Start the hardware serial port
  Serial.begin(9600);

  // Start both software serial ports
  portOne.begin(9600);
  portTwo.begin(9600);

}

void loop()
{
  portOne.listen();
  portTwo.listen();
  if (portOne.isListening()) {
   Serial.println("Port One is listening!");
}else{
   Serial.println("Port One is not listening!");
}

  if (portTwo.isListening()) {
   Serial.println("Port Two is listening!");
}else{
   Serial.println("Port Two is not listening!");
}

}

 

ولی اگر برنامه زیر را تست کنید برای portOne پیام Port One is listening! و برای portTwo نیز هم پیام Port Two is listening! را بر روی سریال مانیتور نرم افزار نمایش می‌دهد.

#include <SoftwareSerial.h>

// software serial : TX = digital pin 10, RX = digital pin 11
SoftwareSerial portOne(10, 11);

// software serial : TX = digital pin 8, RX = digital pin 9
SoftwareSerial portTwo(8, 9);

void setup()
{
  // Start the hardware serial port
  Serial.begin(9600);

  // Start both software serial ports
  portOne.begin(9600);
  portTwo.begin(9600);

}

void loop()
{
  portOne.listen();

  if (portOne.isListening())
  {
    Serial.println("Port One is listening!");
  }
  else
  {
    Serial.println("Port One is not listening!");
  }


  portTwo.listen();
  if (portTwo.isListening())
  {
    Serial.println("Port Two is listening!");
  }
  else
  {
    Serial.println("Port Two is not listening!");
  }
}

 

available()

این تابع تعداد بایت‌های دریافتی بر روی پورت سریال ساخته شده را برمی‌گرداند و همچنین اطلاعات دریافت شده را درون بافر گیرنده پورت سریال ذخیره می‌کند. ساختار کلی تابع به صورت زیر می‌باشد:

mySerial.available();

 

مثال :

#include <SoftwareSerial.h>

#define rxPin 10
#define txPin 11


SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

void setup()
{
  // define pin modes for tx, rx:
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  mySerial.begin(9600);
}

void loop()
{
  if (mySerial.available() > 0)
  {
    mySerial.read();
  }
}

 

read()

این تابع کاراکتر دریافت شده بر روی پورت سریال ساخته شده را می‌خواند و مقدار آن را برمی‌گرداند و در صورت این‌که اطلاعاتی برای خواندن وجود نداشته باشد مقدار ۱- را برمی‌گرداند. شکل استفاده از این تابع به صورت زیر می‌باشد :

char c = mySerial.read();

 

در قسمت بعدی به آموزش ادامه توابع این کتابخانه می‌پردازیم.

 

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

 

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

علیرضا قربانی

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

تبادل نظر و رفع عیب با ثبت دیدگاه

۱۹ دیدگاه

  • سلام وعرض ادب به مهندس اموزش خیلی خوب هست اگر امکانش هست در باره راه اندازی رله هشت کانال با بلوتوث یک پروژه انجام بدین ممنون

  • سلام و خسته نباشید
    برای افزایش rx ، امکانش هست که بشه از یه قطعه خارجی استفده کرد؟ یه گیت سخت افزاری ؟

  • سلام.
    می شود در مورد افزایش rx در میکرو مگا۸ با کدویژن کمک کنید. من نیاز به دو پورت سریال در میکرو دارم. البته با هم تداخل ندارند. یعنی همزمان ورودی ها فعال نیستند. حتی اگر یک ورودی فعال شد دومی خاموش بشود و اطلاعات از دست برود مهم نیست.
    با تشکر

    • با سلام
      لطفا سوالات را در پست های مرتبط با میکرو بپرسید تا توسط کارشناسان مربوطه پاسخ داده شود.

    • با سلام
      این مورد تست نشده است اما به نظر می‌رسد ارتباط از طریق UART امکان پذیر نباشد. مبدل هایی مانند MAX3232 پیشنهاد می‌شود. با این حال بایستی در این مورد تحقیق نمایید.

      • خانم مهندس سلام شرمنده دوباره مزاحم میشم
        به نظر شما میشه از level converter استفاده کنم؟؟

        • با سلام
          بایستی در این مورد تحقیق کنید. از دیگر کاربرانی که در این زمینه تخصص دارند، تقاضا میکنم در بحث شرکت کنند.

  • با سلام منظوراز “””تمام پین‌های آردوینو‌های سری مگا از این کتابخانه پشتیبانی نمی‌کند”””” اردوینو nano , uno هم شامل میشه ؟؟چون عملا از اردینو nano دیگه نمیشه استفاده کرد؟؟می شه راهنمایی کنید

    • با سلام
      در متن آموزش پایه هایی که از این قابلیت پشتیبانی می‌کند، نوشته شده است و تنها کافیست دیتاشیت را بررسی نمایید.

  • سلام
    وقتی ارتباط ما به صورت سریال میشه
    بعد چطور میتونیم از پین ها استفاده کنیم.البته با متلب ؟؟؟

  • سلام خسته نباشید
    لطفا میشه این کد پروژه رو برام ویرایش کنید
    میخوام از پورت سریال مجازی برای ارتباط استفاه بشه. پین ارتباط این کد ۰ , ۱ است . میخواهم همانند کد شما به پین های ۲ و ۳ متصل بشه

    Serial.begin(115200); //تعیین باودریت ارتباط سریال: توجه ارتباط بین ماژول SIM800L و برد اردوینو UNO، از طریق رابط سریال سخت افزاری صورت می گیرد
    delay(300);
    check_connect(); //کنترل اتصال ماژول به شبکه: در این حالت برنامه منتظر اتصال ماژول به شبکه مانده و پس از اتصال، برنامه ادامه می یابد.
    Serial.print(“AT+CMGF=1\r\n”); //به کمک این دستور ارسال پیامک در حالت متن قرار می گیرد.
    delay(1000);
    Serial.print(“AT+CMGD=1,4\r\n”); //به کمک این دستور حافظه پیامک ها را خالی می کنیم.
    delay(1000);
    Serial.print(“AT+CSMP=17,167,0,0\r\n”); //به کمک این دستور تنظیمات ارسال پیامک را انجام می دهیم. این دستور برای سیم کارت ایرانسل الزامی است.
    delay(1000);
    send_sms(“ANTI THEFT SYSTEM SUCCESSFULLY BOOTED”); //ارسال پیامک جهت اعلام موفقیت آمیز فعال شدن برد
    Serial.print(“AT+CFUN=0\r\n”); //خاموش کردن ماژول مخابراتی
    delay(1000);
    for(int j=0; j 2) { //زمانیکه سنسور SR501 حرکتی را تشخیص دهد، خروجی آن ۳٫۳ ولت می شود. در اینجا اگر ولتاژ بیش از ۲ در ورودی آنالوگ قرار گیرد، حرکت را تشخیص می دهیم.
    Serial.print(“AT+CFUN=1,1\r\n”); //روشن کردن ماژول
    delay(1000);
    check_connect(); //کنترل و انتظار برای اتصال ماژول به شبکه
    Serial.print(“ATD+989***********;\r\n”); //برقررای تماس تلفنی، جای ستاره ها شماره تماس خود را بگذارید.
    delay(1000);
    for (i = 0; i < 20; i++)
    delay(1000);
    }

    }

    void check_connect() {
    char ccalr[] = {"+CCALR: 1"};
    Serial.println("WAITING TO CONNECT TO NETWORK");
    Serial.flush();
    while (true) {
    Serial.print("AT+CCALR?\r\n"); // ارسال دستور AT+CCALR به ماژول، در صورتیکه ماژول به شبکه متصل گردد ماژول عبارت CCALR: 1 را بر میگرداند
    if (Serial.find(ccalr) == true) // نتیجه تابع find در صورتی true می شود که عبارت مورد نظر یافت شده باشد، در غیر اینصورت درون حلقه تا زمانیکه نتیجه مورد نظر یافت نشود، باقی خواهد ماند
    break; // خروج از حلقه با یافتن پیام مورد نظر
    }
    Serial.println("CONNECTED TO NETWORK");
    Serial.flush();
    }

    void send_sms( String data) {
    String number = "";
    number = "+989***************";//در اینجا به جای ستاره ها شماره تماس خود را قرار دهید. به این شماره داده ها ارسال می گردد.
    Serial.print("AT+CMGS=\"" + number + "\"\r\n");
    Serial.flush();
    delay(1000);
    Serial.println(data);//ارسال متن پیام
    Serial.flush();
    delay(1000);
    Serial.write(0x1a); //کاراکتر ctrl+z جهت ارسال پیام
    delay(5000);
    }

    • با سلام
      کاربر گرامی امکان پیگیری و بررسی کدهای متفرقه در کامنت ها فراهم نیست.
      با تقدیم احترام

  • با درود و سپاس بابت مطالب مفیدتون
    من تمام این کدهارو بعلاوه کلی کد دیگه با پروتئوس امتحان کردم اما نمیدونم چرا ارتباط فقط یک طرفه برقرار میشه و از پورت مجازی نمیشه تو پورت سخت افزاری رایت کرد ولی بالعکسش امکان پذیره . میشه بفرمایید چرا؟؟؟؟

    • با سلام
      کاربر گرامی ضمن تشکر از شما، این مورد در پروتئوس بررسی نشده است. از دیگر کاربرانی که در این خصوص تجربه ای دارند،تقاضا میکنیم در بحث شرکت کنند.