Sw-motors.ru

Автомобильный журнал
1 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Управление шаговым двигателем 28byj-48 из ПЛИС на Verilog

Управление шаговым двигателем 28byj-48 из ПЛИС на Verilog

Честно говоря у нас на сайте уже была статья про двигатели. В той статье было кратко рассказано про коллекторные и шаговые двухфазные и трехфазные двигатели. Там же был и проект Quartus для управления двигателями из платы Марсоход. Здесь в этой статье я расскажу, как управлять именно этим 28byj-48 в полнофазном (full step) и полуфазном (half step) режиме. Напишем программу управления на Verilog HDL.

Двигатель делает один оборот ротора за 32 шага в полнофазном режиме или за 64 шага в полуфазном режиме. Кроме того, имеется встроенный редуктор с коэффициентом передачи примерно 1/64.

Двигатель 28byj-48 имеет 5 выводов и его схема выглядит вот так:

Условно говоря у двигателя имеется две катушки с выводами посередине, эти выводы объединены в один провод (красный) обычно подключаемый к питанию (или к земле, ). Таким образом, получаются четыре катушки, которые можно независимо включать. Вообще-то через катушки течет довольно большой ток, это еще зависит от напряжения питания. Но в общем случае напрямую к микроконтроллеру или ПЛИС их желательно подключать через драйвер двигателя. Для 28byj-48 часто применяют драйвер на базе микросхемы ULN2003:

Управляющие сигналы, четыре фазы подключаются ко входам IN2, IN2, IN3, IN4, шаговый двигатель подключается специальному 5-ти штырьковому коннектору. Еще нужно подавать питание до +12 вольт. Я питал сам мотор и драйвер двигателя от платы Марсоход с напряжением +3,6В и вполне работает.

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

На языке Verilog HDL такое поведение очень просто описать с помощью такой конструкции:

module fs_motor(
input wire clk,
output reg f0,
output reg f1,
output reg f2,
output reg f3
);

reg [1:0]cnt = 0;
always @( posedge clk)
cnt

always @( posedge clk)
begin
f0
f1
f2
f3
end

Счетчик cnt является двухбитным. Два бита описывают 4 состояния. Каждая катушка включена на два такта и при этом всегда включены и работают две соседние катушки. Временные диаграммы сигналов для полнофазного режима работы шагового двигателя будут вот такие:

В полуфазном режиме картина немного другая, состояний 8 поэтому счетчик нужен трехбитный:

module hs_motor(
input wire clk,
output reg f0,
output reg f1,
output reg f2,
output reg f3
);

reg [2:0]cnt = 0;
always @( posedge clk)
cnt

always @( posedge clk)
begin
f0
f1
f2
f3
end

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

Временные диаграммы выглядят вот так:

Просимулировать самостоятельно модули управления двигателей можно с помощью вот такого простого тестбенча verilog:

reg clock = 0;
always
#10 clock =

wire fw0, fw1, fw2, fw3;
wire hw0, hw1, hw2, hw3;

//full-step motor instance
fs_motor fsm(
.clk( clock),
.f0( fw0 ),
.f1( fw1 ),
.f2( fw2 ),
.f3( fw3 )
);

//half step motor instance
hs_motor hsm(
.clk( clock),
.f0( hw0 ),
.f1( hw1 ),
.f2( hw2 ),
.f3( hw3 )
);

initial
begin
$dumpfile(«out.vcd»);
$dumpvars(0,tb);
#1000;
$finish();
end

Зачем мне понадобился этот шаговый двигатель? Я тут сделал такую игрушку — Marble Machine. И в ней спираль как раз вращается именно таким двигателем, а управление она берет из нашей платы Марсоход.

Работа моей Marble Machine:

Все пластиковые детали для этой машины напечатаны на 3D принтере FLSUN-QQ.

Как подключить электродвигатель к Arduino

Как известно, электродвигатели бывают трёх основных типов: коллекторные, шаговые и сервоприводы. В данной статье мы рассмотрим подключение коллекторного электродвигателя к Arduino с помощью драйвера двигателей на основе микросхемы L9110S или аналогичной.

