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

آموزش تایمر در برنامه نویسی آردوینو بخش دوم

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

در قسمت قبل از آموزش تایمر ، به شرح رجیستر‌های تایمر در حد آشنایی و همچنین عمل کرد تایمر پرداختیم. در این آموزش کتابخانه‌‌هایی معرفی خواهیم کرد کار با  Timer1 , Timer3 , Timer4 و Timer5 را بسیار آسان می‌کند و بدون درک زیادی از رجیستر‌ها قادر خواهید بود برنامه‌هایی که نیاز به استفاده از تایمر می‌باشند را بنویسید. این مجموعه ، اولین مجموعه‌ای از تایمر‌هایی ۱۶ بیتی می‌باشد که برای اولین بار توسط تیم تخصصی دیجی اسپارک بر روی وب قرار گرفته است.در ادامه با مرجع تخصصی آردوینو ، دیجی اسپارک همراه باشید. در قسمت قبل آموختیم که تایمر یک المان در خارج از cpu می‌باشد که وظیفه‌ی آن شمارش زمان ‌می‌باشد.در صورتی که با تایمر آشنایی ندارید ، پیشنهاد می‌کنیم آموزش قبلی تایمر را از لینک زیر مطلاعه کنید. آموزش تایمر آردوینو بخش اول

 


پایه های PWM برد آردوینو


در بردهای آردوینو سری مگا از ۶  تایمر و ۱۵ عدد خروجی PWM استفاده شده است که به شرح زیر می‌باشند:

  • پین ۴ و ۱۳ که به وسیله Timer0 کنترل می‌شوند
  • پین ۱۱ و ۱۲ به وسیله Timer1 کنترل می‌شوند
  • پین ۹ و ۱۰ در اختیار Timer2 قرار دارند
  • پین ۲ ، ۳ و ۵ در اختیار Timer3 قرار دارند
  • پین ۶ ، ۷ و ۸ به وسیله Timer4 کنترل  می‌شوند
  • پین ۴۶ ، ۴۵ و ۴۵ به وسیله Timer5 کنترل می‌شوند

مشکلات معمول تایمر در آردوینو


هنگام استفاده از Timer1 ، در صورتی که از کتابخانه Servo استفاده می‌کنید ، دیگر نمی‌توانید از پین ۹ و ۱۰ به عنوان PWM استفاده کنید. این قضیه در آردوینو‌های سری مگا کمی پیچیده تر می‌باشد. در آردوینو مگا هر تایمر توانایی راه اندازی ۱۲ عدد سروو موتور را دارد. برای راه ندازی ۱۲ سروو موتور اولی از Timer5 استفاده می‌شود (بنابراین از PWM برای پین‌های ۴۴ ، ۴۵ و ۴۶ نمی‌توانید استفاده کنید). برای راه اندازی ۲۴ عدد سروو موتور از Timer1 و Timer5 استفاده می‌شود ( بنابر این نمی‌توانید از PWM برای پین‌های ۱۱ ، ۱۲ ، ۴۴ ، ۴۵ و ۴۶ استفاده کنید) . اگر قصد راه‌اندزی۳۶ عدد سروو موتور را دارید ، آردوینو از Timer1 , Timer3  و Timer5 برای انجام این کار استفاده می‌کند (بنابراین نمی‌توانید از پین‌های ۲ , ۳ , ۵ , ۱۱ , ۱۲ , ۴۴, ۴۵ و ۴۶ به عنوان PWM استفاده کنید). و در آخر اگر می‌خواهید ۴۸ عدد سروو موتور را راه ‌اندازی کنید ، آردوینو برای راه اندازی آن‌ها از تمام تایمر‌های ۱۶ بیتی ( تایمر ۱ ،۳ ، ۴ و ۵) استفاده می‌کند و در این حالت شما تمام پین ‌های PWM را از دست می‌دهید.

 


برنامه نویسی تایمر در Arduino


