هدف از این آموزش راه اندازی واحد PWM میکروکنترلر AVR به زبان C توسط مجموعه آموزشی AVR WIZARD میباشد. ( شما می توانید موتورهای سروو مشابه را به این روش راه اندازی نمایید )
قطعات مورد نیاز:
سروو موتور
موتورهای سروو مدت زیادی است که در بسیاری از کاربردها مورد استفاده قرار می گیرند. اندازه آنها کوچک است اما دارای گشتاور بالا و بسیار کارآمد هستند. این ویژگی به آنها امکان استفاده در اتومبیل های اسباب بازی ، ربات ها و هواپیماهای کنترل شده از راه دور یا رادیویی را می دهد. موتورهای سروو همچنین در کاربردهای صنعتی ، رباتیک ، خطوط تولید ، داروسازی و خدمات غذایی استفاده می شود. اما این موتورها چطور کار می کنند؟
مدار سروو درست در داخل موتور ساخته می شود و دارای شافت قابل تنظیم است ، که معمولاً به یک دنده تعبیه می شود موتور با یک سیگنال الکتریکی کنترل می شود که میزان حرکت شافت را تعیین می کند.
نحوه کنترل سروو موتور
سروها با ارسال پالس الکتریکی با عرض متغیر یا مدولاسیون عرض پالس (PWM) از طریق سیم کنترل کنترل می شوند. حداقل ، حداکثر و میزان تکرار پالس برای هر یک وجود دارد. یک موتور سروو معمولاً فقط می تواند 90 درجه در هر جهتی و در کل 180 درجه حرکت کند. موقعیت خنثی موتور به عنوان موقعیتی تعریف می شود که سروو همان مقدار چرخش بالقوه را در هر دو جهت عقربه های ساعت یا خلاف جهت عقربه های ساعت داشته باشد.
PWM ارسال شده به موتور موقعیت شافت را تعیین می کند و بر اساس مدت زمان پالس ارسال شده از طریق سیم کنترل روتور به موقعیت مورد نظر تبدیل می شود. موتور سروو انتظار دارد که هر 20 میلی ثانیه (میلی ثانیه) یک پالس را ببیند و طول پالس تعیین می کند که موتور تا چه اندازه دور می شود. به عنوان مثال ، یک پالس 1.5ms باعث می شود موتور به حالت 90 درجه برگردد. کوتاهتر از 1.5ms ، آن را در جهت خلاف جهت عقربه های ساعت به سمت موقعیت 0 درجه حرکت می دهد و هر طولانی تر از 1.5ms ، سرو را در جهت عقربه های ساعت به سمت موقعیت 180 درجه می چرخانند.
هنگامی که به این سرووها دستور داده می شود حرکت کنند ، آنها به سمت موقعیت حرکت می کنند و آن موقعیت را نگه می دارند. اگر یک نیروی خارجی در حالی که سروو در حال نگه داشتن موقعیت است ، علیه سروو فشار وارد کند ، سروو از حرکت در خارج از آن موقعیت مقاومت می کند. حداکثر نیرویی که سروو قادر به اعمال آن است ، نرخ گشتاور سروو نام دارد. سروو موقعیت خود را برای همیشه حفظ نخواهد کرد. پالس موقعیت باید تکرار شود تا به سروو دستور دهد تا در موقعیت خود قرار بگیرد.
نحوه اتصال سروو موتور به برد ROBO SHIELD از مجموعه آموزشی AVR WIZARD
در برد شیلد ربات موسوم به ROBO SHIELD از مجموعه آموزشی AVR WIZARD کافی است موتور را به ترمینال خروجی SERVO متصل کنیم.
نحوه برنامه نویسی و کنترل سروو موتور
ابتدا باید یک تایمر در مد WGM ( Waveform Generation Mode ) را انتخاب کنیم که برای سروو مناسب باشد. در مرحله بعد ، باید دوره PWM را انتخاب کنیم که با سروو کار کند. سرووهایی که در اینجا استفاده می شود یک دوره 20 میلی ثانیه ای را می پذیرند و ما برای ایجاد این دوره از ثبت ICR1 استفاده خواهیم کرد. برای انجام این کار ، ما باید یک prescaler را تعیین کنیم تا تایمر از منبع کلاک میکروکنترلر به درستی استفاده کند. حال باید PWM را تنظیم کنیم که در حالت صحیح معکوس یا غیر معکوس باشد در آخر ، ما نیاز داریم که از کدام OCR 1A یا 1B استفاده کنیم.
در ادامه نحوه کنترل سروو موتور را در تابع MAIN مشاهده می کنید:
#include
#include
// Alphanumeric LCD functions
#include
int speed=0;
int stop;
int buff1 = 0;
int buff2 = 0;
// Declare your global variables here
void Servo_Init(char numb,int angle_1,int angle_2)
{
if((buff1== angle_1) && (buff2== angle_2)) stop=1;
else stop=0;
buff1 = angle_1; // store pre value
buff2 = angle_2; // store pre value
angle_1 = angle_1*(933/89) + 800 ; // change degree to value for servo
angle_2 = angle_2*(933/89) + 800 ; // change degree to value for servo
switch (numb)
{
case 1 :
if(angle_2== angle_1)
{
if((OCR1B>=angle_1))
{
for (speed=OCR1B;speed>=angle_1;speed--)
{
OCR1B=speed;
delay_ms(2);
}
}
else
{
for (speed=OCR1B;speed<=angle_1;speed++)
{
OCR1B=speed;
delay_ms(2);
}
}
}
else
{
if(stop ==0 )
{
if(angle_1>angle_2)
{
if((OCR1B>=angle_1))
{
for (speed=OCR1B;speed>=angle_1;speed--)
{
OCR1B=speed;
delay_ms(2);
}
}
else
{
for (speed=OCR1B;speed<=angle_1;speed++)
{
OCR1B=speed;
delay_ms(2);
}
}
for (speed=angle_1;speed>=angle_2;speed--)
{
OCR1B=speed;
delay_ms(2);
}
}
if(angle_2>angle_1)
{
if((OCR1B>=angle_1))
{
for (speed=OCR1B;speed>=angle_1;speed--)
{
OCR1B=speed;
delay_ms(2);
}
}
else
{
for (speed=OCR1B;speed<=angle_1;speed++)
{
OCR1B=speed;
delay_ms(2);
}
}
for (speed=angle_1;speed<=angle_2;speed++)
{
OCR1B=speed;
delay_ms(2);
}
}
}
}
break;
}
}
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRA=(0<