Управление шаговым мотором

Lavrentii
Offline
Зарегистрирован: 03.11.2013

Приветствую.

Решил сделать управление крышкой бардачка с помощью моторо шагового NEMA17. Используя Arduino NANO, драйвер A4988, кнопку.

Суть такова. при нажатии на кнопку (фиксируемая) на вход A0 посупает 5 вольт и мотор должен крутится на определенное количество шагов влево. При пропадании сигнала с А0 мотор должен крутится вправо.

У меня же мотор крутится всегда вправо не зависимо от того что на входе A0.

Вот скетч, который сделал

#include <Arduino.h> 
#include <AccelStepper.h> 

#define RPM_1 97400 
#define ACC_1 97400 

#define M0 0 

AccelStepper *mtr[1]; 
const double rel[1] = {66.6666}; 
const byte mtrPins[5][3] = {{5,4}}; // step, dir 
const byte mtrEnPin = 6; //enb
byte trigger = 0;
 
void setup() { 
  
Serial.begin(9600);
 
mtr[M0] = new AccelStepper(AccelStepper::DRIVER, mtrPins[M0][0], mtrPins[M0][1]); 

pinMode(mtrEnPin, OUTPUT); 
pinMode(A0, INPUT); 
pinMode(13, OUTPUT); 

mtr[M0]->setMaxSpeed(RPM_1); 
mtr[M0]->setAcceleration(ACC_1); 

digitalWrite(mtrEnPin, LOW); 

delay(1000); 
} 

void loop() { 
int v = digitalRead(A0); 
if( v ){ 
digitalWrite(13, HIGH); 
} else { 
digitalWrite(13, LOW); 
} 
if( !trigger && v ){ 
mtr[0]->move(19000); 
trigger = 1; 
} 
if( trigger && !v ){ 
mtr[0]->move(-19000); 
trigger = 0; 
} 
mtr[0]->run(); 
}

Если загрузить пример с интернета то мотор крутится и влево и вправо. При том рукой его не остановить, как в моем примере.

int Index;

void setup() 
{
  pinMode(6, OUTPUT); //Enable
  pinMode(5, OUTPUT); //Step
  pinMode(4, OUTPUT); //Direction

  digitalWrite(6,LOW);
}

void loop() 
{
  digitalWrite(4,HIGH);

  for(Index = 0; Index < 2000; Index++)
  {
    digitalWrite(5,HIGH);
    delayMicroseconds(500);
    digitalWrite(5,LOW);
    delayMicroseconds(500);
  }
  delay(1000);

  digitalWrite(4,LOW);

  for(Index = 0; Index < 2000; Index++)
  {
    digitalWrite(5,HIGH);
    delayMicroseconds(500);
    digitalWrite(5,LOW);
    delayMicroseconds(500);
  }
  delay(1000);
}

Подскажите пожалуйста что не так проиходит ?

Nosferatu
Offline
Зарегистрирован: 04.11.2012

Разбираться с библиотекой лень, но поверхностно взглянув не увидел, где вы переключаете пин DIR, который отвечает за направление движения.

nik182
Offline
Зарегистрирован: 04.05.2015

Не уверен что в 34 строке можно получить ноль.

b707
Онлайн
Зарегистрирован: 26.05.2017

а зачем этот бред в строке 11 - массив 5Х3, если в итоге нужны только два одиночных байта?

Кроме того, если у вас есть готовый и довольно простой код, который крутит моторы как надо (скетч 2) - зачем вам в вашем коде какая-то левая библиотека? Вставьте код для моторов из второго скетча в первый.

Lavrentii
Offline
Зарегистрирован: 03.11.2013

Не совсем понимаю, что в 11 строке не так.
Скетчи пытался соединить, не получилось

Lavrentii
Offline
Зарегистрирован: 03.11.2013

С 40 цикл, который должен это делать

b707
Онлайн
Зарегистрирован: 26.05.2017

Lavrentii пишет:
Не совсем понимаю, что в 11 строке не так. Скетчи пытался соединить, не получилось