برای شروع برنامه‌نویسی ابتدا کتابخانه تایمر‌های ۱۶ بیتی را از لینک زیر دانلود کنید. سپس مجموعه کتابخانه‌ها را به نرم‌افزار آردوینو اضافه نمایید. در فایل ضمیمه شده ، ۴ عدد کتابخانه موجود می‌باشد که از کتابخانه Timer1 می‌توان برای برنامه نویسی تایمر شماره ۱ در آردوینوها Uno , nano ,MEGA و… استفاده نمود و از کتابخانه‌های Timer3 , Timer4 ,Timer5 در آردوینوهای سری مگا استفاده می‌شود.

دانلود کتابخانه تایمرهای ۱۶ بیتی آردوینو (Timer1,Timer3,Timer4 , Timer5)

 


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


 

#include <TimerOne.h>

#include <TimerThree.h>

#include <TimerFour.h>

#include <TimerFive.h>

 

برای فراخوانی کتابخانه‌ها به برنامه  همانند زیر عمل می‌کنیم تمام توابع زیر در تایمر ۱، ۳ ، ۴ ، ۵ یکسان می‌باشند.

 


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


initialize(microseconds)

در هنگام شروع استفاده از تایمر ، این تابع حتما باید در ابتدای کار فراخوانی شود. آرگمانی که به آن می‌دهیم بر حسب میروثانیه می‌باشد و مقدار زمانی که تایمر باید شمارش کند را مشخص می‌کند. به طور پیش فرض مقدار این تابع ۱ ثانیه می‌باشد. کمترین مقدار برای این تابع ۱ میکروثانیه  و بیشترین مقدار برای آن ۸۳۸۸۴۸۰ میکرو ثانیه یا تقریبا ۸٫۳ ثانیه می‌باشد.

برای مثال اگر بخواهیم تایمر شماره ۱ ، ۰٫۵ ثانیه شمارش کند باید همانند قطعه کد زیر عمل کنیم :

Timer1.initialize(50000);

 

setPeriod(microseconds)

بعد از اینکه توسط تابع initialize مقدار دوره زمانی نایمر را تعیین کردید ، به  وسیله‌ی این تابع می‌توانید یک دوره زمانی جدید به تایمر معرفی کنید. به عنوان مثال دوره زمانی ۲٫۵ ثانیه را به تایمر معرفی می‌کنیم :

Timer1.setPeriod(2500000);

 

stop()

عمل شمارش زمان را متوقف می‌کند.

Timer1.stop();

 

resume()

این تابع  از همان جایی که عمل stop انجام شده است ، عمل شمارش را ادامه می‌دهد ( این تابع مقدار تایمر را صفر نمی‌کند )

Timer1.resume();

 

 

start()

این تابع برای شروع کار دوباره تایمر است.

Timer1.start();

 

 

restart()

این تابع مقدار تایمر را صفر می‌کند و عمل شمارش را از سر می‌گیرد.

Timer1.restart();

 

pwm(pin, duty)

به وسیله این تابع مقدار pwm  برای pin مورد نظر کانفیگ می‌شود. در صورتی که بخواهیم برای اولین بار به یک پین ، pwm اعمال کنیم ، ابتدا باید این تابع را فراخوانی کنیم.

pin : شماره پین مربوط به Timer

duty : مقدار pwm که عددی بین ۰ تا ۱۰۲۳ می‌باشد ( صفر به معنی این که pin همیشه در وضعیت LOW قرار دارد و ۱۰۲۳ به این معنی است که pin همیشه در وضعیت HIGH قرار دارد).

در مثال زیر مقدار duty cycle ، برابر ۵۱۲ می باشد و به پین شماره ۹ اعمال می‌شود.

Timer1.pwm(9, 512);

setPwmDuty(pin, duty)

 

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

Timer1.setPwmDuty( 9 , 512);

disablePwm(pin)

این تابع اعمال pwm را بر روی pin غیر فعال می‌کند و از آن به بعد می‌توان از آن به عنوان ورودی خروجی دیجیتال استفاده شود.

Timer1.disablePwm(9);

 

 

attachInterrupt(function)

به وسیله‌ی این تابع ، تابع وقفه‌ای که برای عمل سر ریز شدن تایمر نوشتیم را به برنامه معرفی می‌کنیم. به عنوان مثال در قطعه کد زیر تایمر هرگاه مقدارش ۲ ثانیه شود ، تابع callback فراخوانی می‌شود.

