Шаговый двигатель 28BYJ-48. Прошу помощи в доработке класса

а случайно в AccelStepper.h этого нету ?
да и если вы сами пишите, то почему так не понятно ?
вот так надо делать, возьмите за основу!

// порты для подключения модуля ULN2003 к Arduino
#define in1 8
#define in2 9
#define in3 10     //возможно 3 и 4 надо поменять местами
#define in4 11     //возможно 3 и 4 надо поменять местами
int dl = 5;        // время задержки между импульсами
bool flag = false; // определяем направление вращения

void setup() {
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
}

void loop() {
if (flag==false) {
digitalWrite(in1, HIGH); 
digitalWrite(in2, LOW); 
digitalWrite(in3, LOW); 
digitalWrite(in4, LOW);
delay(dl);
digitalWrite(in1, HIGH); 
digitalWrite(in2, HIGH); 
digitalWrite(in3, LOW); 
digitalWrite(in4, LOW);
delay(dl);
digitalWrite(in1, LOW); 
digitalWrite(in2, HIGH); 
digitalWrite(in3, LOW); 
digitalWrite(in4, LOW);
delay(dl);
digitalWrite(in1, LOW); 
digitalWrite(in2, HIGH); 
digitalWrite(in3, HIGH); 
digitalWrite(in4, LOW);
delay(dl);
digitalWrite(in1, LOW); 
digitalWrite(in2, LOW); 
digitalWrite(in3, HIGH); 
digitalWrite(in4, LOW);
delay(dl);
digitalWrite(in1, LOW); 
digitalWrite(in2, LOW); 
digitalWrite(in3, HIGH); 
digitalWrite(in4, HIGH);
delay(dl);
digitalWrite(in1, LOW); 
digitalWrite(in2, LOW); 
digitalWrite(in3, LOW); 
digitalWrite(in4, HIGH);
delay(dl);
digitalWrite(in1, HIGH); 
digitalWrite(in2, LOW); 
digitalWrite(in3, LOW); 
digitalWrite(in4, HIGH);
delay(dl);
}
if (flag==true) { // тут надо дописать направление в другую сторону

}

}
1 лайк

Спасибо! Этим скетчем вы подтвердили мою правоту.

Не проверял. Мне хватило Stepper.h.

Наоборот. Понятно.

У меня такой же принцип Строки 39-42… Только теперь он реализован в процедуре обработки прерываний по таймеру. Прерывание срабатывает примерно раз в миллисекунду. Направление устанавливается в строке 10.

#include <avr/interrupt.h>

// Подключение шагового двигателя
#define IN1 8
#define IN2 9
#define IN3 10
#define IN4 11

volatile byte takt = 0;
volatile bool arrow = true; // если false, то обратное вращение

void setup()
{
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);

  pinMode(13, OUTPUT);
  digitalWrite(13, 0);

  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  OCR1A = 16;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS10);
  TCCR1B |= (1 << CS12);
  TIMSK1 |= (1 << OCIE1A);
  sei();
}
void loop()
{
}

ISR(TIMER1_COMPA_vect)
{
  takt = (takt + 2 * arrow - 1) & 7;
  digitalWrite(IN1, bitRead(0b00000111, takt));
  digitalWrite(IN2, bitRead(0b00011100, takt));
  digitalWrite(IN3, bitRead(0b01110000, takt));
  digitalWrite(IN4, bitRead(0b11000001, takt));
}

Ваш скетч проверил. Работает. Пробовал менять местами пины 3 и 4. Не работает. время задержки между импульсами достаточно 1 миллисекунды. Недавно пытался подобрать задержку. 850 микросекунд еще работает, а при 800 - нет.

Строка 38 - это намек @andriano в #24, а строки 39-42 - намек @ЕвгенийП в #37.

а он все же делает этот микрошаг ?))) сам мотор поддерживает этот микрошаг ?
или ему все таки будет мешать механика внутри моторчика это сделать ?

