Arduino UNO + шаговый двигатель

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

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

#include <AccelStepper.h>


const byte btnPin =/*пин*/A0;
bool btn;


AccelStepper Stepper1(1,13,12); //использует пин 12 и 13 для dir и step, 1 - режим "external driver" (A4988)



void setup() {
pinMode(btnPin, INPUT_PULLUP);
Stepper1.setMaxSpeed(3000); //устанавливаем максимальную скорость вращения ротора двигателя (шагов/секунду)

Stepper1.setAcceleration(13000); //устанавливаем ускорение (шагов/секунду^2)

}

  void loop() {
 pinMode(btnPin, INPUT_PULLUP);
 btn = digitalRead(btnPin);

if (!btn) 
{
   Stepper1.move(1600); 
   
   Stepper1.run(); //запуск шагового двигателя. Эта строка повторяется вновь и вновь для непрерывного вращения двигателя
  }

  }

 

vvadim
Offline
Зарегистрирован: 23.05.2012

пока не научитесь ПРАВИЛЬНО работать с тактовой кнопкой - дальше двигаться не имеет смысла.

http://arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshch-novichku

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

какая проблема в этом примере?

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

я пробовал двигатель включается. и все мне сейчас чтобы работало и все

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Scratch_nl пишет:

какая проблема в этом примере?

отсутсвие базового минимума у вас. Поэтому и объяснять бесполезно.

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

qwone пишет:

Scratch_nl пишет:

какая проблема в этом примере?

отсутсвие базового минимума у вас. Поэтому и объяснять бесполезно.

да ну

vvadim
Offline
Зарегистрирован: 23.05.2012

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

у вас не правильно обрабатывается кнопка, нет защиты от дребезга.

 

 

Scratch_nl
Offline
Зарегистрирован: 15.10.2018
"У вас не правильно обрабатывается кнопка, имеется защиты от дребезга".
мне этого не нужно. мне нужно чтобы двигатель сделал шаги и как это проверить и чтобы остановился
qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Scratch_nl пишет:
да ну
Ну да. 

конечный автомат Ищите в гугле

https://tproger.ru/translations/finite-state-machines-theory-and-impleme...

Пока не осознаете это . То дальше будут сплошные овраги.

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

Вам не нужна защиты от дребезга, а двигателю нужна. Шагать-то ему.

b707
Offline
Зарегистрирован: 26.05.2017

Scratch_nl пишет:

я пробовал двигатель включается. и все мне сейчас чтобы работало и все

ну то есть все работает, как надо? тогда в чем вопрос?

 

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

самостоятельная остановка двигателя

vvadim
Offline
Зарегистрирован: 23.05.2012

Scratch_nl пишет:

"У вас не правильно обрабатывается кнопка, имеется защиты от дребезга".
мне этого не нужно. мне нужно чтобы двигатель сделал шаги и как это проверить и чтобы остановился

если вам этого не нужно, так здесь никому не нужно тем более))))

b707
Offline
Зарегистрирован: 26.05.2017

Scratch_nl пишет:

самостоятельная остановка двигателя

И что?

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

Мы тут должны ха вас не только код ваш дописывать, но и сами додумывать, что этот код должен делать?

Scratch_nl
Offline
Зарегистрирован: 15.10.2018
bool stepLeft = true; // допустим так обзовем наш флаг
......
void loop(){
  ...
  if(x>0 && x<299){
      if(stepLeft){
        myStepper.setSpeed(1);
        myStepper.step(10);
        stepLeft=false;
      }
  }else{
      stepLeft=true;
  }
...
}

через флаг будет работать

vvadim
Offline
Зарегистрирован: 23.05.2012

Scratch_nl пишет:


через флаг будет работать

это вопрос или утверждение ?

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

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

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

vvadim пишет:

Scratch_nl пишет:


через флаг будет работать

это вопрос или утверждение ?

это вопрос

b707
Offline
Зарегистрирован: 26.05.2017

Scratch_nl пишет:

через флаг будет работать

это вопрос? :)

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

 

Забавный сегодня вечер. Сначала упертый подросток пришел с светодиодами и вызвал флейм на 150 страниц, теперь вот вы... Заканчивайте тупить и либо ясно пишите, что вам надо, либо не отнимайте время.

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

Если он вам должен, то забейте ему стрелу. Угрожайте, пытайте током. 

Работать через флаг - решение правильное. +антидребезг. Все подсказки даны. И всё.

vvadim
Offline
Зарегистрирован: 23.05.2012

Scratch_nl пишет:

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

вы научились работать с кнопкой,?

покажите код, где вы кнопкой правильно вкл и выкл светодиод.

когда научитесь - начинайте разбираться с шаговиком.

Scratch_nl
Offline
Зарегистрирован: 15.10.2018
int flag=0; 

 void setup()   
 { 
      
    pinMode(13, OUTPUT);        
            
 } 

 void loop() 

 { 
       
     if(digitalRead(3)==HIGH&&flag==0)  
     
     { 
                  
       flag=1; 
              
     } 
       
      if(digitalRead(3)==LOW&&flag==1)
      
     { 
         digitalWrite(13,!digitalRead(13)); 
        flag=0;
     } 
 } 

 

vvadim пишет:

Scratch_nl пишет:

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

вы научились работать с кнопкой,?

покажите код, где вы кнопкой правильно вкл и выкл светодиод.

когда научитесь - начинайте разбираться с шаговиком.

vvadim
Offline
Зарегистрирован: 23.05.2012

sadman41 пишет:

 +антидребезг.

b707
Offline
Зарегистрирован: 26.05.2017

Значит так, обьясняю и ухожу.

Ваша проблема в том, что вы проверяете кнопку при каждом обращении к loop. Микроконтроллер - вещь относительно быстрая, пока вы нажимаете на кнопку, loop успевает выполнится тысячи раз. И каждый раз - смотрите в свой код - ваш мотор делает 1600 шагов. Это понятно?

Решение -  вам надо запоминать состояние кнопки и реагировать на одно нажатие ТОЛЬКО один раз. А потом нажатую кнопку игнорировать, пока ее не отожмут.

Но тут есть проблема - в момент, когда вы нажимаете кнопку, она замыкается не сразу - сначала происходит "дребезг" - контакт то есть, то нет - и так десятки раз. То же самое при отпускании кнопки. Для вашего же кода это недопустимо - иначе вы опять будете выполнять свои 1600 шагов мотором по многу раз.

Вывод - антидребезг вам абсолютно необходим.

strarbit
Offline
Зарегистрирован: 12.06.2016

see an example in arduino IDE Examples - Digital - Debounce

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

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

vvadim
Offline
Зарегистрирован: 23.05.2012

никто на вас не нападал.

вам только подсказали в каком направлении двигаться и с чего начать.

vvadim
Offline
Зарегистрирован: 23.05.2012

кстати, большинство здесь с этого и начинали.

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

b707 пишет:

Scratch_nl пишет:

через флаг будет работать

это вопрос? :)

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

 

Забавный сегодня вечер. Сначала упертый подросток пришел с светодиодами и вызвал флейм на 150 страниц, теперь вот вы... Заканчивайте тупить и либо ясно пишите, что вам надо, либо не отнимайте время.

он напал

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Scratch_nl пишет:

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

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

vvadim
Offline
Зарегистрирован: 23.05.2012

бляя, он же вам целую лекцию написал про дребезг, а вы его в нападатели записали.

если не верите - погуглите этот вопрос....

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

да, правда взялся за сложное. попробую с светодиодом

Scratch_nl
Offline
Зарегистрирован: 15.10.2018
/**/
unsigned long mill;
unsigned long mill2;
//--------------------------------------
const byte btnPin =/*пин*/A0;
bool btn;
const byte ledPin =/*пин*/3;
bool Led;
const byte ledPin1 =/*пин*/5;
bool Led1;
unsigned long past;
unsigned long past2;
const unsigned long time1sec = 2000;
const unsigned long time2sec = 2000;
unsigned long eventTime=0;