вы вообще язык хорошо знаете? Что означает запись

const byte mtrPins[5][3] = {{5,4}};

Это массив из 5 строк по 3 элемента в каждом, то есть

const byte mtrPins[5][3] = {{5,4,0},
                            {0,0,0},
                             {0,0,0},
                             {0,0,0},
                             {0,0,0},
                                       };

Зачем он нужен, если потом вы используете из него только 2 первых элемента, вызывая их как mtrPins[0][0] и mtrPins[0][1] - то есть как два константных байта?

Lavrentii
Offline
Зарегистрирован: 03.11.2013

b707 пишет:

Lavrentii пишет:
Не совсем понимаю, что в 11 строке не так. Скетчи пытался соединить, не получилось

вы вообще язык хорошо знаете? Что означает запись

const byte mtrPins[5][3] = {{5,4}};

Это массив из 5 строк по 3 элемента в каждом, то есть

const byte mtrPins[5][3] = {{5,4,0},
                            {0,0,0},
                             {0,0,0},
                             {0,0,0},
                             {0,0,0},
                                       };

Зачем он нужен, если потом вы используете из него только 2 первых элемента, вызывая их как mtrPins[0][0] и mtrPins[0][1] - то есть как два константных байта?


Тут обозначают пины к которым драйвер подключения. Из библиотеки пример был взял.
Можете подсказать как правильно сделать, чтоб работало по заданным условиям

b707
Онлайн
Зарегистрирован: 26.05.2017

Lavrentii пишет:

Можете подсказать как правильно сделать, чтоб работало по заданным условиям

Попробуйте библиотеку AccelStepper выкинуть вовсе, вместо строки 41 подставить строки с 14 по 22 второго скетча, а вместо строки 45 - соответсвенно строки 25-33 .

Сделаете - покажите код. И не забудьте пины описать правильно в сетап

Lavrentii
Offline
Зарегистрирован: 03.11.2013

Каша получится мне кажется. Но попробую

Lavrentii
Offline
Зарегистрирован: 03.11.2013

b707 пишет:

Lavrentii пишет:

Можете подсказать как правильно сделать, чтоб работало по заданным условиям

Попробуйте библиотеку AccelStepper выкинуть вовсе, вместо строки 41 подставить строки с 14 по 22 второго скетча, а вместо строки 45 - соответсвенно строки 25-33 .

Сделаете - покажите код. И не забудьте пины описать правильно в сетап

Сделал но сыпется ошибка по скобкам }

#include <Arduino.h> 
int Index;
#define M0 0 

const double rel[1] = {66.6666}; 
const byte mtrPins[5][3] = {{5,4}}; // step, dir 
const byte mtrEnPin = 6; //enb
byte trigger = 0;
 
void setup() { 
  
Serial.begin(9600);
 
pinMode(6, OUTPUT); //Enable
pinMode(5, OUTPUT); //Step
pinMode(4, OUTPUT); //Direction
pinMode(mtrEnPin, OUTPUT); 
pinMode(A0, INPUT); 
pinMode(13, OUTPUT); 

digitalWrite(mtrEnPin, LOW); 

delay(1000); 
} 