нечего я не подтверждал)))

у меня эти моторчики закончились… и я вовсе не уверен что микрошаг этот выйдет, потому что там еще механика может не позволить сделать этот микрошаг…

и проверять лучше на моем скетче, ваш по крайней мере для меня не понятный…

Ваш скетч я проверил. Об этом написано в последних строках #62.

В строке 38 моего скетча переменная takt меняется или от 0 до 7 или от 7 до 0 в зависимости от направления arrow.

В строках 39-42 переменная takt “говорит” пину - в соответствии с каким битом принять ему состояние.

Например, восьмой пин (строка 39), когда takt будет меняться от 7 до 0 будет принимать такие состояния: 11100000. Если takt=7, то PIN8 (IN1)=1, ПИН9 (IN2) =0, ПИН10 (IN3)=0, ПИН11(IN4)=1. В Вашем скетче это строки 53-56. А когда takt будет равен 6, то PIN8 (IN1)=0, ПИН9 (IN2) =0, ПИН10 (IN3)=0, ПИН11(IN4)=1. В Вашем скетче это строки 48-51. И т. д.

Поддерживает.

Вот здесь об этом написано.

Но диаграмма для полушагового режима там брехливая.

Это непростая задача.
Стандартная библиотека выводит один символ 2.9 мс.

Поддерживать деление шагов (микрошаг) будет любой шаговый.
Использованием 28BYJ-48 с драйвером ULN2003 даже полушага не добиться.
Если 28BYJ-48 слегка разобрать и разорвать внутреннее соединение средних выводов обмоток, превратив его в биполярный, тогда можно будет используя драйвер A4988 получить и большее деление шага.
Деление шагов обеспечивает не двигатель, его обеспечивает драйвер им управляющий.
A4988 деление шага обеспечивает, но для управления им Stepper не подходит.
Если Вам интересно, Optron, почитайте лучше это :wink:

1 лайк

А вот здесь написно, что можно. Там и диаграмма есть, но она не рабочая.

А мой скетч в #62 работает. И скетч в #61 тоже работает.

Я подаю на драйвер 4096 импульсов. В обычном режиме двигатель делает два оборота (почти два), в полушаговом - один оборот, мощность при этом выше.

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

Вот здесь тоже написано о полушаговом режиме. И правильная диаграмма.

1 лайк

Вопросы шагов второстепенны в контексте библиотек. Вот когда делал рисовалку на этих же моторах, без библиотек, заметил, что не хватает им функций типа: моторы(1_50шагов, 2_-30шагов, 200мс); - т.е. синхронного движения на заданном отрезке времени. Или иными словами движения с разными скоростями заданное время.

Поэтому ЧПУ станки умеющие в интерполяцию не делают на ардуинах

А как же тогда, 3D-принтеры на ATmega2560 работают? :wink:

А где ты там увидел интерполяцию ?
Там нет одновременных перемещений.
Движение по диагонали там представлено в G-кодах, как шаг по Х, шаг по У.

А пример одновременных перемещений можно?

Это сильно зависит от управляющей программы. Одним G-кодом можно отправить по диагонали. Но команды на моторы конечно же будут разнесены по времени.

В каких из широко используемых проектов (Marlin, Ramps, Klipper) есть реализация интерполяции ?

Взять хотя бы представление движения по дуге как множество коротких прямых перемещений … Что же это как не интерполяция?

Я выше привел пример круговой интерполяции.
Размерность примера , одна строка.
Для приведения этого кода к пониманию его Ардуино, его нужно во внешней программе привести к отдельным перемещениям, в результате код увеличится до нескольких сотен строк.
Но это половина беды. При выполнении этого кода на фрезерном станке под управлением той же марлин или рампс, все эти короткие перемещения будут видны на поверхности детали.
Что бы этого не было, система должна двигать инструмент с заданной скоростью по всем осям, участвующим в интерполяции, одновременно.