//-----------main()---------------------------
void setup() {
  pinMode(btnPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin1, OUTPUT);
  digitalWrite(ledPin, Led = 1);
  digitalWrite(ledPin1, Led1 = 0);
}
void loop() {
  mill = millis();
  mill2 = millis();
  btn = digitalRead(btnPin);
  if (!btn) { /* если кнопка нажата*/
    digitalWrite(ledPin, Led = 0); /*то вкл светодиод*/
    past = mill;
    }
  if (Led1 & mill - past >= time1sec) {/*если светодиод горит больше 1 сек*/
    digitalWrite(ledPin, Led = 1);/*то выкл*/
  past = mill;
  }
   
  //-----------------------------------------------------------
 
  if(!btn) eventTime=millis(); // засекли когда произошло событие

  if(eventTime && (millis()-eventTime>2000)) // проверям прошло ли XXXX миллесекунд с события
  { 
  digitalWrite(ledPin1, Led1 = 1); /*то вкл светодиод*/
    past2 = mill2;
    eventTime=0;
  }
  if (Led1 & mill2 - past2 >= time2sec) {/*если светодиод горит больше 1 сек*/
    digitalWrite(ledPin1, Led1 = 0);/*то выкл*/
    past2 = mill2;
    eventTime=0;
  }
}

есть такой код, переделанный из двух других

if(!btn) eventTime=millis(); // засекли когда произошло событие

  if(eventTime && (millis()-eventTime>2000)) // проверям прошло ли XXXX миллесекунд с события
  { 
  
  }
}

в эту часть думаю поместить мотор

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Scratch_nl пишет:

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

А кому щас легко?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ну еще одна жертва мифа о кухарко-ориентированности Ардуино. 

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

#include <AccelStepper.h>

AccelStepper Stepper1(1,13,12); 

int dir = 1; 
int flag=0;

void setup() {

Stepper1.setMaxSpeed(3000); 

Stepper1.setAcceleration(13000); 

}