void loop() { 
int v = digitalRead(A0); 
if( v ){ 
digitalWrite(13, HIGH); 
} else { 
digitalWrite(13, LOW); 
} 

if( !trigger && v ){ 
digitalWrite(4,HIGH);

for(Index = 0; Index < 2000; Index++)
{
digitalWrite(5,HIGH);
delayMicroseconds(500);
digitalWrite(5,LOW);
delayMicroseconds(500);}

if( trigger && !v ){ 
digitalWrite(4,LOW);

for(Index = 0; Index < 2000; Index++)
{
digitalWrite(5,HIGH);
delayMicroseconds(500);
digitalWrite(5,LOW);
delayMicroseconds(500);
}
delay(1000);
}

 

Lavrentii
Offline
Зарегистрирован: 03.11.2013

Исправил. Но пока на железе не проверял.

#include <Arduino.h> 
int Index;
#define M0 0 
const double rel[1] = {66.6666}; 
const byte mtrPins[5][3] = {{5,4}}; // step, dir 
const byte mtrEnPin = 6; //enb
byte trigger = 0;
void setup() { 
  
Serial.begin(9600);
pinMode(6, OUTPUT); //Enable
pinMode(5, OUTPUT); //Step
pinMode(4, OUTPUT); //Direction
pinMode(mtrEnPin, OUTPUT); 
pinMode(A0, INPUT); 
pinMode(13, OUTPUT); 
digitalWrite(mtrEnPin, LOW); 

delay(1000); 
} 

void loop() { 
int v = digitalRead(A0); 
if( v ){ 
digitalWrite(13, HIGH); 
} else { 
digitalWrite(13, LOW); 
} 

if( !trigger && v ){ 
digitalWrite(4,HIGH);
}
for(Index = 0; Index < 2000; Index++)
{
digitalWrite(5,HIGH);
delayMicroseconds(500);
digitalWrite(5,LOW);
delayMicroseconds(500);}

if( trigger && !v ){ 
digitalWrite(4,LOW);
}
for(Index = 0; Index < 2000; Index++)
{
digitalWrite(5,HIGH);
delayMicroseconds(500);
digitalWrite(5,LOW);
delayMicroseconds(500);
}
delay(1000);
}

 

b707
Онлайн
Зарегистрирован: 26.05.2017

Lavrentii пишет:

Исправил. Но пока на железе не проверял.

Хорошо.

Погодите пока в железо пихать, я вам чуть погодя код немного "причешу". А то сейчас только на работу пришел, надо изобразить деятельность :)

Lavrentii
Offline
Зарегистрирован: 03.11.2013

b707 пишет:

Lavrentii пишет:

Исправил. Но пока на железе не проверял.

Хорошо.

Погодите пока в железо пихать, я вам чуть погодя код немного "причешу". А то сейчас только на работу пришел, надо изобразить деятельность :)

спасибо

sadman41
Offline
Зарегистрирован: 19.10.2016

Вот так не проще (на моторе не смотрел)? 

uint32_t motorDelay = 5;
uint32_t clockwiseSteps = 200;
uint8_t moveClockwise = HIGH;  // moveClockwise with DIR = HIGH

void setup() {

  Serial.begin(9600);
  pinMode(6, OUTPUT); //Enable
  pinMode(5, OUTPUT); //Step
  pinMode(4, OUTPUT); //Direction
  pinMode(A0, INPUT);
  pinMode(13, OUTPUT);
  digitalWrite(6, LOW);

  delay(1000);
}

void loop() {
  uint32_t clockwiseStepsLeft = 0;

  while (true) {
    digitalWrite(5, HIGH);
    //delayMicroseconds(500);
    digitalWrite(5, LOW);
    delay(motorDelay);

    if (digitalRead(A0)) {
      // Change direction for "clockwiseSteps" steps
      clockwiseStepsLeft = clockwiseSteps;
      digitalWrite(4, moveClockwise);
    }

    clockwiseStepsLeft--;

    if (0 <= clockwiseStepsLeft) {
      // Change direction
      digitalWrite(4, !moveClockwise);
    }
  }

}

P.S. Избавление о delay() - домашняя работа для ТС

Lavrentii
Offline
Зарегистрирован: 03.11.2013

sadman41 пишет:

Вот так не проще (на моторе не смотрел)? 

uint32_t motorDelay = 5;
uint32_t clockwiseSteps = 200;
uint8_t moveClockwise = HIGH;  // moveClockwise with DIR = HIGH

void setup() {

  Serial.begin(9600);
  pinMode(6, OUTPUT); //Enable
  pinMode(5, OUTPUT); //Step
  pinMode(4, OUTPUT); //Direction
  pinMode(A0, INPUT);
  pinMode(13, OUTPUT);
  digitalWrite(6, LOW);

  delay(1000);
}

