Один из подписчиков на моем канале в YouTube попросил сделать привод для жалюзи на базе Arduino UNO, и шаговых двигателях 28BYJ-48 5V.
Я так этим увлекся, что сделал аж целых два варианта.
Для сборки устройства понадобятся: Arduino UNO, 2 шаговых двигателя 28BYJ-48 5V на 5 вольт, 2 драйвера на базе микросхемы ULN2003, макетная плата (либо сразу припаять провода), соединительные провода около 20 штук, 4 кнопки, 1-4 концевиков (для второго варианта).
В первом варианте на каждый шаговый двигатель имеется по две кнопки. Где при нажатии и удержании, двигатель вращается в одну, либо в другую сторону.
Ниже представлен скетч. Он имеет только две настройки: это переменные t1 и t2, которые являются задержкой между переключениями фаз. В данный момент в скетче прописано значение 4, то есть 4 миллисекунды. Можете настроить их на свое усмотрение (чем больше значение t1, t2 тем медленнее вращается вал двигателя).
Чтобы вам было легче находить настройки, я сделал пометки в обеих скетчах //НАСТРОЙКА!!!//
Загрузите этот скетч в Arduino UNO.
//Начало скетча 1
const int buttonPin1 = 15; //15 контакт он же А1 мотор 1 вправо
const int buttonPin2 = 16; //16 контакт он же А2 мотор 1 влево
const int buttonPin3 = 17; //17 контакт он же А3 мотор 2 вправо
const int buttonPin4 = 18; //18 контакт он же А4 мотор 2 влево
int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int i1 = 0;
int i2 = 0;
int i3 = 0;
int i4 = 0;
int t1 = 4; //НАСТРОЙКА!!!//
int t2 = 4; //НАСТРОЙКА!!!//
void setup() {
//4, 5, 6, 7 контакты для 1 двигателя
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
// 12, 13, 10, 11 контакты для 2 двигателя
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
// контакты для кнопок
pinMode(15, INPUT_PULLUP); //А1
pinMode(16, INPUT_PULLUP); //А2
pinMode(17, INPUT_PULLUP); //А3
pinMode(18, INPUT_PULLUP); //А4
}
void prodlit() { //функция для продления цикла
buttonState1 = digitalRead( buttonPin1); buttonState2 = digitalRead( buttonPin2);
buttonState3 = digitalRead( buttonPin3); buttonState4 = digitalRead( buttonPin4);
if (buttonState1 == LOW) {
i1--;
} if (buttonState2 == LOW) {
i2--;
}
if (buttonState3 == LOW) {
i3--;
} if (buttonState4 == LOW) {
i4--;
}
}
void stopPins() {
digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW);
digitalWrite(7, LOW); digitalWrite(10, LOW); digitalWrite(11, LOW);
digitalWrite(12, LOW); digitalWrite(13, LOW); delay(500);
}
void loop() {
buttonState1 = digitalRead( buttonPin1);
if (buttonState1 == LOW) {
while (i1 < 1) { //цикл для вращения мотора 1 вправо
digitalWrite(7, HIGH); digitalWrite(5, LOW); delay(t1);
digitalWrite(6, HIGH); digitalWrite(4, LOW); delay(t1);
digitalWrite(5, HIGH); digitalWrite(7, LOW); delay(t1);
digitalWrite(4, HIGH); digitalWrite(6, LOW); delay(t1);
i1++; prodlit();
} i1 = 0; stopPins();
}
buttonState2 = digitalRead( buttonPin2);
if (buttonState2 == LOW) {
while (i2 < 1) { //цикл для вращения мотора 1 влево
digitalWrite(4, HIGH); digitalWrite(6, LOW); delay(t1);
digitalWrite(5, HIGH); digitalWrite(7, LOW); delay(t1);
digitalWrite(6, HIGH); digitalWrite(4, LOW); delay(t1);
digitalWrite(7, HIGH); digitalWrite(5, LOW); delay(t1);
i2++; prodlit();
} i2 = 0; stopPins();
}
buttonState3 = digitalRead( buttonPin3);
if (buttonState3 == LOW) {
while (i3 < 1) { //цикл для вращения мотора 2 вправо
digitalWrite(13, HIGH); digitalWrite(11, LOW); delay(t2);
digitalWrite(12, HIGH); digitalWrite(10, LOW); delay(t2);
digitalWrite(11, HIGH); digitalWrite(13, LOW); delay(t2);
digitalWrite(10, HIGH); digitalWrite(12, LOW); delay(t2);
i3++; prodlit();
} i3 = 0; stopPins();
}
buttonState4 = digitalRead( buttonPin4);
if (buttonState4 == LOW) {
while (i4 < 1) { //цикл для вращения мотора 2 влево
digitalWrite(10, HIGH); digitalWrite(12, LOW); delay(t2);
digitalWrite(10, HIGH); digitalWrite(12, LOW); delay(t2);
digitalWrite(11, HIGH); digitalWrite(13, LOW); delay(t2);
digitalWrite(12, HIGH); digitalWrite(10, LOW); delay(t2);
digitalWrite(13, HIGH); digitalWrite(11, LOW); delay(t2);
i4++; prodlit();
} i4 = 0; stopPins();
}
}
//Конец скетча 1
И соберите все согласно этой схемы.
Не удивляйтесь что оба двигателя запитанные на прямую от Arduino UNO, каждый из них потребляет чуть больше 310 миллиампер. Так как максимально допустимая нагрузка на плату составляет 500 миллиампер, то я написал программу так чтобы в одно время работал только один двигатель.
Должно получиться как на фото ниже.
Проверьте схему! Если все верно, то можете подключить питание к плате и протестировать как работает устройство.
Второй вариант отличается тем, что после нажатия и отпускания кнопки, шаговый двигатель продолжает вращаться на определенное количество шагов. Так же этот вариант дополнен возможностью подключения концевеков (концевеки использовать не обязательно).
Ниже представлен скетч второго варианта, он имеет уже 8 настроек.
Две настройки как и в первом варианте это t1 и t2, которые являются задержкой между переключениями фаз.
Две настройки х1, х2 которые отвечают за количество шагов которые предстоит выполнить при одном нажатии кнопки.
И 4 настройки, это переменная i которая имеет значение 50 . Эта переменная отвечает за количество шагов, которые необходимо выполнить при срабатывании концевека. То есть при срабатывании концевека, шаговый двигатель останавливается и выполняет обратное вращение чтобы отъехать от концевека на количество шагов, которое прописано в переменной i.
Можете загрузить скетч как есть, или при желании предварительно подредактировать настройки.
//Начало скетча 2
const int buttonPin0 = 14; //14 контакт он же А0 для концевека
const int buttonPin1 = 15; //15 контакт он же A1 мотор 1 вправо
const int buttonPin2 = 16; //16 контакт он же A2 мотор 1 влево
const int buttonPin3 = 17; //17 контпкт он же A3 мотор 2 вправо
const int buttonPin4 = 18; //18 контпкт он же A4 мотор 2 влево
int buttonState0 = 0;
int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int i = 0;
int i1 = 0;
int i2 = 0;
const int t1 = 4; //НАСТРОЙКА!!!//
const int t2 = 4; //НАСТРОЙКА!!!//
const int x1 = 1000; //НАСТРОЙКА!!!//
const int x2 = 1000; //НАСТРОЙКА!!!//
void setup() {
pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT);
pinMode(12, OUTPUT); pinMode(13, OUTPUT); pinMode(10, OUTPUT); pinMode(11, OUTPUT);
pinMode(14, INPUT_PULLUP);
pinMode(15, INPUT_PULLUP);
pinMode(16, INPUT_PULLUP);
pinMode(17, INPUT_PULLUP);
pinMode(18, INPUT_PULLUP);
}
void vyhod() { //функция для выхода из цикла
buttonState1 = digitalRead(buttonPin1); buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3); buttonState4 = digitalRead(buttonPin4);
if (buttonState1 == LOW) {
i1 = x1;
i2 = x2;
delay(500);
} if (buttonState2 == LOW) {
i1 = x1;
i2 = x2;
delay(500);
}
if (buttonState3 == LOW) {
i1 = x1;
i2 = x2;
delay(500);
} if (buttonState4 == LOW) {
i1 = x1;
i2 = x2;
delay(500);
}
}
void vpravo1() {
digitalWrite(7, HIGH); digitalWrite(5, LOW); delay(t1);
digitalWrite(6, HIGH); digitalWrite(4, LOW); delay(t1);
digitalWrite(5, HIGH); digitalWrite(7, LOW); delay(t1);
digitalWrite(4, HIGH); digitalWrite(6, LOW); delay(t1);
}
void vlevo1() {
digitalWrite(4, HIGH); digitalWrite(6, LOW); delay(t1);
digitalWrite(5, HIGH); digitalWrite(7, LOW); delay(t1);
digitalWrite(6, HIGH); digitalWrite(4, LOW); delay(t1);
digitalWrite(7, HIGH); digitalWrite(5, LOW); delay(t1);
}
void vpravo2() {
digitalWrite(13, HIGH); digitalWrite(11, LOW); delay(t2);
digitalWrite(12, HIGH); digitalWrite(10, LOW); delay(t2);
digitalWrite(11, HIGH); digitalWrite(13, LOW); delay(t2);
digitalWrite(10, HIGH); digitalWrite(12, LOW); delay(t2);
}
void vlevo2() {
digitalWrite(10, HIGH); digitalWrite(12, LOW); delay(t2);
digitalWrite(11, HIGH); digitalWrite(13, LOW); delay(t2);
digitalWrite(12, HIGH); digitalWrite(10, LOW); delay(t2);
digitalWrite(13, HIGH); digitalWrite(11, LOW); delay(t2);
}
void vyklPins() {
digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
digitalWrite(12, LOW); digitalWrite(13, LOW); digitalWrite(10, LOW); digitalWrite(11, LOW); delay(500);
}
void loop() {
buttonState1 = digitalRead(buttonPin1);
if (buttonState1 == LOW) {
delay(500);
while (i1 < x1) { //цикл для вращения мотора 1 вправо
vpravo1(); i1++; vyhod();
buttonState0 = digitalRead(buttonPin0);
if (buttonState0 == LOW) {
delay(100); i1 = x1;
while (i < 50) { //НАСТРОЙКА!!!//
vlevo1(); i++;
} i = 0; vyklPins();
}
}
i1 = 0; vyklPins();
}
buttonState2 = digitalRead(buttonPin2);
if (buttonState2 == LOW) {
delay(500);
while (i1 < x1) { //цикл для вращения мотора 1 влево
vlevo1(); i1++; vyhod(); //функция для выхода из цикла
buttonState0 = digitalRead(buttonPin0);
if (buttonState0 == LOW) {
delay(100); i1 = x1;
while (i < 50) { //НАСТРОЙКА!!!//
vpravo1(); i++;
} i = 0; vyklPins();
}
} i1 = 0; vyklPins();
}
buttonState3 = digitalRead(buttonPin3);
if (buttonState3 == LOW) {
delay(500);
while (i2 < x2) { //цикл для вращения мотора 2 вправо
vpravo2(); i2++; vyhod(); //функция для выхода из цикла
buttonState0 = digitalRead(buttonPin0);
if (buttonState0 == LOW) {
delay(100); i2 = x2;
while (i < 50) { //НАСТРОЙКА!!!//
vlevo2(); i++;
} i = 0; vyklPins();
}
} i2 = 0; vyklPins();
}
buttonState4 = digitalRead(buttonPin4);
if (buttonState4 == LOW) {
delay(500);
while (i2 < x2) { //цикл для вращения мотора 2 влево
vlevo2(); i2++; vyhod(); //функция для выхода из цикла
buttonState0 = digitalRead(buttonPin0);
if (buttonState0 == LOW) {
delay(100); i2 = x2;
while (i < 50) { //НАСТРОЙКА!!!//
vpravo2(); i++;
} i = 0; vyklPins();
}
} i2 = 0; vyklPins();
}
}
//Конец скетча 2
После чего можно приступать к сборке устройства согласно схемы представленной ниже.
Как видите концевеки подключаются параллельно, это означает что всего на 2 контакта можно подключать любое количество концевеков. И при срабатывании любого из них, вал двигателя отъедет в обратном направлении, не зависимо от того какой из двигателей работал и в каком направлении вращался вал.
Если все собрано, то можете подключить питание и протестировать устройство.
Так как у меня не нашлось свободного концевека, то вместо него пришлось применить еще одну кнопку!