Arduino и шаговый двигатель BYJ48
Шаговый двигатель представляет собой двигатель, управляемый электромагнитными катушками. Центральный вал имеет ряд магнитов, и окружающие вал катушки при подаче на них тока поочередно создают магнитные поля, которые воздействуют на магниты, тем самым заставляя вал двигателя вращаться. Такой подход позволяет реализовать точное управление положением вала двигателя.
Существуют два типа шаговых двигателей – униполярные и биполярные. Сегодня речь пойдет про униполярный шаговый двигатель 28-BYJ48.
Униполярный двигатель имеет пять или шесть проводов и четыре катушки (на самом деле две катушки, поделенные пополам в центральной точке). Центральные точки связаны друг с другом и используются для подключения питания. Униполярные двигатели получили такое название, потому что питание всегда подводится только к одному полюсу.
Шаг 1: подбор компонентов
Сегодня существует достаточно большое количество типов драйверов шаговых двигателей: L293, ULN2003, A3967SLB и т.д. Мотор 28-BYJ48 зачастую идет вместе с ULN2003. Если же вы решите использовать L293, то в этом случае нужно будет оставить красный провод неиспользованным.
Итак, что нам понадобится:
Плата Arduino Uno
Шаговый двигатель 28-BYJ48 5В
Драйвер ULN2003
Джампер
Внешний источник 5В (желательно, но не обязательно)
Шаг 2: количество шагов и подключение
Примеры для работы с шаговым двигателем, доступные в среде разработки Arduino IDE, очень просто использовать. После соединения платы с двигателем можно загрузить скетч и … все-таки нужно учесть некоторые моменты. Данный мотор имеет передаточное отношение 64 и угол поворота 5.625°. Поэтому он будет характеризоваться 4096 шагами.
Количество шагов = количество шагов на один оборот * передаточное отношение = (360°/5.625°) * 64 = 64 * 64 = 4096.
Например, для двигателя с углом 7.5° и отношением 16 будем иметь:
Количество шагов = (360°/7.5°) * 16 = 48 * 16 = 768
Поэтому всегда нужно учитывать, какой мотор вы используете, проверяя его параметры по документации.
Плата драйвера ULN2003 соединяется выводами IN1 - IN4 с контактами D8 - D11 платы Arduino. Для питания двигателя рекомендуется использовать внешний источник питания 5В-500мА, поскольку при питании от платы Arduino есть вероятность того, что не хватит тока.
Шаг 3: проблемы выбора направления стандартной библиотеки и модификация кода
После загрузки кода двигатель будет вращаться в одном направлении за счет команды step(steps). Здесь вместо steps нужно указать количество шагов, которые должен совершить ваш мотор. В справочном материале сказано, что для вращения в одном направлении следует указать положительное значение, а для вращения в другом направлении – отрицательное. Но за этим также следует приписка, что это может подойти не для всех двигателей, и в таком случае вал будет вращаться в одном направлении независимо от знака. Так как же быть, если наш двигатель не будет реверсировать? Для решения этой проблемы был написан нижеприведенный код. Он позволяет валу шагового двигателя вращаться как по часовой, так и против часовой стрелки.
#define IN1 8
#define IN2 9
#define IN3 10
#define IN4 11
int Steps = 0;
boolean Direction = true;
unsigned long last_time;
unsigned long currentMillis ;
int steps_left=4095;
long time;
void setup()
{
Serial.begin(115200);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
// delay(1000);
}
void loop()
{
while(steps_left>0){
currentMillis = micros();
if(currentMillis-last_time>=1000){
stepper(1);
time=time+micros()-last_time;
last_time=micros();
steps_left--;
}
}
Serial.println(time);
Serial.println("Wait...!");
delay(2000);
Direction=!Direction;
steps_left=4095;
}
void stepper(int xw){
for (int x=0;x<xw;x++){
switch(Steps){
case 0:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
break;
case 1:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, HIGH);
break;
case 2:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
break;
case 3:
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
break;
case 4:
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
break;
case 5:
digitalWrite(IN1, HIGH);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
break;
case 6:
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
break;
case 7:
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
break;
default:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
break;
}
SetDirection();
}
}
void SetDirection(){
if(Direction==1){ Steps++;}
if(Direction==0){ Steps--; }
if(Steps>7){Steps=0;}
if(Steps<0){Steps=7; }
}