Для проекта нам понадобятся:

  • коллекторный электродвигатель постоянного тока или аналогичный;
  • драйвер двигателя L9110S, или шилд на микросхеме L293D или аналогичный;
  • шаговый двигатель 28BYJ-48 с драйвером ULN2003 или аналогичный;
  • Arduino UNO или иная совместимая плата;
  • соединительные провода (например, вот такой набор);
  • макетная плата;
  • персональный компьютер со средой разработки Arduino IDE.

1 Что такое драйвер двигателей и для чего он нужен

Максимальный ток на выводах Arduino слаб (около 50 мА) для такой мощной нагрузки как электромотор (десятки и сотни миллиампер). Поэтому напрямую к выводам Arduino подключать электродвигатель нельзя: есть риск сжечь вывод, к которому подключён двигатель. Для безопасного подключения электродвигателей разных типов к Arduino необходим самодельный или промышленно изготовленный т.н. драйвер двигателей. Драйверы двигателей бывают разные, для их работы часто используются микросхемы типа HG788, L9110S, L293D, L298N и другие. Драйверы двигателей имеют выводы подачи питания, выводы для подключения электродвигателей, а также управляющие выводы.

Читать еще:  Безконденсаторный запуск однофазного двигателя

Различные варианты исполнения драйверов двигателей

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

2 Схема подключения коллекторного двигателяи драйвера двигателей к Arduino

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

Давайте подключим двигатель по приложенной схеме. Питание драйвера двигателя – 5 В от Arduino, для управления скоростью вращения ротора мотора управляющие контакты подключаем к выводам Ардуино, поддерживающим ШИМ (широтно-импульсную модуляцию).

Схема подключения коллекторного двигателя к Arduino с помощью драйвера двигателей

Должно получиться что-то подобное:

Двигатель подключён к драйверу двигателей и Arduino

3 Скетч для управления коллекторным двигателем

Напишем скетч для управления коллекторным двигателем. Объявим две константы для ножек, управляющих двигателем, и одну переменную для хранения значения скорости. Будем передавать в последовательный порт значения переменной Speed и менять таким образом скорость (значением переменной) и направление вращения двигателя (знаком числа).

Загрузим скетч в память Arduino. Запустим его. Вал двигателя не вращается. Чтобы задать скорость вращения, нужно передать в последовательный порт значение от 0 до 255. Направление вращения определяется знаком числа.

Подключимся с помощью любой терминалки к порту, передадим число «100» – двигатель начнёт вращаться со средней скоростью. Если подадим «минус 100», то он начнёт вращаться с той же скоростью в противоположном направлении.

Управление электромотором с помощью драйвера двигателей и Arduino

А вот так выглядит подключение подключение коллекторного двигателя к Arduino в динамике:

4 Управление шаговым двигателем с помощью Arduino

Шаговый двигатель позволяет вращать ротор на определённый угол. Это бывает полезно, когда необходимо задать положение какому-либо механизму или его узлу. Шагом двигателя называется минимальный угол, на который можно повернуть ротор двигателя. Угол поворота и направление движения задаются в управляющей программе. Существует большое разнообазие шаговых двигателей. Рассмотрим работу с ними на примере двигателя 28BYJ-48 с драйвером ULN2003.

Шаговый двигатель с контроллером —> Шаговый двигатель с контроллером

Характеристики двигателя 28BYJ-48:

ХарактеристикаЗначение
Количество фаз4
Напряжение питанияот 5 до 12 В
Число шагов64
Размер шага5,625°
Скорость вращения15 об./сек
Крутящий момент450 г/см

Модуль с микросхемой драйвера для управления шаговым двигателем выглядит так:

Модуль с драйвером ULN2003

