Журнал LinuxFormat - перейти на главную

LXF155:Кру­тить мо­тор­чик

Материал из Linuxformat
Версия от 11:18, 26 июня 2018; Olkol (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск


Arduino Управляем сервопориводами и шаговыми двигателями

Arduino: Моторы и дви­же­ние

По­ра дви­гать­ся даль­ше – Ник Вейч за­став­ля­ет ко­ле­са крутить­ся.


С тех са­мых пор, как Майкл Фа­ра­дей на­чал экс­пе­ри­мен­ти­ро­вать с про­водника­ми в чаш­ках со рту­тью, в элек­тронике, по­жа­луй, ничем не доста­вить боль­ше­го и мгно­венно­го удов­ле­тво­рения, как при­вес­ти что-то в дви­жение.

Схе­мы Arduino обыч­но ис­поль­зу­ют­ся для управ­ления ро­бо­та­ми, но ро­бо­ты не мо­гут по­бе­жать, пре­ж­де чем сде­ла­ют пер­вый неуве­рен­ный шаг, по­это­му здесь мы рас­смот­рим осно­вы дви­га­те­лей и сер­во­при­во­дов.

Го­во­ря о сер­во­при­во­де, обыч­но име­ют в ви­ду уст­рой­ст­во, ча­ще все­го встре­чаю­щее­ся в ра­дио­управ­ляе­мом обо­ру­до­вании, где оно при­ме­ня­ет­ся для управ­ления ру­лем или дру­ги­ми дви­жу­щи­ми­ся час­тя­ми.

Этот тип сер­во­при­во­да – обыч­но со­че­тание несколь­ких эле­мен­тов: дви­га­те­ля, ко­то­рый да­ет энер­гию; шес­терней, со­еди­няю­щих дви­га­тель с его при­вод­ным ры­ча­гом (ко­то­рый мо­жет иметь раз­лич­ную фор­му и раз­ме­ры); и уст­рой­ст­ва об­рат­ной свя­зи, обыч­но по­тен­цио­мет­ра, с по­мо­щью ко­то­ро­го сер­во­при­вод мо­жет точ­но оп­ре­де­лить по­ло­жение ры­ча­га.


Сер­во­при­вод име­ет три про­во­да: по крас­но­му и чер­но­му обыч­но по­да­ет­ся на­пря­жение пи­тания, по треть­ему, как пра­ви­ло, жел­то­му или оран­же­во­му – управ­ляю­щий сиг­нал. Сер­во­при­во­ды ра­бо­та­ют от ана­ло­го­вых управ­ляю­щих сиг­на­лов, ис­поль­зую­щих то­ко­вый им­пульс. Ши­ри­на им­пуль­са оп­ре­де­ля­ет по­ло­жение ры­ча­га.

По со­гла­шению, им­пульс дли­тель­но­стью 1,5 мс пе­ре­ме­ща­ет сер­во­при­вод в ней­траль­ное по­ло­жение, сред­нюю точ­ку – ме­ж­ду на­чаль­ной и конеч­ной точ­ка­ми, а весь диа­па­зон воз­мож­ных по­ло­жений по­кры­ва­ет ши­ри­на им­пуль­сов от 1 до 2 мс.

Для пи­тания од­но­го неболь­шо­го RC-сер­во­при­во­да доста­точ­но линии пи­тания Arduino +5 В, но ес­ли их боль­ше, под­клю­чи­те бо­лее под­хо­дя­щий ис­точник пи­тания. К сча­стью, RC-сер­во­при­во­ды обыч­но пре­крас­но ра­бо­та­ют от на­пря­жения 5 или 6 В, по­это­му Arduino и все сер­во­при­во­ды мож­но под­клю­чить к од­но­му внешнему ис­точнику.

Для фор­ми­ро­вания им­пуль­са не ну­жен вы­со­кий ток, и для их пи­тания не нуж­ны до­полнитель­ные ре­ле или тран­зи­сто­ры, что то­же хо­ро­шо, по­сколь­ку на ко­рот­ких ин­тер­ва­лах вре­мени, с ко­то­ры­ми мы ра­бо­та­ем, с ними мо­гут возник­нуть труд­но­сти.

На са­мом де­ле, эти вре­мен­ные ин­тер­ва­лы мо­гут по­ме­шать эф­фек­тив­но­му управ­лению сер­во­при­во­дом из ко­да Arduino. К сча­стью, су­ще­ст­ву­ет стан­дарт­ная биб­лио­те­ка, с редкой креативностью на­зван­ная Servo. Ес­ли вы под­клю­чи­те свой сер­во­при­вод в со­от­вет­ст­вии с рис. 1, то смо­же­те по­экс­пе­ри­мен­ти­ро­вать с ним и об­на­ру­жить его пре­де­лы.

Стан­дарт­ный при­мер ко­да для на­шей си­туа­ции – шаб­лон под на­званием “Sweep”, ко­то­рый мож­но най­ти в при­ме­рах, по­став­ляе­мых с Arduino. В нем для по­сте­пен­но­го из­менения по­ло­жения сер­во­при­во­да от 0 до 180 гра­ду­сов ис­поль­зу­ют­ся функ­ции по­зи­циониро­вания. Од­на­ко, ес­ли вы не уве­ре­ны в пре­дель­ных зна­чениях для сво­его уст­рой­ст­ва, сна­ча­ла мож­но по­про­бо­вать что-нибудь по­про­ще.

(thumbnail)
Ос­вой­те ос­но­вы — и воз­мож­но все.
  1. include <Servo.h>

Servo servo1; // create servo object

void setup()

{

servo1.attach(9);

}

void loop()

{

servo1.writeMilliseconds(1500);

delay(200);

servo1.writeMilliseconds(700);

delay(200);

servo1.writeMilliseconds(2200);

delay(200);

}

Ме­тод .writeMilliseconds() не со­дер­жит код, пре­об­ра­зую­щий угол в ши­ри­ну им­пуль­са, и про­сто фор­ми­ру­ет им­пульс за­дан­ной дли­тель­но­сти. Эти зна­чения мож­но умень­шать и уве­ли­чи­вать до тех пор, по­ка при­вод не пе­ре­станет дви­гать­ся, а за­тем ис­поль­зо­вать их в ка­че­­ст­ве пре­дель­ных при инициа­ли­за­ции уст­рой­ст­ва:

servo1.attach(9,650,2350);

Па­ра­мет­ры этой функ­ции – но­мер вы­во­да, минималь­ная ши­ри­на им­пуль­са и мак­си­маль­ная ши­ри­на им­пуль­са. Здесь мы ис­поль­зу­ем для сер­во­при­во­да вы­вод 9 – имен­но этот вы­вод ис­поль­зу­ет­ся ча­ще все­го. В ста­рых вер­си­ях ко­да Arduino биб­лио­те­ка ра­бо­та­ла толь­ко с вы­во­да­ми 9 и 10, и да­же сей­час на всех пла­тах, кро­ме Mega, вы­зов биб­лио­те­ки сер­во­при­во­да при­ве­дет к то­му, что на этих вы­во­дах пе­ре­станет ра­бо­тать ШИМ (ши­рот­но-им­пульс­ная мо­ду­ля­ция), по­это­му мо­же­те восполь­зо­вать­ся и ими.

Ес­ли вы хо­ти­те или вам нуж­но за­пи­сы­вать дан­ные в сер­во­при­вод вруч­ную, восполь­зуй­тесь встро­ен­ной функ­ци­ей map:

value = map(value,0,179,650,2350);

ко­то­рая про­мас­шта­би­ру­ет вход­ное зна­чение ме­ж­ду пер­вой па­рой чи­сел в со­от­вет­ст­вую­щее зна­чение ме­ж­ду вто­рой па­рой чи­сел.



(thumbnail)
Рис. 1. Про­стая управ­ляю­щая цепь — ди­од пре­дот­вра­ща­ет не­же­ла­тель­ные эф­фек­ты об­рат­ной ЭДС.

Сер­во­при­во­ды по­лез­ны для управ­ления все­ми ви­да­ми ро­бо­то­техники, а так­же для ра­дио­управ­ляе­мых са­мо­ле­тов. По­жа­луй, са­мое про­стое, что мож­но сде­лать с их по­мо­щью – из­ме­рить фи­зи­че­­ский угол. Кро­ме сер­во­при­во­да, по­на­до­бит­ся толь­ко мик­ро­пе­ре­клю­ча­тель, под­клю­чен­ный к «пле­чу» или дви­жу­ще­му­ся ры­ча­гу сер­во­при­во­да. За­тем мож­но под­ве­сить это к циф­ро­во­му вхо­ду и про­ве­рять его в ка­ж­дом цик­ле (или вме­сто это­го упот­ре­бить пре­ры­вания – см. пре­ды­ду­щую ста­тью) что­бы уви­деть, коснул­ся ли ры­чаг че­го-ли­бо, см. Схе­му 1.

(thumbnail)
На­стоя­щий ша­го­вый дви­га­тель из­нут­ри. Боль­ше сер­деч­ни­ков уве­ли­чи­ва­ют ко­ли­че­ст­во ша­гов в пол­ном обо­ро­те, но про­вод­ни­ков для управ­ле­ния все рав­но че­ты­ре.
  1. include <Servo.h>

Servo servo1;

int switchpin = 2;

int sensorValue = 0;

int pos = 0;

void setup()

{

servo1.attach(9,540,2350);

pinMode(switchpin, INPUT);

Serial.begin(9600);

}

void loop()

{

digitalWrite(switchpin, HIGH);

for(pos = 0; pos < 180; pos += 1)

{

servo1.write(pos);

sensorValue = digitalRead(2);

if (sensorValue == LOW ){

Serial.println(servo1.read(), DEC);

servo1.write(0);

delay(1000);

break;

}

delay(10);

}

}

Мы под­клю­чи­ли пе­ре­клю­ча­тель ме­ж­ду «зем­лей» и вы­во­дом 2 Arduino (вы­во­ды 0 и 1 луч­ше не тро­гать: они ис­поль­зу­ют­ся для USB-ин­тер­фей­са, и иногда в шаб­ло­нах, где они при­ме­ня­ют­ся, за­груз­ка мо­жет про­ис­хо­дить некор­рект­но).

В основ­ном цик­ле мы про­хо­дим по зна­чениям уг­ла и об­нов­ля­ем по­ло­жение сер­во­при­во­да. При ка­ж­дом про­дви­жении ры­ча­га мы про­ве­ря­ем, что пе­ре­клю­ча­тель на­жат; это оз­на­ча­ет, что ры­чаг коснул­ся че­го-то. Тогда мы воз­вра­ща­ем ры­чаг в ну­ле­вое по­ло­жение и вы­хо­дим из цик­ла, пе­ред этим от­пра­вив зна­чение уг­ла в по­сле­до­ва­тель­ный порт. Мож­но бы­ло про­сто вы­вес­ти зна­чение пе­ре­мен­ной pos, но что­бы немно­го по­ри­со­вать­ся, мы восполь­зо­ва­лись ме­то­дом .read() объ­ек­та сер­во­при­во­да.

Этот ме­тод на са­мом де­ле не оп­ре­де­ля­ет по­ло­жение сер­во­при­во­да по вол­шеб­ст­ву, а оп­ра­ши­ва­ет те­ку­щее со­стояние сиг­на­ла, ко­то­рый мы от­прав­ля­ем, и пре­об­ра­зу­ет его в угол. Су­ще­ст­ву­ют дат­чи­ки по­сто­ян­но­го вра­щения, ко­то­рые по су­ще­ст­ву боль­ше по­хо­жи на ша­го­вые дви­га­те­ли. В этих слу­ча­ях ши­ри­на им­пуль­са оп­ре­де­ля­ет ско­рость их вра­щения.

Ша­го­вый дви­га­тель – уди­ви­тель­ная вещь. Ес­ли обыч­ный дви­га­тель мож­но вклю­чить, вы­клю­чить и, воз­мож­но, из­менить на­прав­ление, ша­го­вый дви­га­тель по­зво­ля­ет управ­лять сво­ей ра­бо­той во впе­чат­ляю­щих объ­е­мах.

(thumbnail)
Схе­ма 1. Про­стая схе­ма из­ме­ре­ния уг­ла с сер­во­при­во­дом.
|

С эти­ми боль­ши­ми воз­мож­но­стя­ми при­хо­дит не боль­шая от­вет­ст­вен­ность, а лишь немно­го лишнего бес­по­кой­ст­ва. Во врез­ке опи­сан один из по­пу­ляр­ных ти­пов ша­го­во­го дви­га­те­ля и по­ка­зан прин­цип его ра­бо­ты, но, хо­тя знать, как он ра­бо­та­ет, по­лез­но, ес­ли вы не хо­ти­те уг­луб­лять­ся в де­та­ли, то суть в сле­дую­щем: дви­га­те­лем управ­ля­ют воз­бу­ж­дае­мые элек­тро­магниты внут­ри него, ко­то­рые за­став­ля­ют ро­тор дви­гать­ся. За­тем элек­тро­магниты мож­но воз­бу­дить в про­ти­во­по­лож­ном на­прав­лении, что­бы ро­тор про­дви­нул­ся еще немно­го. По­это­му дви­жение про­из­во­дит­ся ша­га­ми, и в ка­ж­дом ша­ге вы или кон­трол­лер долж­ны управ­лять энер­ги­ей, про­те­каю­щей че­рез элек­тро­магниты.

Для ра­бо­ты элек­тро­магнит­ных сер­дечников тре­бу­ет­ся несколь­ко боль­шая мощ­ность, чем мо­жет пре­доста­вить пла­та Arduino, а за­час­тую и боль­шее на­пря­жение пи­тания, по­это­му на­пря­мую к вы­во­дам Arduino под­клю­чать их нель­зя. Когда нам нуж­на боль­шая мощ­ность, мы об­ра­ща­ем­ся к на­шим кремние­вым друзь­ям, тран­зи­сто­рам.


(thumbnail)
Схе­ма 2. Двух­про­вод­ная схе­ма управ­ле­ния ша­го­вым дви­га­те­лем.

Мощ­ный тран­зи­стор лег­ко мо­жет пре­доста­вить ток и на­пря­жение, доста­точ­ные для пи­тания сер­дечников, и на рис. 1 по­ка­за­на про­стая схе­ма с тран­зи­сто­ром. Ди­од ну­жен толь­ко для за­щи­ты от об­рат­ной ЭДС – дви­га­тель мо­жет не толь­ко по­треб­лять энер­гию, но и генери­ро­вать ее, а скач­ки то­ка, от­прав­ляю­щие­ся об­рат­но в на­шу цепь, нам не нуж­ны. Для од­но­по­люс­но­го дви­га­те­ля эту схе­му доста­точ­но ум­но­жить на че­ты­ре (обыч­ное ко­ли­че­­ст­во схем сер­дечников в дви­га­те­ле). Ой, а я ска­зал о том, что су­ще­ст­ву­ют раз­лич­ные ти­пы дви­га­те­лей? Ос­нов­ных ти­пов три:

1 От­но­си­тель­но нерас­про­странен­ный и до­ро­гой универ­саль­ный ша­го­вый дви­га­тель

2 Удоб­ный в ис­поль­зо­вании од­но­по­люс­ный ша­го­вый дви­га­тель

3 По­все­ме­ст­но рас­по­странен­ный и нена­деж­ный двух­по­люс­ный ша­го­вый дви­га­тель.

Чем же они раз­ли­ча­ют­ся? Все де­ло в про­во­дах. В од­но­по­люс­ном дви­га­те­ле две це­пи сер­дечников ак­ку­рат­но со­еди­ня­ют­ся в цен­тре, а зна­чит, мож­но по­дать пи­тание на центр и вклю­чать или вы­клю­чать сер­дечники на ка­ж­дой сто­роне, за­зем­ляя их.

В двух­по­люс­ном дви­га­те­ле це­пи сер­дечников от­дель­ные, но для их пи­тания нуж­но по­да­вать на­пря­жение в раз­лич­ной по­ляр­но­сти в за­ви­си­мо­сти от ша­га.

Схе­ма для управ­лениям ими сложнее, но в дви­га­те­ле лег­ко раз­мес­тить боль­ше сер­дечников, по­это­му двух­по­люс­ные дви­га­те­ли ве­ро­ятнее все­го най­ти в ста­ром офис­ном обо­ру­до­вании.

В универ­саль­ном ша­го­вом дви­га­те­ле есть про­во­да для лю­бых ти­пов ви­га­те­лей, и его мож­но под­клю­чить как од­но­по­люс­ный или двух­по­люс­ный дви­га­тель. Мы со­сре­до­то­чим­ся на двух­по­люс­ном дви­га­те­ле по­то­му, что с ним у вас с наи­боль­шей ве­ро­ят­но­стью мо­гут возник­нуть труд­но­сти, а так­же по­то­му, что ско­рее все­го вам по­па­дет­ся имен­но та­кой.

Нам нуж­но по­да­вать на­пря­жение на сер­дечники точ­но так­же, как рань­ше (см. рис. 1), но как из­ме­нять его по­ляр­ность? От­вет – с по­мо­щью мосто­вой кон­ст­рук­ции на дио­дах. Ес­ли вам зна­ко­мы схе­мы мосто­вых вы­пря­ми­те­лей в ис­точниках пи­тания, на­ша схе­ма мо­жет по­ка­зать­ся немно­го по­хо­жей, и во мно­гом это так, не счи­тая то­го, что ре­ша­ет она поч­ти про­ти­во­по­лож­ную за­да­чу. На рис. 2 по­ка­за­на рас­про­странен­ная схе­ма H-моста.

Дио­ды га­ран­ти­ру­ют, что ток те­чет толь­ко ту­да, ку­да нам нуж­но, и за­щи­ща­ет схе­му от «от­да­чи» дви­га­те­ля, а пе­ре­клю­чение вы­пол­ня­ет­ся дву­мя тран­зи­сто­ра­ми. На схе­ме вы ви­ди­те, что вход­ные сиг­на­лы сна­ча­ла про­хо­дят че­рез эле­мен­ты «ис­клю­чаю­щее или» (XOR). Они нуж­ны для то­го, что­бы обе сиг­наль­ные линии не со­дер­жа­ли вы­со­ко­го уров­ня в один мо­мент вре­мени, так как это вы­зо­вет ко­рот­кое за­мы­кание и не очень по­нра­вит­ся ва­ше­му ис­точнику пи­тания. Эта схе­ма под­ра­зу­ме­ва­ет, что для дви­га­те­ля ис­поль­зу­ет­ся от­дель­ный ис­точник пи­тания, и мы на­стоя­тель­но ре­ко­мен­ду­ем вам сде­лать имен­но так.

Мо­жет по­ка­зать­ся, что для ра­бо­ты дви­га­те­ля нуж­но при­ло­жить слиш­ком мно­го до­полнитель­ных уси­лий, осо­бен­но когда вы понимае­те, что вам на са­мом де­ле нуж­ны две этих схе­мы, по од­ной для ка­ж­до­го сер­дечника. К сча­стью, мир ком­мер­че­­ских ин­те­граль­ных схем сно­ва спа­са­ет всех нас, и на рын­ке мож­но най­ти мно­же­ст­во ва­ри­ан­тов мик­ро­схем двой­но­го H-моста по доступ­ным це­нам.

Ка­кая мик­ро­схе­ма вам по­на­до­бит­ся, за­ви­сит от ти­па дви­га­те­ля, но по­пу­ляр­ная мик­ро­схе­ма L293D по­дой­дет для боль­шин­ст­ва ша­го­вых дви­га­те­лей, ко­то­рые мо­гут вам встре­тить­ся. Ти­пич­ный ва­ри­ант под­клю­чения при­ве­ден на схе­ме 2. В ней, бла­го­да­ря то­му фак­ту, что несколь­ко пар про­во­дов од­но­вре­мен­но на­хо­дят­ся в со­стоянии «единица» или «ноль», чис­ло управ­ляю­щих вы­во­дов уда­ет­ся со­кра­тить до двух (с по­мо­щью несколь­ких до­полнитель­ных тран­зи­сто­ров).

Что ка­са­ет­ся управ­ления дви­га­те­лем – ну, для это­го опять же есть стан­дарт­ная биб­лио­те­ка:

(thumbnail)
Тео­ре­ти­че­ская схе­ма уп­ро­щен­но­го двух­по­люс­но­го ша­го­во­го дви­га­те­ля.
  1. include <Stepper.h>

Stepper myStepper(100, 9,10);

void setup() {

myStepper.setSpeed(10);

}

void loop() {

myStepper.step(100);

delay(500);

myStepper.step(-100);

delay(500);

}

Stepper – еще од­на стан­дарт­ная биб­лио­те­ка Arduino, ко­то­рая за­бо­тит­ся о генера­ции управ­ляю­щих сиг­на­лов и да­же умеет ра­бо­тать с дву­мя или че­тырь­мя вы­во­да­ми. Чис­ло вы­во­дов за­да­ет­ся при инициа­ли­за­ции объ­ек­та Stepper: пер­вый па­ра­метр – ко­ли­че­­ст­во ша­гов в пол­ном обо­ро­те, за ним идут два или че­ты­ре ис­поль­зуе­мых вы­во­да.

В ме­то­де setup за­да­ет­ся ско­рость дви­га­те­ля (в обо­ро­тах в ми­ну­ту). Управ­ление ско­ро­стью осу­ще­ст­в­ля­ет­ся от­дель­но от ра­бо­ты дви­га­те­ля, но нуж­но об этом помнить, по­то­му что это мо­жет при­вес­ти к бло­ки­ров­ке Arduino (то есть ис­полнение ко­да бу­дет за­дер­жа­но до тех пор, по­ка дви­га­тель не про­вернет­ся на оп­ре­де­лен­ное ко­ли­че­­ст­во ша­гов). Та­ким об­ра­зом, луч­ше пе­ре­ме­щать­ся неболь­ши­ми ша­га­ми и час­то, вме­сто то­го, что­бы сра­зу рвануть на боль­шое ко­ли­че­­ст­во ша­гов.

Ме­тод .step() вы­зы­ва­ет по­во­рот ро­то­ра дви­га­те­ля на за­дан­ное ко­ли­че­­ст­во ша­гов впе­ред (или, ес­ли ар­гу­мент от­ри­ца­те­лен, на­зад) с те­ку­щей ско­ро­стью. Та­ким об­ра­зом, 100 ша­гов на 100-ша­го­вом дви­га­те­ле, ра­бо­таю­щем с час­то­той 10 обо­ро­тов в ми­ну­ту, зай­мут 6 се­кунд.

Вот и все, что нуж­но для управ­ления дви­га­те­лем. Да­лее в этой се­рии мы рас­смот­рим управ­ле­ние дву­мя дви­га­те­ля­ми для соз­да­ния рель­со­вой те­леж­ки.

Персональные инструменты
купить
подписаться
Яндекс.Метрика