ساخت سیگنال PWM را در پست های قبلی یاد گرفته ایم. در این پست قصد داریم که به راه های خواندن یک سیگنال PWM در آردوینو بپردازیم.
همانطور که می دانید PWM یک سیگنال مربعی می باشد. و چون ما در اینجا با آردوینو و سطح منطقی TTL کار داریم. این موج بین 0 ولت و 5 ولت نوسان می کند. برای خواندن PWM چند روش داریم که هر کدام به طریقی که توضیح می دهیم عمل می کنند.
برای خواندن سیگنال PWM در واقع ما با زمان سرو کار داریم. یعنی ما مقدار زمانی که سیگنال 5 ولت است را می خوانیم. طول زمان سپری شده در موقعی که موج مربعی در بالا قرار دارد را باید به روشی برداریم.
()pulseIn:
اولی روش استفاده از متد یا تابع pulseIn می باشد. که راحت ترین روش هم است. این تابع وقتی که ولتاژ روی یک پینHIGH می شود، شمردن زمان را شروع می کند تا وقتی ولتاژ روی پین LOW شود. و این زمان را بصورت میکرو ثانیه بر می گرداند.
byte PWM_PIN = 5; int pwm_value; void setup() { pinMode(PWM_PIN, INPUT); Serial.begin(9600); } void loop() { pwm_value = pulseIn(PWM_PIN, HIGH); Serial.println(pwm_value); }
این روش یک ایراد خیلی بزرگی که دارد این است که، وقتی پایه یک می شود، میکرو منتظر می ماند تا پایه صفر شود. و در این حین نمی تواند کار دیگری انجام دهد.
interrupt :
روش بعدی استفاده از وقفه می باشد. بردهای آردوینو دو وقفه ی خارجی دارند. یکی پین 2 و دیگری پین 3. ما از یکی از این وقفه ها و تغییر تنظیم آن، به وقفه ی بالا رونده و پایین رونده، سیگنال را می خوانیم.
توجه داشته باشید که برای تعریف متغییر، هنگام استفاده از وقفه آن را باید volatile تعریف کنیم. برای آشنایی بیشتر با وقفه ها این مطلب را مطالعه کنید.
volatile int pwm_value = 0; volatile int prev_time = 0; void setup() { Serial.begin(9600); // when pin D2 goes high, call the rising function attachInterrupt(0, rising, RISING); } void loop() { } void rising() { attachInterrupt(0, falling, FALLING); prev_time = micros(); } void falling() { attachInterrupt(0, rising, RISING); pwm_value = micros()-prev_time; Serial.println(pwm_value); }
تابع micros برای اندازه گرفتن زمان اجرای برنامه می باشد. مقدار زمانی که برنامه در Loop اجرا می شود را به ما بر می گرداند.
Pin Change Interrupt :
روش سوم استفاده از وقفه ی تغییر پین می باشد. این روش چون محدودیتی برای استفاده از پین خاصی را ندارد، در مواقعی که می خواهیم از پین های 2 و 3 استفاده ی دیگری کنیم مورد استفاده قرار می گیرد. ولی پیچیدگی خودش را در برنامه نویسی دارد.
#include <PinChangeInt.h> #define MY_PIN 5 // we could choose any pin volatile int pwm_value = 0; volatile int prev_time = 0; uint8_t latest_interrupted_pin; void rising() { latest_interrupted_pin=PCintPort::arduinoPin; PCintPort::attachInterrupt(latest_interrupted_pin, &falling, FALLING); prev_time = micros(); } void falling() { latest_interrupted_pin=PCintPort::arduinoPin; PCintPort::attachInterrupt(latest_interrupted_pin, &rising, RISING); pwm_value = micros()-prev_time; Serial.println(state); } void setup() { pinMode(MY_PIN, INPUT); digitalWrite(MY_PIN, HIGH); Serial.begin(9600); PCintPort::attachInterrupt(MY_PIN, &rising, RISING); } void loop() { }
دیدگاه ها :