На входы IN1…IN4 подаются управляющие сигналы от Arduino. Используем любые 4 цифровых пина, например, D8…D11. На вход питания необходимо подать постоянное напряжение от 5 до 12 В. Двигателю желательно обеспечить отдельное питание. Но в данном случае, т.к. не планируется использовать двигатель на постоянной основе, можно подать питание и от Arduino. Перемычка «Вкл/выкл» просто разрывает «плюс» питания, подаваемого на драйвер. В «боевом» изделии сюда можно, например, коммутировать питание с помощью реле, когда это необходимо, чтобы снизить потребление всего изделия. Итак, схема подключения будет такой:

Схема подключения шагового двигателя с драйвером ULN2003 к Arduino

Соберём всё по схеме.

Подключение шагового двигателя 28BYJ-48 к Arduino

Для Arduino «из коробки» существует готовая библиотека для управления шаговыми двигателями. Она называется Stepper. Можно посмотреть готовые примеры в среде разработки для Arduino: File Examples Stepper. Они позволяют управлять шаговым двигателем, изменяя скорость и направление движения, поворачивать ротор на заданный угол. Как говорится – бери и пользуйся. Но давайте попробуем разобраться с принципом работы шагового двигателя самостоятельно, не применяя никаких библиотек.

Двигатель 28BYJ-48 имеет 4 фазы. Это означает, что у него имеются 4 электромагнитные катушки, которые под действием электрического тока притягивают сердечник. Если напряжение подавать на катушки поочерёдно, это заставит сердечник вращаться. Рисунок иллюстрирует данный принцип.

Схема работы шагового двигателя

Здесь на (1) напряжение подано на катушки A и D, на (2) – на A и B, (3) – B и С, (4) – C и D. Далее цикл повторяется. И таким образом ротор двигателя вращается по кругу.

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

Простейший скетч управления шаговым двигателем (разворачивается)

Как можно догадаться, задержка del определяет скорость вращения двигателя. Уменьшая или увеличивая её можно ускорять или замедлять двигатель.

Если загрузить этот скетч, то увидим, что шаговый двигатель вращается против часовой стрелки. Соответственно, можно вынести цикл вращения в одну сторону в отдельную функцию rotateCounterClockwise(). И сделать аналогичную функцию вращения в противоположную сторону rotateClockwise(), в которой фазы будут следовать в обратном порядке. Также вынесем в отдельные функции каждую из 4-х фаз чтобы избежать дублирования одинакового кода в нескольких местах программы. Теперь скетч выглядит несколько интереснее:

Скетч управления шаговым двигателем (разворачивается)

Если мы загрузим скетч и проверим, поворачивается ли ротор двигателя на целый оборот, если один раз вызвать функцию rotateClockwise(), то обнаружим, что нет. Для совершения полного оборота функцию необходимо вызвать несколько раз. Соответственно, хорошо бы добавить в качестве аргумента функции число, которое будет показывать количество раз, которые она должна выполняться.

Финальный скетч управления шаговым двигателем (разворачивается)

Вот теперь совсем другое дело! Мы можем управлять скоростью шагового двигателя, задавая задержку после каждой фазы. Мы можем менять направление движения ротора двигателя. И, наконец, мы умеем поворачивать ротор на некоторый угол. Осталось только определить, какое число необходимо передавать в функции поворота rotateClockwise() и rotateCounterClockwise(), чтобы ротор шагового двигателя 1 раз провернулся на 360° вокруг своей оси. Собственно, дальнейшие наработки – вопрос фантазии или необходимости.

СТАНОК С ЧПУ СВОИМИ РУКАМИ

Последние публикации
  • Гравировка CO2-лазером герба РФ на стеклянном стаканчике
    Подробнее
  • Гравировка CO2-лазером фотографии на стекле
    Подробнее
  • Интернет-сервис формирования G-кода из BMP, JPG, GIF, PNG
    Подробнее
  • Рисуем в Paint эскиз для резки CO2-лазером
    Читать
  • Определение величины задержки между шагами ШД
    Читать
  • Гравировка CO2-лазером на металле с использованием пасты
    Читать
  • Резка по изображению «от руки», чертежу или растровой картинке
    Читать
