انتظر لحظة... موقع T3STO™Tech التعليمي

Top Ad unit 728 × 90

الجديد

كل

المؤقتات الزمنية و التحكم اللحظي بمنافذ الأردوينو



السلام عليكم ورحمة الله تعالى وبركاته .

كيف تجعل منافذ الأردوينو أكثر إستجابة ؟؟ ذا السؤال الذي طالما يطرح علي في رسائل المتابعين على صفحتي الشخصية ، فهل يمكنني ذلك ؟؟ هل يمكنني ربط حساسات كثيرة مثل الالتراسونيك و الاشعة تحت الحمراء و المحركات مع  الأردوينو و جعلها تعمل بشكل واحد و بدون تأخير زمني ملحوظ ؟

في البداية يجب أن أشير إلى أن المتحكمات الأصغرية MCU برمجتها تعتمد على الأوامر السلمية Ladder أي تنفيذ البرامج يكون بالترتيب حسب موضع التعليمة بالكود , من الأعلى للأسفل , هناك استثناءات الأ وهي المقاطعات Interrupts و المؤقتات Timers.

لكن نرجع للسؤال الأهم ، هل يمكنهم كلهم العمل مع الأردوينو دون تأخير زمني ملحوظ ؟؟

 الجواب نعم

كيف ؟ هذا ما سنتعرف عليه سويا في  هذه التدوينة .

أبسط أوامر التأخير الزمني في الأردوينو هو delay هذا الأمر يسهل على المبتدئين معرفة معنى التأخير الزمني و كيفية تطبيقه على المداخل و المخارج .

كأبسط مثال , برنامج Blink الذي يطبق على الباعث الضوئي LED المربوط على المدخل D13 يضيء لثانية واحده و يطفى لثانية واحدة 



/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
 
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}





هذا الأمر فيه عدة عيوب , منها أنه لا نستطيع عمل أي شيء خلال زمن التأخير , لا نستطيع مثلاً قراءة حالة مدخل معين خلال هذا الوقت او التحكم في حالة مدخل آخر , إلا بعد انتهاء زمن التأخير كما أن زمن التأخير لا يكون بالضبط بنفس القيمة المحددة , في المثل السابق التأخير الزمني هو 1000 ملي ثانية لكن فعلياً التأخير يزيد بقليل عن هذه القيمة , و اذا تم تشغيل هذا البرنامج لفترة طويلة سيكون واضحاً جداً ان التأخير الزمني بين عمليه الأنارة و الأطفاء تزيد عن 1000 ملي ثانية بوضوح تام ! 

الحل يكون باستخدام الأمر millis ففي الأردوينو يمكن تشغيل المؤقتات باستخدام هذا الأمر و ان يكون زمن الأضاءة و الأغلاق للباعث الضوئي LED بالضبط هو 1000ملي ثانية حتى و لو استمر البرنامج بالعمل لفترة طويلة , هذا رائع :)

هذا البرنامج مثال موجود ضمن ملفات الأردوينو يوضح طريقة العمل لهذا الأمر و بنفس مخرجات البرنامج السابق .


/* Blink without Delay
 
 Turns on and off a light emitting diode(LED) connected to a digital  
 pin, without using the delay() function.  This means that other code
 can run at the same time without being interrupted by the LED code.
 
 The circuit:
 * LED attached from pin 13 to ground.
 * Note: on most Arduinos, there is already an LED on the board
 that's attached to pin 13, so no hardware is needed for this example.
 
 
 created 2005
 by David A. Mellis
 modified 8 Feb 2010
 by Paul Stoffregen
 
 This example code is in the public domain.

 
 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
 */

// constants won't change. Used here to 
// set pin numbers:
const int ledPin =  13;      // the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);      
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the 
  // difference between the current time and last time you blinked 
  // the LED is bigger than the interval at which you want to 
  // blink the LED.
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}


ممتاز هذا رائع , لكن لو اردنا عمل برامج معقدة سيكون وضع الكود بهذه الطريقة أمراً مربكاً للمبرمج , فالحل يكون بوجود مكتبة .

