Держите мотор в движении

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

На данный момент шаговый двигатель движется, только если кнопка постоянно нажата.

//Константы не изменятся. Они используются здесь для установки номеров контактов:
const int buttonPin = 4;     // номер вывода кнопки
const int ledPin =  13;      // номер вывода светодиода
const int dirPin = 8;        // номер вывода направления двигателя
const int stepPin = 9;         // номер штифта шагового двигателя

//Переменные изменятся:
boolean flag = true;
int buttonState = 0;         // переменная для чтения статуса кнопки
int distance = 0;   

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(dirPin, OUTPUT);  //ЖЕЛТЫЙ
  pinMode(stepPin, OUTPUT); //АПЕЛЬСИН

  digitalWrite(buttonPin, LOW);
  digitalWrite(dirPin, HIGH);
  digitalWrite(stepPin, HIGH);
}

void loop() {
  buttonState = digitalRead(buttonPin); // Читаем состояние кнопки

  if (digitalRead(buttonPin) == LOW) {  // Если кнопка нажата, состояние кнопки будет HIGH:
    digitalWrite(ledPin, HIGH);
    digitalWrite(dirPin, LOW);          // НИЗКИЙ = НАПРАВЛЕНИЕ ВПЕРЕД
    digitalWrite(stepPin, HIGH);        // stepPin = ДВИГАТЕЛЬ ВКЛ/ВЫКЛ
    delayMicroseconds(100);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(100);
    distance++;
    if(distance > 21000){
      distance = 0;
      delay (3000);
      reverse();
    }
  } 

  if (digitalRead(buttonPin) == HIGH){ // выключаем светодиод:
    digitalWrite(ledPin, LOW);
    digitalWrite(dirPin, LOW);  //НИЗКИЙ = НАПРАВЛЕНИЕ ВПЕРЕД
    digitalWrite(stepPin, LOW); //stepPin = ДВИГАТЕЛЬ ВКЛ/ВЫКЛ
    delayMicroseconds(100);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(100);
  }
}

void reverse() {
  digitalWrite(dirPin,HIGH); //ВЫСОКИЙ = ОБРАТНОЕ НАПРАВЛЕНИЕ
  digitalWrite(stepPin,HIGH);
  delayMicroseconds(100);
  digitalWrite(stepPin,LOW);
  delayMicroseconds(100);
  distance++;
    if(distance > 21000){
      distance = 0;
      delay(3000);
      return;
    }
  reverse();   
}

, 👍-1

Обсуждение

1.) Отформатируйте код. Код, выровненный по левому краю, плохо читается. Он должен иметь правильный отступ. Это также облегчит вам выявление проблем. 2.) Используйте переменные для именования выводов, например, вывод 8 и 9. Вы уже сделали это для выводов 4 и 13. Почему не для 8 и 9? С именами людям не нужно помнить, какое число имеет какое назначение, @Thomas Weller

3.) если вы хотите два разных действия при нажатии кнопки, то вам нужно вести учет текущего состояния. Таким образом, вам понадобится переменная, например bool isMoving=true, и переключайте ее при каждом нажатии кнопки., @Thomas Weller


2 ответа


1

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

Он должен перестать двигаться только в том случае, если я снова нажму кнопку ... [на данный момент] шаговый двигатель движется, только если кнопка постоянно нажата.

Итак, вам нужно сохранить состояние вашего мотора (ДВИЖЕТСЯ, ОСТАНОВЛЕН и т. д.) и основывать свой код на этом состоянии.

Вам также потребуется устранить дребезг коммутатора.

Ваш цикл должен:

  • Читать & убрать дребезг переключателя
  • Обновить состояние на основе переключателя.
  • Запуск степпера в зависимости от состояния

псевдокод:

// подключаем библиотеки и т.д.
#include <Stepper.h> 

// устанавливаем контакты кнопок и т. д.
int button = <pin>;
Stepper = step(...); // контакты и т. д.

void setup()
{
   // выполняем настройку...
}

enum MOTORSTATES {
  STOPPED = 1,
  FORWARD = 2,
}

MOTORSTATES state = STOPPED;

// вперед объявить свои функции
bool isPressedDebounce(int pin);
void doStep(Stepper&, MOTORSTATES);
MOTORSTATES changeState(MOTORSTATES);

// цикл теперь простой
void loop()
{
  if(isPressedDebounce(button))
    state = changeState(state);

  doStep(step, state);
}

// потому что мы разбили нашу проблему на части
bool isPressedDebounce(int pin)
{
  // обрабатываем и устраняем дребезг коммутатора
  // реализация оставлена читателю в качестве упражнения
}

void doStep(Stepper& step, MOTORSTATES state)
{
  // в зависимости от состояния перемещаем степпер
  // реализация оставлена читателю в качестве упражнения
  switch(state)
  {
    case STOPPED:
      // СДЕЛАЙ ЭТО
      break;
    case FORWARD:
      // СДЕЛАЙ ЭТО
      break;
  }
}

MOTORSTATES changeState(MOTORSTATES state)
{
  // NB Я использовал этот шаблон, потому что это начало конечного автомата!
  switch(state)
  {
    case STOPPED:
      return FORWARD;
      break;
    case FORWARD:
      return STOPPED;
      break;
  }
}

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

,

0

Есть две проблемы:

  1. Вам СЛЕДУЕТ подтягивать или опускать входной контакт при использовании кнопки.
  2. Вы должны обнаружить события "нажать" и "отпустить".

Две описанные выше проблемы упоминаются в этом руководстве

,