Заметки
  • Прошиваем GRBL в Ардуино UNO. Ошибка avrdude: stk500_recv(): programmer is not responding
    Читать
  • Изготовление источника питания для двигателей из старых зарядников.
    Читать
  • Муфта соединения оси шагового двигателя и оси винтовой передачи.
    Читать
  • Каретка винтовой передачи скольжения станка с ЧПУ.
    Читать
  • Подключение драйвера ШД на TB6560 к Ардуино, шаговому двигателю и БП.
    Читать
  • Запуск CO2-лазера при отрицательной температуре
    Читать

Прошивка Ардуино для станка с ЧПУ, драйверы ULN2003, двигатели 28BYJ-48-5V

Краткое описание

  • Контроллер: Ардуино
  • Драйверы ШД: ULN2003
  • Шаговые двигатели: 28BYJ-48-5V
  • Назначение: рисование, фрезерование 2D, фрезерование 3D

Подробное описание

Прошивка для платы Ардуино написана на языке Processing в среде разработки Arduino 1.0.2 в операционной системе Windows.
Данный скетч используется для работы самого дешёвого варианта станка с ЧПУ. Эта прошивка работает с 3-хосевым станком с ЧПУ. Используются драйверы шаговых двигателей ULN2003 и шаговые двигатели 28BYJ-48-5V.
Прошивка может использоваться для рисования, фрезерования 2D (обведение или полное вырезание силуэтов и орнаментов), а также для 3D-фрезерования. Работает очень медленно, ибо скорость работы шаговых двигателей 28BYJ-48-5V крайне мала.

Исходный код прошивки Ардуино

int motorPins[3][4] = <<2, 3, 4, 5>,<6, 7, 8, 9>,<10, 11, 12, 13>>;
int count;
int count2[3] = <0,0,0>;
int delayTime;
int val = 0;
int rot=0;
int incomingByte = 0;
int sign=1;

//Процедура настройки прошивки
void setup() <
int i;
Serial.begin(9600);