void loop() {
  uint32_t clockwiseStepsLeft = 0;

  while (true) {
    digitalWrite(5, HIGH);
    //delayMicroseconds(500);
    digitalWrite(5, LOW);
    delay(motorDelay);

    if (digitalRead(A0)) {
      // Change direction for "clockwiseSteps" steps
      clockwiseStepsLeft = clockwiseSteps;
      digitalWrite(4, moveClockwise);
    }

    clockwiseStepsLeft--;

    if (0 <= clockwiseStepsLeft) {
      // Change direction
      digitalWrite(4, !moveClockwise);
    }
  }

}

P.S. Избавление о delay() - домашняя работа для ТС


Как тогда задать количество шагов вперед и назад ? Или это кусок

sadman41
Offline
Зарегистрирован: 19.10.2016

Lavrentii пишет:

Суть такова. при нажатии на кнопку (фиксируемая) на вход A0 посупает 5 вольт и мотор должен крутится на определенное количество шагов влево. При пропадании сигнала с А0 мотор должен крутится вправо.

В условии написано - должен крутится влево на N шагов - это задается в начале скетча, при пропадании - вправо. Где написано про K шагов вправо?

b707
Онлайн
Зарегистрирован: 26.05.2017

вот так получилось. Число шагов в каждом направлении - Step_to_move - надо будет подобрать.

#include <Arduino.h> 

const double rel[1] = {66.6666}; 
const byte mtrStepPin = 5; // step
const byte mtrDirPin = 4; // dir 
const byte mtrEnPin = 6; //enb
byte trigger = 0;

int Steps_to_move = 19000;  


void motor_move (byte dir, int steps) {
 int Index;
 digitalWrite(mtrDirPin,dir);
 for(Index = 0; Index < steps; Index++)
  {
   digitalWrite(mtrStepPin,HIGH);
   delayMicroseconds(500);
   digitalWrite(mtrStepPin,LOW);
   delayMicroseconds(500);
  }
}

void setup() { 

Serial.begin(9600);
pinMode(mtrEnPin, OUTPUT); //Enable
pinMode(mtrStepPin, OUTPUT); //Step
pinMode(mtrDirPin, OUTPUT); //Direction
pinMode(A0, INPUT); 
pinMode(13, OUTPUT); 
digitalWrite(mtrEnPin, LOW); 

delay(1000); 
} 

void loop() { 
int v = digitalRead(A0); 
if( v ){ 
 digitalWrite(13, HIGH); 
 } 
else { 
 digitalWrite(13, LOW); 
} 

if( !trigger && v ){ 
  motor_move (HIGH, Steps_to_move);
  trigger = 1;
}
if( trigger && !v ){ 
  motor_move (LOW, Steps_to_move);
  trigger = 0;
}

delay(1000);
}

 

Lavrentii
Offline
Зарегистрирован: 03.11.2013

b707 пишет:

вот так получилось. Число шагов в каждом направлении - Step_to_move - надо будет подобрать.

#include <Arduino.h> 

const double rel[1] = {66.6666}; 
const byte mtrStepPin = 5; // step
const byte mtrDirPin = 4; // dir 
const byte mtrEnPin = 6; //enb
byte trigger = 0;

int Steps_to_move = 19000;  


void motor_move (byte dir, int steps) {
 int Index;
 digitalWrite(mtrDirPin,dir);
 for(Index = 0; Index < steps; Index++)
  {
   digitalWrite(mtrStepPin,HIGH);
   delayMicroseconds(500);
   digitalWrite(mtrStepPin,LOW);
   delayMicroseconds(500);
  }
}

void setup() { 

Serial.begin(9600);
pinMode(mtrEnPin, OUTPUT); //Enable
pinMode(mtrStepPin, OUTPUT); //Step
pinMode(mtrDirPin, OUTPUT); //Direction
pinMode(A0, INPUT); 
pinMode(13, OUTPUT); 
digitalWrite(mtrEnPin, LOW); 

delay(1000); 
} 