void setup()
{
 Timer1.initialize(200000);
 Timer1.attachInterrupt(callback);
}

void callback()
{
  //کد هایی که هنگام رسیدن تایمر به یک مقدار خاص باید اجرا شوند
}

detachInterrupt()

به وسیله این تابع ، تابع وقفه‌ای که به برنامه معرفی کرده بودیم ، غیر فعال می‌شود.

Timer1.detachInterrupt();

 


نمونه پروژه تایمر آردوینو


پروژه : در برنامه‌ی زیر یک LED که به پین شماره ۱۲ آردوینو متصل  می‌باشد هر ۱ ثانیه یک بار چشمک می‌زند.

//فراخوانی کتابخانه تایمر شماره ۱
#include <TimerOne.h>
int ledState = LOW;
int ledPin = 12;

void setup()
{
  pinMode(ledPin, OUTPUT);
  //تنظیم کردن تایمر برای مدت زمان ۱ ثانیه
  Timer1.initialize(1000000);
  //معرفی تابع وقفه به تایمر
  Timer1.attachInterrupt(blink);
}
//تابعع وقفه تایمر
void blink()
{
  ledState = !ledState;
  digitalWrite(ledPin, ledState);
}
void loop()
{
}

 

 


لوازم مورد نیاز


برد آردوینو Mega2560

 


جمع بندی


در این آموزش روش استفاده از کتابخانه تایمر آردوینو را بررسی کردیم. توابع مربوط به برنامه نویسی را در این بخش بررسی کردیم. نمونه ای پروژه با تایمر آردوینو هم اجرا شد. پاسخ به مشکلات رایج در تایمرهای آردوینو هم بررسی شدند.

 

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

 

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

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

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

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