for (i=0; i >=1;
for (count = 3; count >= 0; count—) <
digitalWrite(motorPins[sm][count], count2[sm]>>count&0x01);
>
>

//Поворот двигателя с номерм sm на один шаг назад
void moveBackward(int sm) <
if ((count2[sm] == 0) || (count2[sm] == 1)) <
count2[sm] = 16;
>
count2[sm]>>=1;
for (count = 3; count >= 0; count—) <
digitalWrite(motorPins[sm][3 — count], count2[sm]>>count&0x01);
>
>

//Одновременный поворот двигателей 0, 1, 2 на x, y, z шагов соответственно
void MoveSM(long x, long y, long z) <
long c[3], c2[3];
double c1[3], d[3];
long m, i;
boolean flg;

Uln2003 схема подключения шагового двигателя

Управление шаговым двигателем 28BYJ-48
Попался мне в руки Шаговый двигатель 28BYJ-48 решил его использовать для управления жалюзи на кухне.
Шаговый двигатель 28BYJ-48, использует в кондиционерах, термовентиляторах и т.п.
Он как правило продается с простейшим драйвером собранном на микросхеме ULN2003
На плате есть 4 светодиода отображающие на какой из обмоток есть напряжение

Характеристики:
номинальное напряжение питания: 5В или 12В
число фаз: 4
сопротивление фазы: 200 Ом ±7%
угловой шаг: 5,625°
соотношение: 1:64
частота: 100 Гц
крутящий момент: 450 г*см
сопротивление изоляции: >10 МОм (500В)
диаметр: 25 мм высота 18мм.
плата управления: 27 х 17 мм.
общий вес: до 80 гр.

Со встроенной библиотекой Stepper Library, моторчик отказался работать
Написал тестовый скетч для ардуино, что бы заставить его вращаться
В полношаговом режиме

void setup ()
<
step_init ;
step_stop ;
>

step1 ;
step2 ;
step3 ;
step4 ;

void setup ()
<
step_init ;
step_stop ;
>

void loop ()
< Start
step1 ;
step2 ;
step3 ;
step4 ;
step5 ;
step6 ;
step7 ;
step8 ;
End >

Admin
Посмотреть профиль
Отправить личное сообщение для Admin
Найти ещё сообщения от Admin

Тоже эксперементировал с таким шаговиком для управления оконными жалюзями. Хотелось чтобы подходили к 2-м жалюзям 4 провода (2 витых пары, а не 9 = 1 земля питания + 4 фазы + 4 фазы для управления всеми обмотками), поэтому сделал управление на ATTINY2313 и ULN2003, макетка влезла внутрь корпуса жалюзи. ATTINY2313 управляется по UART, т.е. требуется 4 провда «+»,»-«,»rx»,»tx». Реализованы 4 команды полное открытие, полное закрытие, открытие на определенный угол, закрытие на определенный угол. Открытие-закрытие делал поворотом пластин, поднятие/опускание не делал. Шаговик соединял с осью вращения через обрезок корпуса ручки, на ось и шаговик наматывал изоленту, чтобы и плотно было и могло немного проскользнуть. Небольшое проскальзывание нужно чтобы не использовать датчики конечных положений. При инициализации просто поворачивается на угол чуть больше максимального поворота, за счет проскальзывание выставляетс в «0». Потом уже от этого нуля высталяется угол.

#define MAX_COMMAND_LEN 16 //Максимальная длина команды
#define DEVICE_NUM 1 //Номер этого устройства
#define NUM_DRIVES 2 //Количество приводов
#define nop() //подключаем функция для формирваония задержки

void Close ( unsigned char Drive , unsigned char Count ); //Прототип функции поворота ротора ШД вправо
void Open ( unsigned char Drive , unsigned char Count ); //Прототип поворота влево
void USART_Init ();
unsigned char USART_Receive ( void );
//void USART_Transmit( unsigned char data );
unsigned char USART_Command [ MAX_COMMAND_LEN ];
static unsigned char CurrentPos [ NUM_DRIVES ];

int m = 1 ; //переменные

bool ReadCommand ( void )
<
unsigned char UART_char ;

//Очищаем буфер
for( unsigned char Count = 0 ; Count MAX_COMMAND_LEN ; Count ++) USART_Command [ Count ]= 0 ;

//Читаем первый символ
UART_char = USART_Receive ();

//Исли первый символ не ‘#’, значит это не начало команды
if ( UART_char == ‘#’ ) UART_char = USART_Receive ();

//Читаем дальше если команда для этого устройства или 0 (широковещательный адрес, для всех)
if (( UART_char == 0 )||(( UART_char == DEVICE_NUM ))) <

//Читаем UART и заполняем буфер
for( unsigned char Count = 0 ; Count MAX_COMMAND_LEN ; Count ++)
<
UART_char = USART_Receive ();
USART_Command [ Count ] = UART_char ;
if( UART_char == ‘n’ ) break; //Если «окончание строки», то считаем что закончили считывать команду
>

//На всякий случай, если переданная строка больше размера буфера в конце ставим «окончание строки»
USART_Command [ MAX_COMMAND_LEN — 1 ] = ‘n’ ;

//Удачно считали команду
return true ;

//Исли символ не ‘#’, значит это это не команда
else return false ;
>

unsigned char N , P ;
DDRB = 0xFF ; //Конфигурирования порта на выход
PORTB = 0x00 ; //Отключаем подтягивающие резисторы порта
CurrentPos [ 0 ] = 170 ; //Считаем что жалюзи открыты, чтобы закрыть их
CurrentPos [ 1 ] = 170 ;
Close ( 0 , 175 ); //Закрываем жалюзи

USART_Init ();
//USART_Transmit(‘D’);
for(;;) //Вечный цикл
<
if ( ReadCommand ()) <
//Формат команды: C N P
//C-байт команды, N-байт номер привода, P-байт параметр
N = USART_Command [ 1 ];
P = USART_Command [ 2 ];

if ( N NUM_DRIVES )
switch( USART_Command [ 0 ]) <
case ‘O’ :
Open ( N , 170 );
break;
case ‘C’ :
Close ( N , 180 );
break;
case ‘o’ :
Open ( N , P );
break;
case ‘c’ :
Close ( N , P );
break;
>

//Функция задержки
void delay ( int t )
<
for ( int x = 0 ; x t ; x ++)
nop ();
>

//Функция поворота ротора вправо
//Drive — номер привода (0, 1, . )
//Count — количество циклов поворота
void Open ( unsigned char Drive , unsigned char Count )
<
unsigned char NewPos , Bit ;

//Определяем какой бит(номер вывода, к которому подключен ШД) будеv двигать (0 — оба)
Bit = ( Drive == 0 ) ? 0b10001000 : Bit = ( Drive == 1 ) ? 0b00001000 : 0b10000000 ;

//Определяем новую позицию, куда нужно переместить ШД
NewPos = (( CurrentPos [ Drive ] + Count ) >= 170 ) ? 170 : CurrentPos [ Drive ] + Count ;

for( unsigned char i = CurrentPos [ Drive ]; i NewPos ; i ++)
<

PORTB = Bit ; //обмотка A
delay ( 3000 );

PORTB >>= 1 ; //обмотка B
delay ( 3000 );

PORTB >>= 1 ; //обмотка C
delay ( 3000 );

//PORTB = 0b00010001;//обмотка D
PORTB >>= 1 ; //обмотка D
delay ( 3000 );

CurrentPos [ Drive ] = NewPos ; //Запоминаем позицию, в которой находятся жалюзи

//Функция поворота ротора влево
//Drive — номер привода
//Count — количество циклов поворота
void Close ( unsigned char Drive , unsigned char Count )
<
unsigned char Delta , Bit ;

//Если количество шагов больше чем может быть (упрется в ограничитель),
//то выводим в 0 с запасм 5 шагов (вдруг не успел IL отрабоать что-то из-за частоты, напряжения и т.д.)
if ( CurrentPos [ Drive ] Count ) <
Delta = CurrentPos [ Drive ] + 5 ; //Определяем на сколько нужно помернуть ШД
CurrentPos [ Drive ] = 0 ; //Запоминаем позицию, в которой находятся жалюзи
>
else <
CurrentPos [ Drive ] -= Count ; //Определяем на сколько нужно помернуть ШД
Delta = Count ; //Запоминаем позицию, в которой находятся жалюзи
>

//Bit = (Drive==1) ? 0b00000001 : 0b00010000;//Определяем какой бит(номер вывода, к которому подключен ШД) будет двигать
Bit = 0b00010001 ;

for( unsigned char i = 0 ; i Delta ; i ++)
<
PORTB = Bit ;
delay ( 3000 );

PORTB 1 ;
delay ( 3000 );

PORTB 1 ;
delay ( 3000 );

PORTB 1 ;
delay ( 3000 );
>
PORTB = 0x00 ;

void USART_Init ( void ) //Функция инициализации USART
<
unsigned int speed ;
speed = 103 ; //9600
UBRRH = ( unsigned char ) ( speed >> 8 );
UBRRL = ( unsigned char ) speed ;
UCSRA = ( 1 U2X ); //Удвоение скорости
UCSRB = ( ( 1 RXEN ) | ( 1 TXEN ) ); //Разрешение на прием и н апередачу через USART
UCSRC = ( 1 USBS ) | ( 3 UCSZ0 );
>

unsigned char USART_Receive ( void ) //Функция приема данных
<
while ( !( UCSRA & ( 1 RXC )) ); //Ожидание приема символа
return UDR ; //Возврат символа
>
/*
void USART_Transmit( unsigned char data ) //Функция отправки данных
<
while ( !(UCSRA & (1

голоса
Рейтинг статьи
Ссылка на основную публикацию
ВсеИнструменты
Adblock
detector