لحسن الحظ فالمهتمين بالأردوينو قاموا بكتابة عشرات المكتبات لتسهل على المستخدمين التعامل مع المداخل و المخارج بصورة سريعة و بدقة عالية , منها مكتبة  Metro .

هذه المكتبة تعتمد بشكل أساسي على الأمر millis و تسهل على المبرمج الحصول على برنامج يحتوي العديد من البرامج ذات تأخير زمني ثابت بين كل وظيفة و الأخرى .

اولاً يمكن تحميل المكتبة من هنا

أوامرها جداً سهلة و يمكن أن ترى عدة أمثلة مرفقه مع المكتبة .

مثلاً لو أردنا تشغيل 3 مداخل في الأردوينو بحيث يكون :

1)واحد منهم يعمل لأضاءة - اطفاء ضوء لمدة2000ملي ثانية 

2)يعمل كتعديل نبضي PWM بحيث يقوم بزيادة طول النبضة الفعالة  "زيادة توهج ال LED " مرة كل 10 ملي ثانية.

3) يعمل كمدخل قراءة لحساس تماثلي "مقاومة متغيرة" يقوم بالتحقق منها كل 200ملي ثانية و يزيد توهج LED مربوط على مدخل رقمي بتناسب طردي مع قيمة المقاومة المقروءة .

القطع المستخدمة في التجربة :

1) بطاقة أردوينو
2) مقاومة متغيرة Potentiometer
3) LED باعث ضوئي عدد 3
4)مقاومات عدد 3 "ان تكون قيمتها أقل من 1كيلو اوم"
5) اسلاك توصيل
6) Bread Board . 

المخطط :


البرنامج :

// Metro Library code 
//Written By : MBARK TiЭSTO 
//http://www.mbarktiesto.com
// 18/12/2015 
//....................................
#include <Metro.h> // Include the Metro library
//first , Blink Led for 150ms
Metro LED_flasher = Metro(2000);
boolean LEDState=true;
//second , Increase dimming For Led by 1 each time
Metro PWM_Cycle = Metro(10);
int i=0;
int Factor=1; //or -1
// third , Read Potentiometer and control the bright
//of led connect to another PWM Pin 
Metro Sensor=Metro(200);

const int LED=13;
const int pwmPin=6;
const int sensorPin=A0;
const int pwmPin2=3;
void setup() {
  // put your setup code here, to run once:
pinMode( LED ,OUTPUT);
pinMode( pwmPin ,OUTPUT);
pinMode( pwmPin2 ,OUTPUT);
pinMode( sensorPin ,INPUT);

}

void loop() {
  // put your main code here, to run repeatedly: 
   if (LED_flasher.check() == 1) { // check if the metro has passed its interval .
  digitalWrite(LED,LEDState);
  LEDState=!LEDState;
   }
  if (PWM_Cycle.check() == 1) { // check if the metro has passed its interval .
   analogWrite(pwmPin,i);
   if(i==0){Factor=1;}
   if(i>255){Factor=-1;}
   i+=Factor;
}
  if (Sensor.check() == 1) { // check if the metro has passed its interval .
  int SensorValue=analogRead(A0);
  analogWrite(pwmPin2,SensorValue/4);
}
}

هذه أحدى الطرق لزيادة فاعلية برنامجك , حاول دائماً ان لا تستخدم ال delay بشكل كبير خصوصاً عندما تحتوي مشاريعك على العديد من القطع او التعليمات التي تحتاج دقة في الوقت .

المصدر MBARK TiЭSTO Blog
عبر عن مدى إستفادتك بتقييمك للموضوع :
{[['']]}
المؤقتات الزمنية و التحكم اللحظي بمنافذ الأردوينو مراجعة MBARK T3STO يوم 6:11 م التقييم: 5

ليست هناك تعليقات:

جميع الحقوق محفوظة // موقع T3STO™Tech التعليمي © 2014 - 2015

نموذج الاتصال

الاسم

بريد إلكتروني *

رسالة *

يتم التشغيل بواسطة Blogger.