السلام عليكم و رحمة الله...
نستكمل اخوانى شرح التحكم فى السيرفو موتور بطريقة اكثر سهوله و دقة حيث يمكنكم بهذة الطريقه التحكم فى محرك السيرفو بدقة اعلى من زى قبل.
نعلم من الشروحات السابقة اننا اذا اردنا للسيرفو ان يتحرك لزاويه معينة درجة يجب اعطاءة نبضة مدتها من 0.7 ms الى 2.3 ms ليتحرك من 0الى 180 درجة.
ولكن كانت المشكلة هى اننا نريد تغيير قيمة النبضة باستمرار لضمان التحكم الدقيق فى زاوية الدوران وكان ذلك غير ممكن عند استخدام امر التأخير الزمنى
.فكنا نلجا الى الاسلوب الذى تم شرحة سابقا.
اليوم اقدم لكم امر جديد يمكننا بسهولة من التحكم فى التاخير الزمنى باستمرار فى الازمنة الصغيرة (ميكرو ثانية) بسهولة.
امر التاخير الزمنى
يمكننا عمل تاخير زمنى يعتمد على زمن التعليمات الخاصة بمذبذب الميكرو كنترول.
فمثلا عند استخدام كريستاله 4 Mega Hertz فان زمن التعليمة يكون 1 ميكرو ثانية .
ولعمل تاخير زمنى بقيمة 100 ميكرو ثانية تكون القيمة المكتوبة داخل امر التاخير هى
حيث ان المكتبة الداخلية تقوم بضرب القيمة المكتوبة * 10 .
وبالتالى اذا اردنا اعطاء نبضة لمدة 1.7 ميللى ثانية تكون القيمة داخل امر التاخير هى
كود:
1700 (µS)/10=170
So,
Delay_Cyc (170);
اذن لعمل برنامج يمكننا فية تغيير عرض نبضة باستمرار يمكننا عمل متغير نضعة داخل امر التاخير و نقوم بزيادتة باستمرار .
الان مطلوب برنامج يحرك السيرفو الى زاوية قيمتها 90 درجة.
بالتالى نحتاج نبضه لمدة 1500 ميكرو ثانية عالى و نبضة قيمتها 18500 منخفض حتى يكون التردد 50 هيرتز كما نعلم وبالتالى يكون البرنامج بالشكل التالى.
كود:
while(1){
servo1=on;
Delay_Cyc(150); // delay=150*10=1500 us=1.5 ms
servo1=off ;
delay_ms(1850);
}
البرنامج التالى يمكننا من التحكم فى السيرفو بدقة عالية لكل درجة
كود:
while(1){
delay=i*10;
delay=delay+n;
servo1=on;
Delay_Cyc(delay); // delay=70*10=700 us=.7 ms
servo1=off;
delay_ms(20);
if(sw1==pressed){delay_ms(200);
n++;
if(n>=161){n=0;}
}}
الشرح:
نريد زيادة المتغيرdelay بحيث يزداد من 70 الى 230 بمقدار الوحدة.
قمنا بفرض متغيرين n,m .
عند الضغط على المفتاح n يزداد المتغير يمقدار الوحدة
if(sw1==pressed){delay_ms(200);
n++;
المتغير i القيمة الابتدائية له هى 7 لاحظ عند التعويض يكون كما يلى:
كود:
delay=i*10; //delay=70
delay=delay+n ; // delay =70+1=71
و عند التعويض فى الناتج النهائى فى دالة التاخير
كود:
Delay_Cyc(delay); كما قلنا الدالة تقوم بضرب المتغير داخلها *10 يكون الناتج التاخير النهائى هو 701 ميكرو ثانية اى 0.71 ميللى ثانية وبالتالى استطعنا الزيادة بمقدار بسيط جدا.
الشرط الاخير اذا كانت قيمة n اكبر من او تساوى 161 نقوم بتصفير القيمة مرة اخرى ولكن لماذا هذة القيمة بالذات؟؟
لاننا نريد ان تكون قيمة التاخير الزمنى بالميكرو ثانية محصورة مابين 700 و 2300 و الفرق بينهم هو عدد الخطوات المطلوب زيادتها مقسومة على 10 .
[
LEFT]
كود:
2300-700=1600/10=160 n(max)=160
[/LEFT]
وبالتالى يكون الكود النهائى للبرنامج كالتالى
كود:
// servo motor control
// author :ashraf kamal elhanahmy
// 14-april-2012
# define servo1 portb.f1
# define servo1_dir trisb.f1
# define servo2 portb.f3
# define servo2_dir trisb.f3
# define sw1 portb.f0
# define sw2 portb.f2
# define sw1_dir trisb.f0
# define sw2_dir trisb.f2
# define pressed 0
# define output 0
# define input 1
# define on 1
# define off 0
char i;
char n; unsigned short delay;
void init(){
servo1_dir=output;
servo2_dir=output;
sw1_dir=input;
sw2_dir=input;
}
void main() {
init(); i=7;
n=0;
while(1){
delay=i*10;
delay=delay+n;
servo1=on;
Delay_Cyc(delay); // delay=70*10=700 us=.7 ms
servo1=off;
delay_ms(20);
if(sw1==pressed){delay_ms(200);
n++;
if(n>=161){n=0;}
} } }
تحميل الكود و المحاكاة و الهيكس
على الرابط
هنا