PWM چيست؟!
در بسياري از موارد، ما نياز به كنترل ولتاژ بر روي پايههاي خروجي ميكروكنترلر را داريم. مثلاً اگر بخواهيم سرعت موتور را كنترل كنيم، بايد ولتاژي كه بر روي موتور اعمال ميشود را كنترل كرد. در حقيقت سرعت موتور تقريباًً تابع مستقيمي از ولتاژي است كه بر روي آن اعمال ميشود. يعني اگر ولتاژ كاريِ موتوري (ولتاژ استاندارد براي فعال سازي موتور كه بر روي بدنهي آن نوشته ميشود) 12 ولت باشد، با اعمال ولتاژ 6 ولت روي آن، ميتوانيد سرعت چرخش آن(rpm) را حدوداً به نصف كاهش دهيد.
كنترل سرعت ربات، در همهي سطوح رباتيك اهميت بسيار زيادي دارد، از رباتهاي مسيرياب ساده گرفته تا رباتهاي فوتباليست. ما تا كنون ياد گرفتهايم كه چگونه ميتوان به موتور دستور حركت يا توقف داد، اما راهي براي كنترل سرعت موتور ياد نگرفتهايم.
يادآوري
همانطور كه ميدانيد سطح ولتاژ پايههاي خروجي ميكروكنترلر منطقي است، يعني يك پايهاي كه براي كنترل موتور ربات استفاده ميشود فقط ميتواند 0 يا 1 باشد. ما 2 پايه از ميكروكنترلر را به حركت ربات اختصاص ميدهيم، براي صدور دستور حركت، بايد يك پايه را 0 و پايهي ديگر را 1 كنيم، در اين حالت بين 2 پايهي موتور اختلاف پتانسيل برقرار ميشود و حركت ميكند. اگر هم بخواهيم موتور معكوس بچرخد، بايد پايهاي كه 1 بود 0 ، و پايهاي كه 0 بود را 1 كنيم؛ و براي توقف موتور، بايد هر دو پايه را 0 يا هر دو پايه را 1 كنيم (تا بين 2 پايهي موتور اختلاف پتانسيل 0 ولت باشد). در نتيجه در حالت عادي ما فقط 2 فرمان "حركت" و "توقف" را ميتوانيم به موتورها بدهيم، و ما هيچ كنترلي بر روي سرعت موتور نداريم.
PWM تكنيكي است كه به كمك آن ميتوانيم ولتاژ پايههاي خروجي ميكروكنترلر، و در نتيجه سرعت موتور يا ساير قطعات جانبي كه به ميكروكنترلر متصل ميشود را كنترل كنيم.
PWM مخفف واژهي Pulse Width Modulation و به معناي "مدولاسيون پهناي پالس" است. همانطور كه گفتيم PWM تكنيكي براي كنترل ولتاژِ پايهي خروجي است. حال ببينيم چگونه با اين تكنيك ميتوان ولتاژ خروجي را كنترل كرد.
ميدانيم كه ولتاژ در پايههاي خروجي ميكروكنترلر يا 0 است يا 5 ولت، اما براي كنترل سرعت موتور، بايد بتوانيم حداقل ولتاژ يكي از پايهها را بين 0 تا 5 تغيير دهيم. PWM روشي است تا ما بتوانيم با استفاده از همين پايهي خروجي معمولي، به نوعي ولتاژ را بين 0 تا 5 ولت تغيير دهيم.
در اين روش، ما با سرعت بالايي سطح ولتاژ خروجي را 0 و بلافاصله 1 ميكنيم(مثلاً هزار بار در ثانيه)، نمودار ولتاژ خروجي بر حسب زمان به شكل زير ميشود.