۵۴ دیدگاه

    • سلام خسته نباشید من در اردینیو به همین ترتیب عمل کردم و مشکلی ندارم حالا میخواهم از طریق هدر بورد بلو پیل stm32 وقفه را پیاده بکنم حالا کتابخانه timer1 را در بردهای stm میشه استفاده کرد ممنون میشم راهنمایی بفرمایید

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

  • سلام
    تشکر بابت آموزشتون
    فقط لینک کتابخانه ها از بین رفته
    اگه میشه اصلاحش کنید
    موفق باشید

  • با سلام و تشکر از آموزش خوبتون
    لینک دانلود فایل کتابخانه تایمر دچار مشکله شده.بی زحمت مجددا آپلود بفرمائید

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

  • با سلام و احترام …دوست عزیز میشه راهنمایی کنین این کتابخانه ها را چگونه میشه تهیه کرد …..ایا از سایت خاصی تهیه میکنین …..؟ و ما چگونه میتونیم به این کتابخانه ها دسترسی داشته باشیم

    • درود

      این کتابخانه ها توسط خود بنده ادیت شده بود که به دلیل جابه جایی سرور ها متاسفانه حذف شدند و من نسخه ای از اون ها ندارم

      به زودی دوباره آپلود میشوند

      • سلام دوستان من در پروؤه خودم که با اردوینو مگا کار می کنم به تایمر چهار و پنج نیاز دارم ولی لینک کتاب خانه این تایمر متاستفانه خراب شده از سایت زیر این کتاب خانه را نیز دانلود کردم ولی متاستفانه ازدینو نمی شناسه
        http://forum.arduino.cc/index.php?topic=220775.0
        اگه کسی این کتاب خونه را داره لطفا تو سایت اپلود کنید
        با سپاس فروان

  • […] از کتابخونه ی تایمر ۱ کتاب خوبه برای تایمر های ۴و ۵ نوشت آموزش تایمر آردوینو بخش دوم – دیجی*اسپارک Timer 4 and Timer 5 libraries for Arduino […]

  • سلام.
    تشکر میکنم از مطلب آموزندتون.
    عزیز برای مقدار دهی ۱ ساعته باید این زمان رو به میکروثانیه جلوی تابع نوشت؟

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

    • سلام
      لینک بررسی شد، مشکلی برای دانلود وجود ندارد.
      با کلیک بر روی لینک وارد صفحه محصول آردوینو arduino mega2560 خواهید شد. سپس در قسمت دانلود ، لینک دانلود کتابخانه تایمر ۱۶ بیتی آردوینو قرار گرفته شده است.

    • سلام
      همانطور که در کامنت قبل پاسخ دادم، لینک کتابخانه در آموزش قرار داده شده است. با کلیک بر روی آن وارد صفحه محصول Arduino mega 2560 خواهید شد. سپس در قسمت دانلود لینک دانلود کتابخانه تایمر قرار داده شده است.

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

  • سلام عزیز توروخدا کمکم کن مشکلم راه اندازی کانتر با آردوینو هست من همجااارو زیرو رو کردم چرا جایی صحبت از کانتر آردوینو نیست؟مثلا چجوری میشه وقتی cpu کاره خودشو میکنه تعداد پالسهای ورودی رو شمرد؟؟کانتر یک قسمت خیلیی مهم و پرررکاربرد هست در زمینه avr حتما یجوری میشه راش انداخت مطمئنم شما میتونی کمکم کنی ممنون

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

      volatile int IRQcount;
      int pin = 2;
      int pin_irq = 0; //IRQ that matches to pin 2

      void setup() {
      // put your setup code here, to run once:
      Serial.begin (9600);
      attachInterrupt(pin_irq, IRQcounter, RISING);
      }

      void IRQcounter() {
      IRQcount++;
      }

      void loop() {
      // put your main code here, to run repeatedly:
      IRQcount = 0;
      delay(25);
      int result = IRQcount;
      Serial.print(F(“Counted = “));
      Serial.println(result);
      }

      `

      در کد فوق سنسوری که قصد شمردن تیک‌ های آن را دارید، به پین شماره ۲ که دارای اینتراپت خارجی است متصل کنید.

      • ممنون از و اینکه شما عالی بود مرسی بسیار کا آمد هست برنامه ای که نوشتین. اما بنده مد نظر دارم ک با کانترهای آردوینو کار کنم یعنی پالس رابه پایه های T0یا T1 بدیم چجوری و با چه کدهایی میشه کانتر آردوینو رو راه اندازی کرد. تشکر

        • سلام مجدد ضمن تشکر از شما،
          در این زمینه نویسنده پست، باید به شما پاسخ کامل ارایه دهند، ولی این سوال شما با یک جستجوی ساده قابل رفع است. اقدام کنید، سپس سوالات تکمیلی را از این طریق اعلام کنید.

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

    #include

    //after get card (switch is on)delay 1 second and turn on led
    volatile int card_in_key = 6 ;
    const boolean card_in = 1 ;
    volatile boolean t1_flag = 0;

    void setup()
    {

    delay(100);
    pinMode(card_in_key,INPUT_PULLUP);
    pinMode(7,OUTPUT);
    Timer1.initialize(1000000); // 1 s
    Timer1.attachInterrupt(delay_time); //

    }

    void loop() {
    while ( digitalRead(card_in_key)== card_in )
    {
    delayMicroseconds(50); // add after
    if (t1_flag == 0 )
    {
    Timer1.restart();
    t1_flag = 1;
    }
    }
    delay(100); // delay ms added after the timer 1 not work
    digitalWrite(7 , HIGH );
    Timer1.stop();
    t1_flag = 0 ;
    }

    void delay_time(){

    t1_flag = 1;
    digitalWrite(7 , LOW ) ;
    }

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

  • با سلام و خسته نباشید. لینک مربوط به بخش اول آموزش مشکل داره؟ یا کلاً بخش اول حذف شده؟

  • سلام و خسته نباشید خدمت مدیریت سایت
    من تا حالا دو مرتبه با کتابخانه هایی که شما معرفی کردید با این اررو رو برو شدم
    ( #include expects “FILENAME” or ) و اسم کتابخانه هایی که معرفی میکنم طبق کد های شما رو به رنگ قرمز در نمیاره.
    با اینکه تمام کتابخانه های مورد نیاز رو از همین جا دانلود و به نرم افزار اردوینو اضافه کردم.
    یکی با کتابخانه های تایمر این مسئله بوجود میاد و دیگری با کتابخانه ی oled ممنون میشم کمک کنید.
    پیشاپیش متشکرم:).

  • سلام
    برای تولید زمان یک ثانیه با استفاده از تایمر یک، نیاز به کریستال ساعت هم داریم؟

  • سلام
    من کتابخانه را نصب کردم و برنامه پروژه را هم کپی کردم ولی ظاهرا کتابخانه ای که واسه دانلود گذاشتین با این اموزش همخوانی نداره واسه دانلود کتابخانه مناسب این اموزش میتونید به این لینک مراجعه کنید .https://github.com/PaulStoffregen/TimerOne

  • با سلام وخسته نباشید ببخشید من یک اکواریوم دارم که می خواستم لامپ اون از ساعت ۱۵/۳۰ تا ۲۳/۳۰ روشن وبقیه روز خاموش باشد وبا استفاده از ماژول رله دو کانال هم فاز وهم نول قطع و وصل شود از شما می خواهم به بنده در برنامه نویسی کمک کنید ممنون

  • سلام خسته نباشید من میخوام از کتابخونه ای که قرار دادید استفاده کنم ولی با این ارور مواجه میشم میشه لطفا راهنمایی کنید که علتش چیه؟
    specified folder/zip file does not contain a valid library

  • با سلام.قبلا تایمر ۱ رو نصب کرده بودم و داره روی برد ئثلش ۲۵۶۰ کار میکنه .حالا نیاز به یک تایمر دیگه دارم.هر کدام از تایمر ها رو که تست می کنم این خطا رو میده.

    C:\Users\win 8\Documents\Arduino\libraries\Timer4\Timer4.cpp: In function ‘void startSlowCountingTimer4()’:

    C:\Users\win 8\Documents\Arduino\libraries\Timer4\Timer4.cpp:127:6: error: redefinition of ‘void startSlowCountingTimer4()’

    void startSlowCountingTimer4(void) {

    ^

    C:\Users\win 8\Documents\Arduino\libraries\Timer4\Timer4.cpp:110:6: note: ‘void startSlowCountingTimer4()’ previously defined here

    void startSlowCountingTimer4(void) {

    ^

    • سلام
      تابع startSlowCountingTimer4 را پیشتر تعریف کرده اید، نام آن را عوض کنید تا مشکل حل شود.

  • سلام
    همین کد که با کتابخانه تایمر و برای آردوینو کار می‌کنه رو برای اتمگا ۱۶ یا ۶۴ آپلود میکنیم کار نمیکنه ( پکیج mighty core و minicore و … رو هم نصب کردیم و از اون لحاظ مشکلی نیست )

    ایراد رجیستری مربوط timsk در قسمت ارورها میاد ، لطفا راهنمایی کنید

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

      برای مثال، در آردوینو UNO، تایمر ۱ (Timer1) دارای خروجی PWM است که شما می‌توانید از آن برای تولید PWM با فرکانس معین استفاده کنید. می‌توانید دوره تایمر را تنظیم کنید تا با فرکانس مورد نظر شما هماهنگ شود.
      کد زیر نمونه‌ای از چگونگی تنظیم تایمر ۱ در آردوینو UNO برای تولید PWM با فرکانس ۱۰۰۰ هرتز را نشان می‌دهد. در اینجا TCCR1A و TCCR1B به عنوان ثبات‌های تایمر ۱ استفاده شده‌اند و با تنظیم بیت‌های مربوطه در این ثبات‌ها، حالت PWM مطلوب تنظیم می‌شود. همچنین، OCR1A برای تنظیم مقدار دوره تایمر به‌طور مستقیم استفاده شده است.

      const int pwmPin = 9; // شماره پین مورد نظر برای خروجی PWM

      void setup() {
      pinMode(pwmPin, OUTPUT);

      // تنظیم تایمر ۱ برای تولید PWM
      TCCR1A = _BV(COM1A1) | _BV(WGM11);
      TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);

      // تنظیم مقدار دوره تایمر بر اساس فرکانس ۱۰۰۰ هرتز
      OCR1A = 159; // فرمول: OCR1A = (F_CPU / (2 * prescaler * desired_frequency)) – 1
      }

      void loop() {
      // کد دیگر برنامه را اینجا بنویسید
      }

      شاد و پیروز باشید.