یک انکودر چرخشی برای کنترل دقیق یک خروجی، همانند چرخش یک موتور، موقعیت مکاننما بر روی یک صفحه یا روشنایی یک LED بکاربرده میشود.
در این مقاله خواهیم دید که چگونه جهت و میزان چرخش یک انکودر چرخشی برای کنترل دستگاهها، برای مثال LED و یک استپ موتور بکاربرده میشود. قطعات مورد نیاز هم در لیست زیر ارائه شده است :
- آردوینو UNO و برد بورد
- انکودر چرخشی: KY-040
- استپ موتور: 28BYJ-48
- برد اتصال استپ موتور با تراشه ULN2003
- باتری: 9 ولت
- LED
- مقاومت: 220 اهم
انکودرهای چرخشی بهعنوان کلیدهای کنترلی همانند تجهیزات صوتی بکاربرده میشوند. انکودر چرخشی 20 موقعیت دارد، اما روتور میتواند بطور پیوسته برای افزایش یا کاهش یک متغیر کنترلی به عقب یا جلو چرخانده شود.
معرفی انکودر چرخشی ( روتاری انکودر)
درون یک انکودر چرخشی سه پایه وجود دارد: یک پایه مشترک و دو پایه با نام A و B که آفست هستند. با چرخش روتور هرکدام از پایههای A و B به پایه مشترک متصل یا از آن جدا میشوند، و امواج مربعی با فرکانسهای مشابه اما با یک چهارم دور یا 90 اختلاف فاز تولید میکند (شکل 2). تعداد پالسهای امواج مربعی میزان چرخش را نشان میدهند، که میتوانند بر روی پایه A یا پایه B اندازهگیری شوند.
موقعیت موج مربعی در پایههای A و B جهت چرخش را تعیین میکند. اگر چرخش ساعتگرد باشد، پایه A قبل از پایه B به پایه مشترک متصل میشود، بنابراین موج مربعی در پایه B در لبه پایینرونده موج مربعی در پایه A خواهد بود، خط مشکی عمودی نشاندهنده لبه پایینرونده پایه A است (شکل 2). در مقابل، اگر در لبه پایینرونده موج مربعی پایه A، موج مربعی در پایه B LOW باشد چرخش پادساعتگرد است. لبه بالارونده موج مربعی در پایه A همچنین میتواند بهعنوان نقطه مرجع زمان استفاده شود، در این حالت مقدار LOW موج مربعی در پایه B نشانگر یک چرخش ساعتگرد است.
دنباله حالتهای پایه A و پایه B در یک لبه پایینرونده موج مربعی در پایه B با چرخش ساعتگرد انکودر چرخشی برابر با (LOW,LOW)، (LOW,HIGH)، (HIGH,HIGH)، و (HIGH,LOW) یا 00، 01، 11 و 10 است. چنین دنبالهای کد Gray است که دو مقدار متوالی یک بیت تفاوت دارند. همچنین دنباله باینری افزایشی 00، 01، 10 و 11 را میتوان با استفاده از دو موج مربعی (LOW,LOW)، (LOW,HIGH)، (HIGH, LOW)، و (HIGH, HIGH) ایجاد کرد، اما دو موج مربعی هم فاز هستند و فرکانس موج دوم دو برابر موج اول است (شکل 3).
اتصال انکودر چرخشی به آردوینو
سوییچ روی انکودر چرخشی، که با فشار دادن میله انکودر چرخشی فعال میشود، میتواند برای تغییر حالت یک متغیر باینری بکاربرده شود. در این دستورات (کد زیر)، فشردن کلید یک LED را خاموش میکند. پایههای A و B انکودر چرخشی به پایههای کلاک (CLK) و داده (DT) اشاره دارند. پایه کلید انکودر چرخشی (SW) به جای یک مقاومت جداگانه در مدار از یک مقاومت پول آپ داخلی متصل به هر پایه ورودی آردوینو استفاده میکند. یک مقاومت پول آپ داخلی با دستور digitalWrite(pin, INPUT_PULLUP) فعال میشود، اما این پایه بجای اکتیو LOW اکتیو HIGH است. در این فصل از ماژول انکودر چرخشی، KY-040 استفاده میشود که شامل مقاومتهای پولآپ 10 کیلواهم در پایههای کلاک (CLK) و داده (DT) است. یک LED برای انکودر چرخشی به پایه PWM آردوینو متصل میشود تا سطح روشنایی LED را کنترل کند.
پایههای کلاک (CLK)، داده (DT)، و سوییچ (SW) برای سهولت شماتیک به پایههای A0، A1، و A2 آردوینو متصل میشوند (شکل 4 و جدول 1).
جدول 1- اتصالات برای انکودر چرخشی و LED
قطعه
|
اتصال به
|
و اتصال به
|
---|---|---|
CLK انکودر چرخشی
|
پایه A0 آردوینو
|
|
DT انکودر چرخشی
|
پایه A1 آردوینو
|
|
SW انکودر چرخشی
|
پایه A2 آردوینو
|
|
VCC انکودر چرخشی
|
5 ولت آردوینو
|
|
GND انکودر چرخشی
|
GND آردوینو
|
|
پایه بلند LED
|
پایه A6 آردوینو
|
|
پایه کوتاه LED
|
مقاومت 220 اهم
|
GND آردوینو
|
کنترل روشنایی LED با روتاری انکودر در آردوینو
در کد زیر ، تابع ()encoder جهت چرخش را با برگرداندن مقدار 1 برای چرخش ساعتگرد و 1- برای چرخش پادساعتگرد مشخص میکند. تابع ()encoder با دستور if (oldA == HIGH && newA == LOW) منتظر یک لبه پایینرونده بر روی پایه A میماند. مقدار محوشدگی تدریجی شدت سیگنال که برای کاهش یا افزایش روشنایی LED در جهت چرخش انکودر چرخشی ضرب میشود، روشنایی LED را افزایش میدهد. فشار دادن سوییچ انکودر چرخشی با ریست کردن روشنایی LED به صفر LED را خاموش میکند.
int CLKpin= A0; // pin A or clock pin
int DTpin= A1; // pin B or data pin
int SWpin= A2 ; // switch pin
int LEDpin = 6; // LED on PWM pin
int bright = 120; // initial LED value
int fade = 10; // amount to change LED
int rotate = 0; // number of rotary turns
int oldA = HIGH; // status of pin A
int change, result, newA, newB;
void setup()
{
Serial.begin(9600); // define Serial output baud rate
pinMode(LEDpin, OUTPUT); // LED pin as output
pinMode(SWpin, INPUT_PULLUP); // switch pin uses internal pull-up resistor
}
void loop()
{
if(digitalRead(SWpin) == LOW) bright = 0; // switch, active LOW,
// turns off LED
change = encoder(); // function for direction of rotation
rotate = rotate + abs(change); // number of turns of rotary encoder
bright = bright + change*fade; // change LED brightness
bright = constrain(bright, 0, 255); // constrain LED brightness
if(change != 0)
{ // display number
Serial.print(rotate);S erial.print("\t"); // of rotary turns
Serial.println(bright); // and LED brightness
}
analogWrite(LEDpin, bright); // update LED brightness
}
int encoder() // function to determine direction
{
result = 0;
newA = digitalRead(CLKpin); // state of (CLK) pin A
newB = digitalRead(DTpin); // state of (DT) pin B
// falling edge on (CLK) pin A
if (oldA == HIGH && newA == LOW) result = 2*newB - 1;
oldA = newA; // update state of (CLK) pin A
return result;
}
اگر تابع ()void loop شامل چندین فرآیند یا تاخیر باشد، میکروکنترلر ممکن است با عدم تشخیص تمامی لبههای پایینرونده بر روی پایه A یا پایه CLK چرخشهای انکودر چرخشی را از دست دهد. برای مثال، وارد کردن دستور delay(100) در تابع ()void loop سبب میشود میکروکنترلر چرخشهای انکودر چرخشی را از دست دهد. اجرای یک وقفه مشکل میکروکنترلر برای عدم تشخیص تغییر وضعیت دستگاه در صورت وجود چندین کار یا تاخیر در تابع ()void loop را برطرف میکند. موضوع وقفه در مقالات بعدی بررسی میشود.
انکودر چرخشی و استپ موتور
یک استپ موتور در شکل 5 به آردوینو متصل میشود. پایههای آنالوگ آردوینو A0 تا A5 که متناظر با پایههای 14 تا 19 هستند با استفاده از دستور (پایه)digitalRead میتوانند به عنوان پایههای دیجیتال بکاربرده شوند.
انکودر چرخشی میتواند برای کنترل استپ موتور بکاربرده شود. در دستورات ابتدا استپ موتور به یک مکان اولیه و سپس به یک مکان هدف که توسط تعداد چرخشها تعیین میشود، حرکت میکند (کد زیر و جدول 2 را مشاهده کنید). وقتیکه استپ موتور به مکان هدف رسید، جهت چرخش معکوس میشود و استپ موتور به “منفی” مکان هدف حرکت میکند. سوییچ انکودر چرخشی هدف استپ موتور را به صفر تغییر میدهد. حداکثر سرعت استپ موتور 700 گام در دقیقه تنظیم میشود که معادل 20.6 rpm با گام کامل است. یک LED به پایه PWM آردوینو متصل میشود، بنابراین انکودر چرخشی روشنایی LED را به صورت موازی با تغییر در هدف استپ موتور کنترل میکند.
#include // include AccelStepper library
int blue = 12; // coil activation order on ULN2003
int pink = 11; // blue, pink, yellow, orange
int yellow = 10;
int orange = 9;
int fullstep = 4; // number of coil activation stages
int halfstep = 8; // with full-step and half-step
int coil = fullstep; // set number of coil activation stages
// associate stepper with AccelStepper library and coil pairing order
AccelStepper stepper(coil, blue, yellow, pink, orange);
int stepperTarget = 500; // initial position for stepper motor
int stepperChange = 200; // number of steps to move stepper motor
int CLKpin= A0; // rotary encoder pin A
int DTpin= A1; // and pin B
int SWpin= A2 ; // switch pin
int rotate = 0; // number of rotary encoder turns
int oldA = HIGH; // status of pin A
int direct = 1; // direction of rotation
int LEDpin = 6; // LED on PWM pin
int bright = 60; // initial LED value
int fade = 25; // amount to change LED
int change, result, newA, newB;
void setup()
{
Serial.begin(9600); // define Serial output baud rate
pinMode(SWpin, INPUT_PULLUP); // switch pin uses internal pull-up resistor
stepper.setMaxSpeed(700); // maximum speed of stepper motor
stepper.setAcceleration(600); // acceleration rate (steps/s2)
}
void loop()
{
if(digitalRead(SWpin) == LOW)
{
stepperTarget = 0; // switch repositions stepper motor
bright = 0; // and turns off the LED
}
change = encoder(); // determine direction of rotary encoder
rotate = rotate + abs(change); // number of rotary encoder turns
// move stepper motor to new position
stepperTarget = stepperTarget + change * stepperChange;
stepperTarget = constrain(stepperTarget, 0, 2037); // constrain position
bright = bright + change*fade; // change LED brightness
bright = constrain(bright, 0, 25 5); // constrain LED brightness
if(change != 0)
{
Serial.print(rotate);Serial.pr int("\t"); // display rotary turn number
Serial.print(bright);Serial.pr int("\t"); // display LED brightness
Serial.println(stepperTarget); // and new target position
}
analogWrite(LEDpin, bright); // update LED brightness
stepper.moveTo(direct*stepperTarget/2); // move to target position
if (stepper.distanceToGo() == 0) direct=-direct; // reverse direction
stepper.run(); // move stepper motor
}
int encoder() // function to determine direction
{
result = 0;
newA = digitalRead(CLKpin); // state of (CLK) pin A
newB = digitalRead(DTpin); // state of (DT) pin B
// falling edge on (CLK) pin A
if (oldA == HIGH && newA == LOW) result = 2*newB - 1;
oldA = newA; // update state of (CLK) pin A
return result;
}
جدول 2- اتصالات برای انکودر چرخشی و استپ موتور
قطعه
|
اتصال به
|
و اتصال به
|
---|---|---|
سیم آبی استپ موتور
|
ULN2003 IN1
|
پایه 12 آردوینو
|
سیم صورتی استپ موتور
|
ULN2003 IN2
|
پایه 11 آردوینو
|
سیم زرد استپ موتور
|
ULN2003 IN3
|
پایه 10 آردوینو
|
سیم نارنجی استپ موتور
|
ULN2003 IN4
|
پایه 9 آردوینو
|
مثبت باتری 9 ولت
|
ULN2003 مثبت
|
|
منفی باتری 9 ولت
|
ULN2003 منفی
|
GND آردوینو
|
CLK انکودر چرخشی
|
پایه A0 آردوینو
|
|
DT انکودر چرخشی
|
پایه A1 آردوینو
|
|
SW انکودر چرخشی
|
پایه A2 آردوینو
|
|
VCC انکودر چرخشی
|
5 ولت آردوینو
|
|
GND انکودر چرخشی
|
GND آردوینو
|
|
پایه بلند LED
|
مقاومت 220 اهم
|
پایه 6 آردوینو
|
پایه کوتاه LED
|
GND آردوینو
|
|