نمودار بالا ولتاژ خروجي اين پايه بر حسب زمان است.
در شكل بالا جمع 2 بازهاي كه با فلشهاي 2طرفه نشان داده شده است، (به عنوان مثال) 10 ميكرو ثانيه است. كه 5ميكرو ثانيه خروجي 1 و سپس 5ميكرو ثانيه 0 ميشود. اما همانطور كه گفته شد، اين عمل هزاران بار در ثانيه تكرار ميشود، اما آيا موتور نيز به همين تعداد در ثانيه روشن و خاموش ميشود؟
جواب منفيست، اتفاقي كه روي ميدهد اين است كه موتور، اين موج را در درون خود به نوعي ميانگين گيري ميكند و در حقيقت آنرا به شكل زير مي بيند:

يعني در واقع موتور اين موج را به صورت يك ولتاژ 2.5 ولت معمولي دريافت ميكند.
به همين ترتيب ميتوان هر ولتاژي بين 0 تا 5 ولت را بر روي خروجي مورد نظر ايجاد كرد. اگر بخواهيم ولتاژي بالاتر از 2.5 ولت داشته باشيم، بايد طول بازههاي زمانياي كه خروجي 1 است را نسبت به بازههايي كه خروجي 0 است بيشتر كنيم. به عنوان مثال براي ايجاد ولتاژ 2.5 ولت، بايد 5 ميكرو ثانيه سطح ولتاژ خروجي 1 باشد، سپس 5 ميكرو ثانيه سطح ولتاژ 0 شود تا موجي به شكل بالا ايجاد شود.
يا به عنوان مثالي ديگر، اگر بخواهيم در خروجي ولتاژ 4 ولت داشته باشيم، بايد بايد 8 ميكرو ثانيه سطح ولتاژ خروجي 1 باشد، سپس 2 ميكرو ثانيه سطح ولتاژ 0 شود، تا ولتاژ پايهي خروجي مورد نظر 4 ولت باشد.
در حقيقت ولتاژ خروجي از رابطهي سادهي زير به دست ميايد:
پس طبق رابطهي بالا،براي ايجاد ولتاژ 4 ولت، ميتوان به جاي استفاده از بازههاي 8 و 2 ميكرو ثانيهاي، از بازههاي 4 و 1 ميكرو ثانيهاي استفاده كرد. (يعني 4ميكرو ثانيه 5ولت، 1 ميكرو ثانيه 0 ولت)
زيرا: 2÷ 8 = 1÷4
نمودار ولتاژهاي 4 ولت و 1 ولت در زير نشان داده شده است:

نمودار نحوهي توليد ولتاژ 4 ولت با تكنيك PWM.

