در جلسه چهارم از آموزش ارتباط سریال در آردوینو قصد داریم به توضیح توابع find , peek ,flush بپردازیم. در ادامه با مرجع تخصصی آردوینو به زبان فارسی، دیجی اسپارک همراه باشید.
find()
ساختار تابع به صورت زیر میباشد:
Serial.find(target);
عمل کرد تابع این گونه میباشد که به جای target یک رشته به تابع میدهیم ، برنامه شروع به خواندن بافر سریال میکند و در بافر عبارت مورد نظر را جست و جو میکند و در صورت پیدا کردن عبارت مورد نظر ، مقدار true را برمیگرداند. مثال:
bool find = false; void setup() { Serial.begin(9600); } void loop() { // در صورت وجود دیتا در بافر سریال وارد شرط زیر می شود if ( Serial.available () > 0) { //عبارت digispark را در بافر جست و جو می کند find = Serial.find( "digispark" ) ; //در صورت یافتن عبارت ، بر روی سریاالل مانیتور پیامی را نمایش می دهد if (find) { Serial.println( "digispark find" ); } } }
peek()
این تابع عمل کردی تقریبا مشابه تابع read دارد با این تفاوت که تابع read پس از خواندن داده از بافر سریال ، آن داده را از بافر حذف میکرد . ولی تابع peek پس از خواندن دیتا از بافر سریال ، دیتا را دست نخورده در بافر باقی میگذارد. به مثال زیر توجه کنید.
void setup () { Serial.begin (9600); } void loop () { if ( Serial.available () > 0 ) { Serial.println (Serial.read ()); Serial.println (Serial.read ()); } }
برای انجام مثال فوق ابتدا یک کاراکتر توسط سریال مانیتور نرم افزار بر روی پورت سریال ارسال میکنیم . در خط شماره ۱۰ ، دیتا توسط تابع read خوانده و سپس از بافر سریال حذف میشود . بعد از آن نوبت به عملیات خط شماره ۱۱ میرسد ،در بافر دیتایی وجود ندارد پس تابع read که در خط شماره ۱۱ به کار برده شده است مقدار -۱ را برمیگرداند. همانطور که در آموزش های قبلی ارتباط سریال آردوینو گفته شد ، در صورتی که تابع read ، دیتایی دریافت نکند ، مقدار منفی ۱ را برمیگرداند. حال مثال را با استفاده از تابع peek بیان میکنیم :
void setup() { // put your setup code here, to run once: Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: if (Serial.available() > 0) { Serial.println(Serial.peek()); Serial.println(Serial.read()); } }
در این مثال نیز یک کاراکتر توسط سریال مانیتور نرم افزار به پورت سریال ارسال میکنیم. در خط شماره ۱۰ دیتا توسط تابع peek خوانده میشود ولی برخلاف مثال قبل این بار دیتا از بافر سریال حذف نمیشود . پس از آن نوبت به خط شماره ۱۱ میرسد . این بار به این علت که قبل از آن از تابع peek استفاده شده است و دیتا از بافر پاک نشده ، دیتا را خوانده و بر روی سریال مانیتور نرم افزار نمایش میدهد.
flush()
در کتابخانه سریال نرم افزار آردینو تابعی به نام flush قرار دارد که کمی کاربران را در استفاده از آن گمراه میکند و در تمام آموزش ها هم (حداقل آموزش های زبان فارسی) این تابع را به صورت کاملا اشتباه توضیح داده اند. و این آموزش تنها آموزشی است که به تشریح درست این تابع میپردازد. در ورژنهای ۱٫۰ به قبل نرم افزار آردوینو ، این تابع وظیقهی پاک کردن بافرگیرنده سریال را داشت. یعنی هرگاه از این تابع استفاده میشد تمام اطلاعات بافر گیرنده به طور کامل حذف میشد. ولی بعد از ورژن ۱٫۰ نرم افزار آردوینو، ماهیت این تابع کاملا تغییر یافت. در حال حاضر هنگامی که از این تابع استفاده میشود ، برنامه متوقف شده تا تمام دیتا را از بافر فرستنده ارسال کند. توجه کنید گفته شد اطلاعات را ارسال کند نه دریافت. برای درک بهتر این تابع دو مثال بیان میکنیم و زمان ارسال کامل اطلاعات در هنگام استفاده از این تابع و عدم استفاده از این تابع را به کمک تابع millis محاسبه میکنیم. مثال اول قطعه کدی است که در آن از تابع flush استفاده نشده است و قصد داریم یک سری اطلاعات را به سریال مانیتور ارسال کنیم و زمان ارسال آن را اندازه گیری نماییم :
void setup() { // Give some time to open serial monitor after programming delay(2500); Serial.begin(9600); // Store the current time (start the clock) unsigned long millisNoFlushStart = millis(); // Transmit some psuedo-random text Serial.println(F("How long will it take to transmit the following:")); Serial.println(F("abcdefghijklmnopqrstuvwxyz")); Serial.println(F("done")); // Store the current time (stop the clock) unsigned long millisNoFlushStop = millis(); Serial.print(F("Without flush, Serial.println()s return control in: ")); Serial.print( millisNoFlushStop - millisNoFlushStart); Serial.println(F(" milliseconds.")); } void loop() {}
پس از کامپایل این کد ، مشاهده میکنید که اطلاعات در زمان حدود ۲۰ میلی ثانیه ارسال شدهاند. مثال دوم قطعه کدی است که در آن از تابع flush استفاده شده است و قصد داریم یک سری اطلاعات را به سریال مانیتور ارسال کنیم و زمان ارسال آن را اندازه گیری نماییم:
void setup() { // Give some time to open serial monitor after programming delay(2500); Serial.begin(9600); // Store the current time (start the clock) unsigned long millisWithFlushStart = millis(); // Transmit the same psuedo-random text as before Serial.println(F("How long will it take to transmit the following:")); Serial.println(F("abcdefghijklmnopqrstuvwxyz")); Serial.println(F("done")); // This time, let TX buffer flush before "stopping" the clock Serial.flush(); // Store the current time (stop the clock) unsigned long millisWithFlushStop = millis(); // Print results for flushed calls Serial.print(F("WITH flush, Serial.println()s return control in: ")); Serial.print( millisWithFlushStop - millisWithFlushStart); Serial.println(F(" milliseconds.")); } void loop() { }
پس از کامپایل کد مشاهده میکنید که زمان ارسال اطلاعات به حدود ۸۰ میلی ثانیه رسیده است.یعنی حدود ۴ برابر بیشتر از زمانی شده است که از تابع flush استفاده نشده بود. پس همانطور که از مثال ها پیداست تابع flush باعث مکث در برنامه میشود و زمانی که قصد داریم که ابتدا اطلاعات به طور کامل ارسال شود و بعد از آن برنامه را ادامه دهیم باید از این تابع استفاده کرد. این قسمت از آموزش را به پایان میرسانیم و در قسمت بعد مبحث ارتباط سریال آردوینو را تکمیل میکنیم.
چنانچه در مراحل راه اندازی و انجام این پروژه با مشکل مواجه شدید، بدون هیچ نگرانی در انتهای همین پست، به صورت ثبت نظر سوالتان را مطرح کنید. من در سریعترین زمان ممکن پاسخ رفع مشکل شما را خواهم داد. همچنین اگر ایرادی در کدها و یا مراحل اجرایی وجود دارند میتوانید از همین طریق اطلاع رسانی کنید.
انصافا تابع flush رو عالی توضیح دادین
من خیلی وقت بود میخواسم بدونم کارش چیه ولی نه خود سایت آردوینو نه سایتای دیگه هیچکدوم این چیزا را دربارش نگفتن
خیلی مرسی
درود
امانش هست پروتکل spi را هم تدریس کنید
واقعا ممنون از آموزش عالیتون
با سلام
کاربر گرامی از توجه شما سپاسگزارم.
سلام بر شما
مقدار millis را در یک متغییر ذخیره کرده و روی سریال مانیتور نمایش میدم.
هر بار سریال مانیتور را باز میکنم، از صفر شروع میشه. بدون ریست کردن یا دانلود کد روی برد!!!
void setup() {
Serial.begin(9600);
}
void loop() {
unsigned long Time=millis();
Serial.println(Time);
}
اگه ممکنه توضیح دهید
ممنون
درود
توسط تابع millis زمان شرو برنامه بر حسب میلی ثانیه نمایش داده میشود. با اتصال برد آردوینو و اجرای این دستور شروع به شمارش خواهد کرد.
بسیار عالی ممنون از اموزش بسیار خوبتان
سلام
از توجه و دقت نظر شما ممنونم.
با عرض سلام
خیلی ممنونم بابت اموزش های عالیتون
برای بنده یک سوالی بوجود اومده و هیچ جا نتونستم پیداش کنم جوابشو ممنون میشم بفرمایین
در دستور if ( Serial.available () > 0 ) این کد > 0 برای چی هست کلا!؟
با سلام
از تابع available جهت خواندن دیتا از سریال پورت استفاده میشود که یک عدد بایت است. به عنوان مثال با فراخوانی این تابع با ارسال عدد در سریال مانیتور یک عدد نمایش داده میشود.
سلام من serial.read bytes(s,10);
میکنم
بعدش
If (strstr(s,”password”)
Serial.println(“yes”);
اما کار نمیکنه
موقعی هم که کاراکتر کاراکتر چاپ میکنم یه کاراکتر با کد اسکی ۱۰ اخر اون جملم هستش
.
نمیدونم مشکل چیه
.
در ضمن while(serial.available())
میکنم برای خواندن اعداد صحیح در اخر یه عدد ۰ هم بعد از عدد خودم چاپ میشه
باید all bailable()>1 میکنم درست میشه
.
مشکل چیه
سلام
کد ارسالی مربوط به چه پروژه ای است؟
سلام واقعا عالی بود
ممنون
با سلام
از توجه شما ممنونم.
سلام
ممنوناز توضیحاتتون
الان اگر بخواهیم اطلاعات بافر رو پاک کنیم باید از چه روشی استفاده کنیم ؟
سلام
قطعه کد زیر مناسب این کار است:
if(Serial.avaiable() > 0)
Serial.readString();l