در این مقاله آموزشی به بررسی ماژول روتاری انکودر و نحوه راه اندازی آن با آردوینو می پردازیم.
مقدمه
روتاری انکودر نوعی سنسور موقعیت است که برای مشخص نمودن موقعیت زاویه ای یک شافت چرخان استفاده ميشود. بسته به نوع حرکت چرخشی، این نوع انکودر یک سیگنال الکتریکی آنالوگ یا دیجیتال تولید ميکند.
همان طور که در شکل زیر مشاهده می کنید، این ماژول انواع مختلفی دارد که براساس سیگنال خروجی و تکنولوژی حسگر دسته بندی شده اند:
یکی از انواع این انکودر که در این آموزش مورد استفاده قرار ميگیرد، روتاری انکودر افزاینده است که سادهترین نوع سنسور برای اندازهگیری موقعیت زاویهای به شمار ميرود. این نوع انکودر به نام انکودر پالس مربعی (quadrature encoder) یا انکودر دوراني نسبی (relative rotary encoder ) نیز شناخته ميشود و خروجی آن بصورت یکسری امواج پالسی شکل است.
نحوه عملکرد ماژول روتاری انکودر
در این بخش نگاه دقیقتری به ماژول روتاری انکودر و نحوه عمکلرد آن خواهیم داشت.
در شکل زیر نحوه تولید امواج پالسی نشان داده شده است. همان طور که مشاهده می کنید روتاری انکودر دارای دیسکی با نواحی مختلف است. نواحی که با فاصله ای یکسان از هم بر روی دیسک قرار گرفته اند. این نواحی به یک پین مشترک C و دو پین مجزای A و B متصل شده اند.
وقتی که دیسک مرحله به مرحله شروع به چرخش ميکند، امواج مربعی شکل خروجی با تماس پینهای A و B به پین مشترک C تولید ميشوند. برای تشخیص ميزان دوران ایجاد شده کافیست تعداد پالس یکی از سیگنالهای A و یا B شمارش شود. هر چند برای تشخیص جهت حرکت چرخشی لازم است همزمان موج A و موج B در نظر گرفته شود.
خروجی A و B نسبت به یکدیگر دارای 90 درجه اختلاف فاز هستند. اگر انکودر در جهت ساعتگرد چرخش داشته باشد، سیگنال خروجی A جلوتر از سیگنال خروجی B خواهد بود.
در لبههای بالا رونده و پایین رونده سیگنالها در مواقع تغییر سطح سیگنال، به وضوح می توان دید که دو سیگنال A و B دارای مقادیر متضاد هستند. اما اگر انکودر برخلاف جهت عقربههای ساعت دوران داشته باشد، اين دو سیگنال دارای مقادیر یکسان خواهند بود. بر همین اساس براحتی ميتوانیم کنترلر را برای خواندن اندازه موقعیت زاویه ای و تشخیص جهت چرخش برنامهنويسي کنیم.
مثال 1: راه اندازی ماژول روتاری انکودر با آردوینو
در این بخش یک مثال عملی از نحوه راه اندازی ماژول روتاری انکودر با آردوینو را ارائه می کنیم.
ماژول خاصی که برای این کار استفاده ميشود بر روی یک برد الکترونیکی برک-اوت (Breakout) با پنج پین قرار داده شده است. پین اول خروجی A و پین دوم خروجی B است. سومين پین، Button و دو پین دیگر تغذیه VCC و زمين GND ميباشد. پینهای خروجی به هر یک از پینهای دیجیتال برد آردوینو وصل ميشوند.
کد برنامه نویسی (سورس کد)
کد برنامه نویسی آردوینو برای این مثال بصورت زیر است:
/* Arduino Rotary Encoder Tutorial
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
*/
#define outputA 6
#define outputB 7
int counter = 0;
int aState;
int aLastState;
void setup() {
pinMode (outputA,INPUT);
pinMode (outputB,INPUT);
Serial.begin (9600);
// Reads the initial state of the outputA
aLastState = digitalRead(outputA);
}
void loop() {
aState = digitalRead(outputA); // Reads the "current" state of the outputA
// If the previous and the current state of the outputA are different, that means a Pulse has occured
if (aState != aLastState){
// If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
if (digitalRead(outputB) != aState) {
counter ++;
} else {
counter --;
}
Serial.print("Position: ");
Serial.println(counter);
}
aLastState = aState; // Updates the previous state of the outputA with the current state
}
توضیح کد آردوینو
در ابتدا متغیرهای مورد نیاز را تعریف می کنیم. دو پین که روتاری انکودر به آنها متصل شده است، به عنوان ورودیها تعریف ميشوند. پس از آن ارتباط سریال برای پرینت نتایج بر روی یک سریال مانیتور و خواندن مقدار اولیه خروجی A و نيز براي مقدار دهی به متغیر aLastState استارت ميشود.
سپس در تابع loop مقدار خروجی A را مجددا می خوانیم اما این بار آن را در متغیر aState می ریزیم. اگر انکودر چرخانده شود، با تولید پالس در خروجی A، مقدار دو متغیر متفاوت خواهد بود و عبارت شرط “if” اول فعال خواهد شد. جهت چرخش توسط عبارت شرطی “if” دوم تعیین ميگردد. اگر مقدار خروجی A متفاوت از مقدار خروجی B باشد، شمارشگر یک واحد اضافه خواهد شد، در غیر این صورت یک واحد کم می شود.
در انتها، پس از پرینت نتایج بر روی یک سریال مانیتور، متغیر aLastState با مقدار فعلی متغیر aState بروز ميشود. چنانچه این کد بر روي آردوينو آپلود شود، با چرخش انکودر مقدار دادههای موردنیاز بر روی سریال مانیتور در دسترس خواهند بود.
مثال 2: کنترل استپر موتور (موتور پلهاي) ماژول روتاری انکودر
علاوه بر مثال ساده قبل، در این قسمت کد برنامه آردوینو برای کنترل کردن یک استپر موتور (موتور پلهای) با استفاده از ماژول روتاری انکودر ارائه شده است.
در اینجا می توانید سورس کد این مثال را مشاهده کنید:
/* Stepper Motor using a Rotary Encoder
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
*/
#include <LiquidCrystal.h> // includes the LiquidCrystal Library
LiquidCrystal lcd(1, 2, 4, 5, 6, 7); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7)
// defines pins numbers
#define stepPin 8
#define dirPin 9
#define outputA 10
#define outputB 11
int counter = 0;
int angle = 0;
int aState;
int aLastState;
void setup() {
// Sets the two pins as Outputs
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
pinMode (outputA,INPUT);
pinMode (outputB,INPUT);
aLastState = digitalRead(outputA);
lcd.begin(16,2); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display }
}
void loop() {
aState = digitalRead(outputA);
if (aState != aLastState){
if (digitalRead(outputB) != aState) {
counter ++;
angle ++;
rotateCW();
}
else {
counter--;
angle --;
rotateCCW();
}
if (counter >=30 ) {
counter =0;
}
lcd.clear();
lcd.print("Position: ");
lcd.print(int(angle*(-1.8)));
lcd.print("deg");
lcd.setCursor(0,0);
}
aLastState = aState;
}
void rotateCW() {
digitalWrite(dirPin,LOW);
digitalWrite(stepPin,HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin,LOW);
delayMicroseconds(2000);
}
void rotateCCW() {
digitalWrite(dirPin,HIGH);
digitalWrite(stepPin,HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin,LOW);
delayMicroseconds(2000);
}
اگر سوالی در زمینه راه اندازی ماژول روتاری انکودر ذهن شما را مشغول کرده است، می توانید آن را با ما در میان بگذارید.