void loop() { 
int v = digitalRead(A0); 
if( v ){ 
 digitalWrite(13, HIGH); 
 } 
else { 
 digitalWrite(13, LOW); 
} 

if( !trigger && v ){ 
  motor_move (HIGH, Steps_to_move);
  trigger = 1;
}
if( trigger && !v ){ 
  motor_move (LOW, Steps_to_move);
  trigger = 0;
}

delay(1000);
}

 


Спасибо большое. Вечером в железе попробую

b707
Онлайн
Зарегистрирован: 26.05.2017

забыл сказать - не компилировал, могут быть мелки опечатки. Нет ардуины под рукой сейчас.

и еще - не знаю что за параметр rel[1] - строка 3. На всякий случай оставил, но в скетче он не используется.

Lavrentii
Offline
Зарегистрирован: 03.11.2013

b707 пишет:

забыл сказать - не компилировал, могут быть мелки опечатки. Нет ардуины под рукой сейчас.

и еще - не знаю что за параметр rel[1] - строка 3. На всякий случай оставил, но в скетче он не используется.

Проверил мотор крутится в оду и туже сторону. Может ускорения не хватает ?

b707
Онлайн
Зарегистрирован: 26.05.2017

Lavrentii пишет:

Проверил мотор крутится в оду и туже сторону. Может ускорения не хватает ?

при чем тут ускорение?

Опишите, как вы работаете с кнопкой и как при этом реагирует мотор и светодиод на пине 13

Lavrentii
Offline
Зарегистрирован: 03.11.2013

b707 пишет:

Lavrentii пишет:

Проверил мотор крутится в оду и туже сторону. Может ускорения не хватает ?

при чем тут ускорение?

Опишите, как вы работаете с кнопкой и как при этом реагирует мотор и светодиод на пине 13

кнопка подключена к пину А0. Через нее на пин поступает логическая 1 т.е. 4.8 вольта. Кнопка с фиксацией. 

При нажатии на А0 поступает лог 1 и светодиод на 13 пине загорается. Мотор начинает крутится влево на задонное количество шагов.

При повторном нажатии с пина А0 проподает лог 1, светодиод на пине 13 гаснет и мотор должен крутится вправо на задонное количество шагов. Но этого не происходит.

Схема включения драйвера универсальная,взята с инета

b707
Онлайн
Зарегистрирован: 26.05.2017

Lavrentii пишет:

кнопка подключена к пину А0. Через нее на пин поступает логическая 1 т.е. 4.8 вольта. Кнопка с фиксацией. 

При нажатии на А0 поступает лог 1 и светодиод на 13 пине загорается. Мотор начинает крутится влево на задонное количество шагов.

При повторном нажатии с пина А0 проподает лог 1, светодиод на пине 13 гаснет и мотор должен крутится вправо на задонное количество шагов. Но этого не происходит.

 

не пишите "как должно быть", напишите как оно на самом деле. Типа "нажимаю кнопку - она фиксируется - зажигается светодиод - мотор крутится...

Lavrentii
Offline
Зарегистрирован: 03.11.2013

b707 пишет:

Lavrentii пишет:

кнопка подключена к пину А0. Через нее на пин поступает логическая 1 т.е. 4.8 вольта. Кнопка с фиксацией. 

При нажатии на А0 поступает лог 1 и светодиод на 13 пине загорается. Мотор начинает крутится влево на задонное количество шагов.

При повторном нажатии с пина А0 проподает лог 1, светодиод на пине 13 гаснет и мотор должен крутится вправо на задонное количество шагов. Но этого не происходит.

 

не пишите "как должно быть", напишите как оно на самом деле. Типа "нажимаю кнопку - она фиксируется - зажигается светодиод - мотор крутится...

Все правильно. Нажал кнопку она зафиксировалась. Мотор крутится влево и светодиод горит. Нажал кнопка разомкнула цепь мотор крутится влево светодиод погас

b707
Онлайн
Зарегистрирован: 26.05.2017

