بسم الله الرحمن الرحيم
في بعض التطبيقات قد نحتاج لتحديد سرعة دوران المحـرك او اتجاه دورانه او مقدار الازاحـة , يوجد العديد من الحساسات التي قد تستخدم لهذا الغرض لكن غالباً مـا نستخدم المشفر البصري ( optical encoder ) .
الحساس ببساطة عبارة عن مصدر ضوء و حساس ضوء , يفصل بينهم قرص مثبت على محور الدوران في المحرك ,
و القرص يحتوي على عدد معين من الثقوب التي تسمح بمرور الضوء عبرها .
و عند دوران المحرك يمر الضوء بشكل متقطع من خلال القرص و بالتالي تنتج سلسلـة من النبضات كهربائية يمكن قراءتها من خلال حساس الضوء .
هذا النوع من الحساسات يسمى المشفر التزايدي ( incremental encoder ) , لاحظ انه يتكون من مسار واحد من الثقوب , و الناتج منه هو سلسلة نبضات كهربائية ! و هذا النوع سنستخدمه في التجربة !
لكن هناك نوع آخر يسمـى المشفر المطلق ( absolute encoder ) , القرص فيه اكثر من مسار للثقوب ( و هناك اكثر من مستقبل ضوئي ) , بحيث يكون الناتج كـلـمة رقمية و بالتالي يمكن تحديد موضع محور الدوران مباشرة , و تعتمد دقته على عدد المسارات الموجودة في القرص .
لكن كيف يمكن حساب السرعة من خلال هذا الحساس ؟
بالعودة للمشفر التزايدي ( incremental encoder ) اذا كان عدد الثقوب الموجود في القرص = 10 مثلاً .. هذا يعني انه عند كل 10 نبضات خارجة من الحساس ,يكون المحرك قد اكمل دورة كاملة !
و بالتالي لقياس سرعة دوران المحرك , يجب حساب عدد النبضات الناتجة من الحساس خلال مدة معينة ( ثانية واحدة مثلاً ) !
و لنفرض ان عدد النبضات الناتجة ( خلال الثانية ) = 50 نبضة ! ثم نقسمه على عدد الثقوب في القرص !
لتكون سرعة المحرك = 5 دورات لكل ثانية !
لتكون سرعة المحرك = 5 دورات لكل ثانية !
تحتاج في هذه التجربة الـى :
• متحكم اردوينو ( من اي نوع ) .
• مشفر بصري ( optical encoder ) .
يمكنك شرائـه من هــنــا .
• قرص مثقب ( خاص بالحساس ) .
• محرك DC من اي نوع .
قم بتثبيت القرص على محور دوران المحرك و ثبت الحساس بحيث يفصل القرص بين المستقبل و المرسل !
و لكتابة برنامج يقوم بعد النبضات يجب استخدام المقاطعات ( Interrupt ) , لأنه في البرنامج العادي قد تُـفقد بعض النبضات بسبب التأخير الذي تسببه باقي الاوامر , لكن في حالـة الـ Interrupt عند وجود اي نبضة على مدخل الاردوينو يتم ايقاف البرنامج الرئيس و ينفذ برنامج خاص بالـInterrupt ( نكتب فيه كود لعد النبضات ) و بالتالي نضمن عدم فقد اي بيانات !
لكن المنافذ الخاصة بالـ Interrupt محدودة في الاردوينو ( حسب النوع ) و الجدول التالي يبينها :
استخدمنا في هذه التجربة اردوينو من نوع UNO و لنصل الحساس مع Interrupt 0 ( أي مع المدخل 2 في الاردوينو ) !
بعد توصيل الدارة بشكل كامل , نكتب البرنامج التالي :
//Ali Hadabeen 4/1/2014
volatile int slits = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
attachInterrupt(0, blink, FALLING);
for (int counter = 0; counter < 100; counter++) { delayMicroseconds(10000); }
detachInterrupt(0);
int rpm = slits * 3;
/* note that the encoder disk has 20 slits
slits per minute = ( slits * 60 )
Revolutions per minute = slits per minute / 20
rpm = slits * 60/20
= slits * 3
*/
Serial.println("rpm = ");
Serial.println(rpm);
delay(100);
slits = 0;
}
void blink()
{
slits++ ;
}
لاحظ اننا استخدمنا امر delayMicroseconds فقط , لأن باقي اوامر التأخير تعتمد على الـ Interrupt و بالتالي لن تعطينا قيم دقيقة !
و اقصـى قيمة يمكن ان للأمر delayMicroseconds ان يعطيها هي 16000 , و بالتالي نحتاج لتكرار الامر عشرات المرات حتى نحصل على تأخير مقداره 1 ثانية .
مـصــادر
• farahat library .
أخي أولا كل الشكر والتقدير للمجهود ولاكني أود منك تحليل أدق للكود حتى يمكنني تنفيذه وشرح التحكم في الموتور بإعطاء قيمه معينه مثلا 10 لفات في الدقيقه وشكرا
ردحذفأخي أولا كل الشكر والتقدير للمجهود ولاكني أود منك تحليل أدق للكود حتى يمكنني تنفيذه وشرح التحكم في الموتور بإعطاء قيمه معينه مثلا 10 لفات في الدقيقه وشكرا
ردحذفلا شكر على واجب
ردحذف