نمودار نحوهي توليد ولتاژ 1 ولت با تكنيك PWM.
حال ببينيم چگونه ميتوان برنامهاي نوشت تا بر روي پايهاي دلخواه از ميكروكنترلر PWM ي براي ولتاژ 4 ولت ايجاد كرد.
هر دستوري كه بر روي خروجيهاي ميكروكنترلر قرار ميگيرد، تا زماني كه دستور بعدي، خروجي را تغيير ندهد، آن خروجي تغييري نخواهد كرد. يعني مثلاً زماني كه پايهاي را 1 ميكنيم، تا زمانيكه با دستور ديگري آن پايه را 0 كنيم، مقدار خروجي آن پايه 1 خواهد ماند. به اين عمل اصطلاحاً Latch كردن ميگويند. ميكروكنترلر همواره اطلاعاتي كه بر روي خروجي قرار ميدهد را Latch ميكند و تا زمانيكه اطلاعات جديد بر روي پايه قرار نگيرد، اطلاعات قبلي را تغيير نميدهد.
در نتيجه، مثلاً اگر ميخواهيم پايهاي را 5 ميكروثانيه 1 وسپس 0 كنيم، كافيست پايهي مورد نظر را 1 كنيم و 5ميلي ثانيه در برنامه تاخير ايجاد كنيم و سپس پايهي مورد نظر را 0 كنيم.
پس وقتي مي خواهيم مثلاَ بر روي پايهي B.4 ، يك PWM براي ولتاژ 2.5 ولت ايجاد كنيم، بايد به شكل زير عمل كنيم.
{
PORTB.4=1;
5 ميكرو ثانيه تاخير
PORTB.4=0;
5 ميكرو ثانيه تاخير
}
در بالا يك حلقهي بينهايت تعريف شده است كه بر روي پايهيB.4، يك PWM براي 2.5 ولت ايجاد ميكند.
مبحث كدويژن، وقفه و PWM :
ابتدا با توابعي كه براي ايجاد وقفه در اجراي دستورات برنامه توسط CodeVision براي كاربران در نظر گرفته شده آشنا ميشويم.
همانطور كه در ميحث پيش ديديم، در قسمتهايي از برنامه ممكن است نياز پيدا كنيم تا براي لحظاتي روند اجراي دستورات را متوقف كنيم. CodeVision براي اين كار توابعي را از پيش تنظيم كرده است. (در مورد مبحث «توابع» در زبان C در آينده مفصل توضيح خواهيم داد.)
delay :
براي ايجاد تاخير در روند اجراي دستورات، CodeVision دو تابع زير را در اختيار ما قرار داده است.
delay_us( );
تابع ()delay_ms براي ايجاد تاخيرهايي در حد ميلي ثانيه به كار ميرود. در داخل پرانتز، يك عدد صحيح مثبت مينويسيم كه نشان دهندهي اندازهي تاخير مورد نيز ما بر حسب ميلي ثانيه است. به بيان سادهتر، مثلاً اگر داخل پرانتز عدد 100 را بنويسيم، روند اجراي برنامه به اندازهي 100 ميلي ثانيه در همان خط متوقف خواهد شد.
تابع ()delay_us براي ايجاد تاخيرهايي در حد ميكروثانيه به كار ميرود. نحوهي استفاده از آن دقيقاً مانند ()delay_ms است.
به عنوان يك مثال عملي،همان برنامهي ايجاد PWM 2.5 ولت را با استفاده از توابع delay بازنويسي ميكنيم.
{
PORTB.4=1;
delay_ms(5); // 5 milliseconds delay
PORTB.4=0;
delay_ms(5); //5 milliseconds delay
}
تنها نكتهي بسيار مهم در استفاده از توابع delay اضافه كردن هِدِرفايل Header file باعنوان delay.h به برنامه است.( در مورد هدر فايلها هم در آينده توضيح خواهيم داد، اما در اين مبحث هيچ توضيحي در مورد آن نميدهيم تا از بحث اصلي يعني PWM منحرف نشويم.) براي اين كار، جمله
كه اولين جملهي برنامهي شما است را پيدا كنيد. (اين جمله را CodeWizard در برنامهي شما نوشته است). حال كافيست اين جمله را درست زير ان تايپ كنيد:
دقت كنيد كه اين دستور نيازي به « ; » ندارد !!
با آموختن تابع delay، ديگر شما ميتوانيد هر ولتاژي را كه ميخواهيد بر روي پايههاي خروجي ايجاد كنيد. البته دوستان دقت داشته باشند كه ولتاژي كه با تكنيك PWM شبيه سازي ميشوند، در حقيقت ولتاژ خاصي نيستند و فقط شبيه سازي شدهي ولتاژهاي مختلف هستند. هرچند كه در راهاندازي موتورها اين تكنيك بسيار كارآمد است، اما بايد دقت نظر لازم را در استفاده از اين تكنيك در ساير موارد را داشته باشيد.
همانطور كه ميدانيد موتورهاي متعارفي كه براي ساخت رباتها استفاده ميشود،ممكن است ولتاژهاي كاري مختلفي داشته باشند (مثلاً 12ولت، 24 ولت، 6 ولت و ...) و براي راهاندازي آنها بايد از درايورهاي موتور مثل L298 استفاده كنيم. سوالي كه ممكن است پيش آيد اين است كه وقتي ما ميكروكنترلر را به درايورهاي موتور(مثل L298) وصل ميكنيم و از تكنيك PWM براي كنترل سرعت موتور استفاده ميكنيم، چه وضعيتي پيش ميآيد؟ مثلاً وقتي ما PWM مربوط به ولتاژ 2.5 ولت را توليد ميكنيم، درايور ما چه عكس العملي نشان ميدهد؟ آيا ولتاژ 2.5 ولت بر روي پايههاي موتور قرار ميگيرد؟
براي پاسخ دادن به اين سوال بايد به ساختار PWM دقت كنيم، ما وقتي PWM مربوط به 2.5 ولت را توليد ميكنيم، در حقيقت سطح ولتاژ خروجي را با فواصل زماني برابر 0 و 1 ميكنيم، پس اگر اين خروجي را، به ورودي L298 وصل كنيم(مثلاً پايهي 7)، L298 نيز موتور را با همين الگو كنترل ميكند و ولتاژي كه به موتور ميدهد را 0 و 1 ميكند. و همانطور كه ميدانيد، L298 هر ولتاژي كه بر روي پايهي شمارهي 4 آن قرار گرفته باشد را بر روي موتور قرار ميدهد(اگر ولتاژ كاري موتور 12 ولت باشد، بايد اين پايه به 12 ولت متصل شود) . پس جواب سوال بالا منفيست!!! وقتي ما PWM مربوط به 2.5 ولت را توليد ميكنيم، در حقيقت سطح ولتاژ خروجي در 50 درصد زمان 1 و بقيهي زمان 0 است. پس اگر همان طور كه در بالا اشاره شد، اين PWM به درايوري مثل L298 داده شود، و ولتاژ پايهي 4 ِ آن 12ولت باشد، درايور، ولتاژ 6 ولت را به موتور ميدهد. در نتيجه اهميتي ندارد چه ولتاژي بر روي پايهي 4 ِ L298 قرار گرفته باشد، وقتي كه ما PWM مربوط به 2.5 ولت را توليد ميكنيم، درايور ولتاژي كه به موتور ميدهد را 50 درصد ميكند. در نتيجه بهتر است از اين به بعد به جاي آن كه بگوييم PWM مربوط به 2.5 ولت، بگوييم PWMااا50 درصد. يا به جاي PWM ِمربوط به 1 ولت، بگوييم PWMااا20 درصد
PWM در ميكروكنترلرهاي AVR :
انجام تنظيمات اوليه براي استفاده از PWM براي راه اندازي موتور درميكروكنترلرهاي AVR كمي پيچيده است، اما در اينجا هم CodeWizard به كمك ما آمده است و كار را كمي سادهتر كرده است. ما در ادامه مبحث، تنظيمات CodeWizard را بدون توضيح مطرح مينماييم، زيرا توضيح هر بخش از آن نيازمند مقدمات مفصلي است و تاثير چنداني هم در روند كار ما ندارد، اما به دوستاني كه ميخواهند ميكروكنترلر را كاملاً حرفهاي دنبال كنند، پيشنهاد ميكنم از منابعي كه قبلاً معرفي شده است، مطالب را تكميل كنند.
به هر حال دوستان عزيز با انجام اين تنظيمات اوليهي مختصر در CodeWizard، ميتوانند از الگويي به مراتب سادهتر از آنچه تا به حال آموختهايم، براي ايجاد PWM براي هدايت موتورهاي ربات استفاده نمايند.
در ميكروكنترلرهاي خانوادهي AVR، نيازي نيست در هربار استفاده از PWM ، چندين خط برنامه بنويسيم. در ATmega16 چهارپايهي مشخص از آي سي به اين موضوع اختصاص داده شده است. يعني اين چهارپايه علاوه بر كاربردهاي معمولي خود، اين قابليت را دارند كه در مواقع لزوم براي توليد PWM استفاده شوند.
حال سوال اينجاست كه اين چهارپايه چه تفاوتي با بقيهي پايههاي خروجي آيسي دارند كه آنها را از ساير پايههاي خروجي ميكروكنترلر متمايز ميسازد؟
براي اين چهارپايه نيازي به اجراي الگويي كه تا به حال براي ايجاد PWM فراگرفتهايد نيست. در اين روش، فقط شما بايد يك عدد صحيح بين 0 تا 255 انتخاب كنيد، و طبق الگوي زير آن را در برنامهي خود بنويسيد.
يك عدد صحيح بين 0 تا 255 = نام رجيستر مربوطه ;
اين عدد، بيانگر توان PWM شماست، و شما توان PWM ِ مورد نياز خود را با اين عدد مشخص ميكنيد. كه 255 بالاترين توان و مربوط بهPWMااا100 درصداست، و 0 پايينترين توان و مربوط به PWMااا0 درصد است.
به عنوان مثال اگر اين عدد را 128 قرار دهيد، همان PWMااا50 درصد را ايجاد كردهايد. يا مثلا اگر اين عدد 51 باشد، PWMااا20 درصد بر روي پايه قرار دادهايد.
رجيسترهاي مربوط به اين 4 پايه :
همانطور كه ميدانيد، براي پايههايي كه در CodeWizard به صورت خروجي تعريف شدهاند، رجيستري به نام «PORTx» وجود دارد كه هر مقداري در اين رجيستر قرار داده شود، مقدار پايههاي خروجي متناظر با آن رجيستر را مشخص ميكند.
در اين مبحث با 4 رجيستر ديگر آشنا ميشويم، كه وقتي تنظيمات مربوط به PWM ِ موتور در CodeWizard را انجام دهيم، هر مقداري كه در آنها ريخته شود، توان PWM پايهي متناظر را مشخص ميكنند.
اين رجيسترها OCR0، OCR1AL، OCR1BL و OCR2 نام دارند كه به ترتيب، متناظر پايههاي PB.3، PD.5، PD.4 و PD.7 هستند.
پس مثلاً اگر در بخشي از برنامهي خود بنويسيم :
در حقيقت بر روي پايهي PB.3 ميكروكنترلر، PWMااا50-درصد به وجود آوردهايم.
به مثالهاي ديگري توجه كنيد: (توضيح هر دستور در جلوي دستور و بعد از // آورده شده است)
OCR1AL=51; // 20% Duty Cycle on PD.5
OCR1BL=255; //100% Duty Cycle on PD.4
OCR2=0; //0% Duty Cycle on PD.7
در ادامه اين مبحث، در مورد نحوهي انجام تنظيمات اوليه جهت توليد PWM در CodeWizard را توضيح خواهيم داد....
همانطور كه در مباحث قبلي هم متذكر شديم، در اينجا مجال نيست تا تمام مباحث مربوط به PWM و تايمرها را باز كنيم و مفصل به آنها بپردازيم، به همين خاطر در اين بخش قسمتي از تنظيمات در CodeWizard را بدون توضيح آموزش ميدهيم.
براي انجام تنظيمات به كمك CodeWizard،پس از انجام تنظيمات ساير لبهها (مانند Ports، Chip و .... ) در CodeWizard، لبهي Timers را باز كنيد.
همانطور كه ميبينيد ميكروكنترلر ATmega16 داراي 3 تايمر مجزا است و ما براي توليد PWM بايد از اين تايمرها استفاده كنيم. تايمرها كاربردهاي متعددي دارند، و يكي از مهمترين مباحث در ميكروكنترلر هستند، ما هم در مورد تايمرها در جلسات آينده مفصل توضيح خواهيم داد. اما در اين مبحث فقط استفاده از تايمرها را براي ايجاد PWM براي كنترل موتورهاي ربات استفاده ميكنيم.
Timer0
Timer0 مربوط به رجيستر OCR0 است و بايد به شكل زير تنظيم شود:

نكتهاي كه در مورد تنظيم هر 3 تايمر بايد رعايت شود، اين است كه در بخش "Clock Value" بايد پايينترين فركانس را انتخاب كنيد. در اين مورد توضيح مختصري ميدهم، ولي اگر عزيزان اين بند را متوجه نشوند اهميت زيادي ندارد: اندازهي فركانسي كه انتخاب ميكنيد در اين بخش، در حكم اندازهي همان Delayهايي است كه براي توليد PWM به صورت عادي (كه در ابتداي مبحث قبل توضيح داديم) استفاده ميكنيم. يعني در حقيقت طول موج را در نمودار ولتاژ بر زمان تعيين ميكند. هر چه فركانس بالاتري را انتخاب كنيد، طول موج كمتر ميشود. در عمل ديده شده كه هر چه فركانس پايينتر باشد و در نتيجه طول موج بيشتر باشد، موتورها بهتر هدايت ميشوند. به همين خاطر در بالا گفته شد كه دوستان پايينترين فركانس را براي "Clock Value" انتخاب كنند.
Timer1
تايمر1 بايد به شكل زير تنظيم شود. دقت كنيد كه ممكن است در بخش Clock Value شما فركانسي كه در شكل زير نمايش داده شده است را در گزينهها نداشته باشيد، ولي همانطور كه گفته شد فقط مهم اين است كه شما پايينترين فركانس را انتخاب كنيد.

همانطور كه ميبينيد، تايمر1 داراي دو خروجي مجزا است كه رجيسترهاي مربوط به آنها OCR1AL و OCR1BL هستند.
Timer2
تايمر2 ميز به شكل زير تنظيم ميشود و مانند تايمر0 فقط يك خروجي دارد.

Watchdog
يا سگ نگهبان (Watch Dog) نيز يكي از مباحث مربوط به تايمرهاست كه در ادامه بحث به آن خواهيم پرداخت.
حال كه همهي تنظيمات لازم را در CodeWizard انجام دادهايد، "Generate, Save and Exit" انتخاب كنيد و وارد فضاي برنامه نويسي شويد.
نكتهي بسيار مهم:
براي كنترل هر موتور، علاوه بر يك پايهي PWM، يك خروجي معمولي نيز لازم داريم تا بتوانيم به وسيلهي اين دو پايه و به كمك درايور موتور، اختلاف پتانسيل مورد نظر را بر روي دو پايهي موتور برقرار كنيم. اين 2 پايه را به دو پايهي ورودي L298 متصل ميكنيم و دو پايهي موتور را نيز، به دو پايهي خروجي L298 متصل ميكنيم. حال ميتوانيم موتور را به وسيلهي ميكروكنترلر با سرعت دلخواه كنترل كنيم. به عنوان مثال اگر بخواهيم موتور ما تقريباً با سرعت نصف بچرخد، و پايههاي PD.6 و PD.7 (مربوط به رجيستر OCR2) را به L298 متصل كرده باشيم،برنامهي زير را بايد بنويسيم:
PORTD.6=0;
و اگر بخواهيم موتور ما با همين سرعت و در جهت معكوس بچرخد، مينويسيم:
PORTD.6=1;
براي درك اين موضوع دقت كنيد كه در اين حالت چه ولتاژي توسط L298 بر روي موتورها قرار داده ميشود. همانطور كه ميدانيد، سرعت و جهت چرخش موتور وابسته به اختلاف ولتاژي است كه بر روي پايههاي موتور قرار داده ميشود.
تا به اينجا مباحث پايهاي در ميكروكنترلرهاي AVR مطرح شده است و همين آموختههاي دوستان، نيازهاي اوليهي شما عزيزان را براي ساخت رباتهاي نسبتاً حرفهاي برطرف ميسازد.
يكي از مهمترين فوايد استفاده از ميكروكنترلر در ساخت رباتهاي مسيرياب، استفاده از قابليت PWM براي هدايت موتورهاي ربات است. اما به چه صورت از PWM استفاده ميكنيم؟

به شكل بالا نگاه كنيد، در همانطور كه مي دانيد در اين ربات ها 3 سنسور هر طرف را با همديگر ANDمنطقي ميكنيم و اگر هر يك از اين 3 سنسور خط را تشخيص داد، موتور همان سمت را متوقف ميكنيم تا به اين ترتيب ربات خط را تعقيب كند.
اما در رباتهاي مسيرياب ميكروكنترلر دار، ما ميتوانيم براي هر سنسور، به طور مجزا دستوري به موتور بدهيم. براي درك اين موضوع مجدد به شكل بالا نگاه كنيد، اين نماي كلي يك ربات از زير است. سنسورهاي آن را به ترتيب از چپ به راست، از 7 تا 1 شماره گذاري ميكنيم.
همانطور كه به خاط داريد در رباتهاي بدون ميكروكنترلر، تفاوتي نداشت كه سنسور 1 يا 2 يا 3 كداميك خط را بيابند، هر كدام خط را تشخيص ميداد، موتور سمت چپ خاموش ميشد. اما در رباتهاي ميكروكنترلر دار، ما ميتوانيم تعيين كنيم كه مثلاً اگر سنسور شمارهي 3 خط را ديد، موتور سمت چپ به طور كامل متوقف نشود، بلكه سرعت آن به نصف كاهش پيدا كند. اين كار به نظر هم منطقي ميرسد، زيرا سنسور شمارهي 3 و 5 تا خط فاصلهي كمي دارند و نياز نيست وقتي خط را تشخيص ميدهند به طور كامل موتور متوقف شود، بلكه فقط كافيست سرعت موتور كمي كاهش پيدا كند تا ربات به تدريج به روي خط باز گردد. اين عمل باعث ميشود حركت ربات نرمتر و دقيقتر بشود و در مجموع سرعت ربات بالاتر برود.
حال اگر سنسور شمارهي 2 خط را ببيند، يعني شرايط كمي خطرناكتر شده و ربات ممكن است از خط خارج شود، پس ميتوانيم در اينجا به موتور دستور توقف كامل را بدهيم تا ربات با سرعت بيشتري به مسير مسابقه بازگردد. و در نهايت اگر سنسور شمارهي 1 خط را ببيند، يعني ربات در آستانهي خروج از مسير مسابقه قرار گرفته است و بايد با حداكثر توان ربات را به مسير مسابقه بازگرداند. براي اين كار به موتور سمت چپ دستور باز گشت به عقب را ميدهيم. اين كار بيشترين سرعت ممكن براي چرخش ربات را فراهم ميسازد و ربات با سرعت زيادي به زمينه مسابقه باز ميگردد.
در زير بخشي از برنامهي يك ربات مسيرياب پيشرفته، كه فقط براي سنسورهاي سمت چپ و طبق توضيحات بالا نوشته شده است را ميبينيد. همانطور كه ميدانيد ما نياز به 3 پايه به عنوان ورودي براي دريافت وضعيت سنسورهاي سمت چپ، و يك پايهي خروجي و يك PWM براي كنترل موتور سمت چپ داريم كه به ترتيب زير هستند:
PA.0 براي سنسور شمارهي 1
PA.1 براي سنسور شمارهي 2
PA.2 براي سنسور شمارهي 3
PD.6 و OCR2 براي كنترل موتور چپ
PD.3 و OCR1BL براي كنترل موتور راست
حالا به برنامه دقت كنيد:
(if (PINA.0==0
{
PORTD.6=0;
OCR2=127;
PORTD.3=0;
OCR1BL=255;
}
(if (PINA.1==0
{
PORTD.6=0
OCR2=0
PORTD.3=0;
OCR1BL=255;
}
(if (PINA.2==0
{
PORTD.6=1;
OCR2=0;
PORTD.3=0;
OCR1BL=255 ; //end
{
به همين منوال بايد براي سنسورهاي سمت راست هم برنامه را ادامه دهيد. دقت كنيد كه بايد حتماً قبل از نوشتن برنامه، از داخل CodeWizard، تنظيمات اوليه را انجام دهيد.
اگر اين سنسور خط را تشخيص دهد، بيانگر اين است كه ربات در وضعيت مناسبي نسبت به خط قرار دارد و هر 2 موتور با تمام توان به سمت جلو حركت ميكنند. اگر پايهي PA.3 را نيز به سنسور وسط اختصاص دهيم، براي اين سنسور نيز داريم:
(if (PINA.3==0
{
PORTD.6=0;
OCR2=255;
PORTD.3=0;
OCR1BL=255;
}