void loop() {
while (flag == 0)
{
if(Stepper1.distanceToGo()==0){ 

Stepper1.move(1600); 



delay(1000); 
flag = 1;

}
 if (flag = 1)
 { 
Stepper1.stop();
}
}
b707
Offline
Зарегистрирован: 26.05.2017

что это?

зачем тут while?

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

void loop() {
if (flag == 0)
{  Stepper1.move(1600); 
   delay(1000); 
   flag = 1;
   Stepper1.stop();
}
}

 

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

то но, не получилось запустить, буду дальше пробовать

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Scratch_nl пишет:

то но, не получилось запустить, буду дальше пробовать

И что сейчас мы видим. Вот где лежит библиотека для ознакомления. https://github.com/waspinator/AccelStepper/blob/master/src/AccelStepper.h

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

http://hobbytech.com.ua/arduino-%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%...

ПС: не наблюдаю в программе метод run()  или runSpeed()

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

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

#include <AccelStepper.h>
AccelStepper Stepper1(1,13,12); 

     unsigned long mill;
     const byte btnPin = A0;
     bool btn;
     const byte relePin = 5;
     bool Myrele;
     unsigned long past;
     const unsigned long time1sec = 3000;
     unsigned long eventTime=0;

void setup() {
  
      Stepper1.setMaxSpeed(3000); 
      Stepper1.setAcceleration(1300);
      
      pinMode(btnPin, INPUT_PULLUP);
      pinMode(relePin, OUTPUT);
      digitalWrite(relePin, Myrele = 0);
      
}

void loop() {
  
       mill = millis();
        btn = digitalRead(btnPin);
        
        if (!btn) { /* если кнопка нажата*/
       
        digitalWrite(relePin, Myrele = 1); /*то вкл реле*/
        past = mill;
   }
      if (Myrele & mill - past >= time1sec) {/*если реле вкл больше 1 сек*/
       digitalWrite(relePin, Myrele = 0);/*то выкл*/
       past = mill;
   }

      if(!btn) eventTime=millis(); // засекли когда произошло событие
 
      if(eventTime && (millis()-eventTime>2000)) // проверям прошло ли XXXX миллесекунд с события
  { 
     Stepper1.runSpeed();
     Stepper1.moveTo(100);
     
     while(Stepper1.currentPosition() != 100)
     Stepper1.run();
  }
}

  

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Видите как организован обработчик кнопки. Вот и сделайте его правильно

if (! bounce && btn != digitalRead(pin)) { // если прошел фронт изм на выводн
        bounce = 1;                              // выставить флаг
        past = millis();                         // сделать временую засветку
      }
      else if ( bounce && millis() - past >= 5 ) { // если прошло антидребезговое время
        bounce = 0;                                // то снять флаг
        btn_old = btn ;
        btn = digitalRead(pin) ;                   // прочитать реальное значение на выводе
        if (btn_old && ! btn) Do();
      }

Отсюда. #4

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

qwone пишет:

Видите как организован обработчик кнопки. Вот и сделайте его правильно

if (! bounce && btn != digitalRead(pin)) { // если прошел фронт изм на выводн
        bounce = 1;                              // выставить флаг
        past = millis();                         // сделать временую засветку
      }
      else if ( bounce && millis() - past >= 5 ) { // если прошло антидребезговое время
        bounce = 0;                                // то снять флаг
        btn_old = btn ;
        btn = digitalRead(pin) ;                   // прочитать реальное значение на выводе
        if (btn_old && ! btn) Do();
      }

Отсюда. #4

и что это?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

А ссылку вы видели?? Или нормальные герои{херои} всегда идут о обход {поступают как велит им собственая жопа}

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

Так видел, хорошая лекция

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

ПС:

    /// The currently motor position.
    /// \return the current motor position
    /// in steps. Positive is clockwise from the 0 position.
    long    currentPosition();  
Перевод.
   // / Текущее положение двигателя.
    // / \ вернуть текущее положение двигателя
    // / в шагах. Положительно по часовой стрелке от позиции 0.

Зачем ШД куда-то двигаться если он уже стоит в текущей позиции

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

Значит нужно обнулить эту позицию, чтобы произошла следующая. Так или нет

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Scratch_nl пишет:

Значит нужно обнулить эту позицию, чтобы произошла следующая. Так или нет

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

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

qwone пишет:

Scratch_nl пишет:

Значит нужно обнулить эту позицию, чтобы произошла следующая. Так или нет

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

Stepper1.setCurrentPosition();
    Stepper1.runToNewPosition();

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Данунах. Хоть уже суббота я еще в пятнице. Казус решаемый бритвой Оккамы. Режте код и пишите свои программы на уровне железа. Не пользуйтесь чужими подпрограммами и классами пока они не станут Вашими. Посмотрите "библиотеку" (хреновое слово), в шаговых движках все просто - подаем напряжение на 1 обмотку., потом на 2 и т.д... закончились обмотки - опять на 1. А тупо используя чужие классы Вы понижаете себе карму :)

Scratch_nl
Offline
Зарегистрирован: 15.10.2018

mykaida пишет:

Данунах. Хоть уже суббота я еще в пятнице. Казус решаемый бритвой Оккамы. Режте код и пишите свои программы на уровне железа. Не пользуйтесь чужими подпрограммами и классами пока они не станут Вашими. Посмотрите "библиотеку" (хреновое слово), в шаговых движках все просто - подаем напряжение на 1 обмотку., потом на 2 и т.д... закончились обмотки - опять на 1. А тупо используя чужие классы Вы понижаете себе карму :)

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

vvadim
Offline
Зарегистрирован: 23.05.2012

ты уже на разных форумах создал сто тем со своим мотором и упорно не хочешь разобраться со своей кнопкой. она у тебя не правильно работает.

чувак точно как на картинке выше)))))