теперь загрузите в МК скетч номер 2 из первого сообщения и проверьте - мотор крутится в разные стороны?  Ничего не переподключайте,  все пины в двух скетчах одинаковые

Lavrentii
Offline
Зарегистрирован: 03.11.2013

b707 пишет:

теперь загрузите в МК скетч номер 2 из первого сообщения и проверьте - мотор крутится в разные стороны?  Ничего не переподключайте,  все пины в двух скетчах одинаковые

с тестовым скетчем из первого поста мотор крутится вперед и назад. Рукой его не остановить. 

Сейчас управляя с кнопки мотор идет только в одну сторону и рукой можно остановить мотор

b707
Онлайн
Зарегистрирован: 26.05.2017

Lavrentii пишет:

с тестовым скетчем из первого поста мотор крутится вперед и назад. Рукой его не остановить. 

Сейчас управляя с кнопки мотор идет только в одну сторону и рукой можно остановить мотор

вы точно пробуете один и тот же мотор на одной и той же плате?

просто того, что вы пишете выше - не может быть, код управления мотором абсолютно одинаков.

Lavrentii
Offline
Зарегистрирован: 03.11.2013

b707 пишет:

Lavrentii пишет:

с тестовым скетчем из первого поста мотор крутится вперед и назад. Рукой его не остановить. 

Сейчас управляя с кнопки мотор идет только в одну сторону и рукой можно остановить мотор

вы точно пробуете один и тот же мотор на одной и той же плате?

просто того, что вы пишете выше - не может быть, код управления мотором абсолютно одинаков.

Все спаяно уже на постояннку. Мотор и ардуина та же. Драйвер тот же. Почему так сам не понимаю

 

sadman41
Offline
Зарегистрирован: 19.10.2016

b707 пишет:

вы точно пробуете один и тот же мотор на одной и той же плате?

просто того, что вы пишете выше - не может быть, код управления мотором абсолютно одинаков.

Да вставьте ему уже в начало лупа того скетча, что работает, while(LOW==digitalRead(A0)) {;} и что-то подобное перед степом возврата. Это же бесконечно будет - работает/не работает/не нравится. 

b707
Онлайн
Зарегистрирован: 26.05.2017

sadman41 пишет:

Да вставьте ему уже в начало лупа того скетча, что работает, while(LOW==digitalRead(A0)) {;}

вставляй ты - твоя очередь :)

Мне почему-то кажется, что у меня результат будет тем же, что и сейчас.

Ради интереса - можешь попробовать найти ошибку в моем скетче, может и правда что-то проглядел. Я не вижу разницы в моем коде работы с мотором и в том, что, по отзывам ТС. работает

sadman41
Offline
Зарегистрирован: 19.10.2016

Да у меня уже есть такой товарищ, мне хватает ;) Два вечера дистанционно ошибку в коде искали, а оказалось что провод не контачит и мотор токо вибрирует, но не крутит.

Lavrentii
Offline
Зарегистрирован: 03.11.2013

сижу пробую. пока ни как 

 

Lavrentii
Offline
Зарегистрирован: 03.11.2013

Мотор перестал менять напровление вообще. теперь только в одну сторону идет

sadman41
Offline
Зарегистрирован: 19.10.2016

Не надо сидеть, надо думать и пытаться понять, как драйвер работает. Берете мультиметр и смотрите, что на входе DIR происходит...

Lavrentii
Offline
Зарегистрирован: 03.11.2013

sadman41 пишет:

Не надо сидеть, надо думать и пытаться понять, как драйвер работает. Берете мультиметр и смотрите, что на входе DIR происходит...


4.8 вольта. Светодиод горит. 0 вольт светодиод погас. Мотор постоянно влево.
Драйвер менял

sadman41
Offline
Зарегистрирован: 19.10.2016

Проверяйте правильность подключения обмоток. Если на драйвере есть степ и меняется дир - скетч уже непричем.

Lavrentii
Offline
Зарегистрирован: 03.11.2013

Всем спасибо. Заменил мотор и все заработало