Как заставить двигатели постоянного тока работать одновременно?

Я кодирую моторный щит adafruit для 3 двигателей постоянного тока, чтобы двигаться вперед и назад, и поэтому меня беспокоит, почему все время работает только мой мотор3, а двигатели 1 и 2 выключаются, что означает, что 1 идет, а 2 идет и продолжается и продолжается? Мой код приведен ниже, если вы видите, где моя ошибка в коде, можете ли вы просто сказать мне, что это такое и что нужно сделать, чтобы они запускались одновременно?

#include <AFMotor.h>
AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
AF_DCMotor motor(3);

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Motor test!");
  // turn on motor
  motor1.setSpeed(300);
  motor2.setSpeed(200);
  motor.setSpeed(500);
  motor.run(RELEASE);
}

void loop() {
  uint8_t i;

  //third motor
  Serial.print("tick");
  motor.run(FORWARD);
  for (i=0; i<255; i++) {
    motor2.setSpeed(i);  
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);  
    delay(10);
  }

  //second motor
  Serial.print("tick");
  motor2.run(FORWARD);
  for (i=0; i<255; i++) {
    motor2.setSpeed(i);  
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);  
    delay(10);
  }
  Serial.print("tack");
  motor2.run(BACKWARD);
  for (i=0; i<255; i++) {
    motor2.setSpeed(i);  
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);  
    delay(10);
  }

  Serial.print("tick");
  motor1.run(FORWARD);
  for (i=0; i<255; i++) {
    motor1.setSpeed(i);  
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor1.setSpeed(i);  
    delay(10);
  }
  Serial.print("tack");
  motor1.run(BACKWARD);
  for (i=0; i<255; i++) {
    motor1.setSpeed(i);  
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor1.setSpeed(i);  
    delay(10);
  }
}

, 👍0

Обсуждение

ну, я еще не запустил его, потому что не знаю, что добавить в свой код, чтобы двигатели работали в течение определенного времени!, @user64079

Мой вопрос в том, как бы я заставил свои двигатели работать определенным образом в течение определенного периода времени? Например, мотор движется вперед на 2 секунды!!!, @user64079

@jstola Я сделал то, что вы сказали сделать, и начал с одного двигателя, идущего в одном направлении, чем закончил этот двигатель, а затем сделал два других двигателя. И все работает отлично, за исключением того, что только двигатель 3 работает все время, а для двигателя 1 и 2 они выключаются, что означает, что 1 выполняет свои запуски s, чем 2, как мне сделать так, чтобы все они работали одновременно\?, @user64079

ссылаясь на скетч выше ... движутся ли двигатели так, как вы хотите? ... прямо сейчас им требуется 2 1/2 секунды, чтобы увеличить скорость, и 2 1/2 секунды, чтобы уменьшить скорость, чтобы остановиться ... вы пробовали большие приращения между шагами?, @jsotola


3 ответа


1

Самый простой подход для включения задержки в ваш скетч-это вызвать функцию Arduino delay (). Передайте этой функции значение задержки в миллисекундах. Например, задержка в 1 секунду составляет 1000 миллисекунд.

Каким бы простым ни был этот метод, он не рекомендуется, если ваш скетч требуется для выполнения задач во время задержки. Это распространенное требование, которое расстраивает многих новых программистов.

Для выполнения задач во время ожидания в течение произвольного периода времени не используйте функцию Arduino delay (). Вместо этого используйте функцию Arudino millis (). Функция millis() вернет количество миллисекунд, прошедших с момента запуска текущей программы на плате Arduino. Запишите это число, выполните желаемое действие, затем введите бесконечный цикл, пока функция millis() не вернет число, указывающее на то, что прошло желаемое количество секунд. Находясь в бесконечном цикле, программа может выполнять другие задачи до тех пор, пока они занимают небольшое количество времени относительно желаемой задержки. Например, проверка на замыкание выключателя и включение светодиода.

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

,

1

То, что вы ищете, называется "неблокирующее программирование", метод, при котором вы часто проверяете или оцениваете, нужно ли что-то делать, и либо делаете это, либо нет, но немедленно двигаетесь дальше. Для одного двигателя вы можете успешно заблокировать (больше ничего не делать, пока вы ждете, пока что-то произойдет): запуск/ожидание/остановка/обратный ход/ожидание/остановка/... и т. Д.

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

В этой статье более подробно описано, как это сделать (полное раскрытие: это один из моих).

,

1

Начните с примера кода BlinkWithoutDelay и внесите изменения в соответствии с вашими потребностями.

Это исходный код.

    /*
  Мигание без промедления

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

  Схема:
  - Используйте встроенный светодиод.
  - Примечание: У большинства ардуино есть встроенный светодиод, которым вы можете управлять. В UNO, МЕГА
    и НОЛЬ он прикреплен к цифровому контакту 13, на MKR1000 на выводе 6. LED_BUILDIN
    устанавливается на правильный вывод светодиода, независимо от того, какая плата используется.
    Если вы хотите знать, к какому контакту подключен встроенный светодиод на вашем
    Модель Arduino, проверьте технические характеристики вашей платы по адресу:
    https://www.arduino.cc/en/Main/Products

  создан в 2005 году
  автор Дэвид А. Меллис
изменено 8 февраля 2010
  автор: Пол Стоффреген
  изменено 11 ноября 2013 г.
  автор: Скотт Фитцджеральд
изменено 9 января 2017
  автор: Артуро Гуадалупи

  Этот пример кода находится в открытом доступе.

  http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

// constants won't change. Used here to set a pin number:
const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

Вот изменения, которые приводят к тому, что светодиод загорается на 500 мс, а затем гаснет на 5000 мс.

Изменения отмечены // *************.

Надеюсь, это даст вам представление о том, как использовать millis() для управления устройством с нужными интервалами.

        /*
          Blink without Delay
          http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
        */

        const int ledPin =  LED_BUILTIN;                        // the number of the LED pin

    //  int ledState = LOW;                    // ************* // change this assignment as follows

        int ledState = 0;                      // ************* // ledState used as a state counter

        unsigned long previousMillis = 0;

    //  const long interval = 1000;            // ************* // change the interval as follows

        const long interval =  500;            // ************* // use a 500 ms interval

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

        void loop() {
          unsigned long currentMillis = millis();
          
          if (currentMillis - previousMillis >= interval) {

            previousMillis = currentMillis;    // ************* // program arrives here every 500 ms

    //      if (ledState == LOW) {             // ************* // this code is not needed
    //        ledState = HIGH;                 // ************* 
    //      } else {                           // ************* 
    //        ledState = LOW;                  // ************* 
    //      }                                  // *************

    //      digitalWrite(ledPin, ledState);    // *************


            if (ledState == 0 ) {              // *************
                digitalWrite(ledPin, HIGH);    // ************* // turn on LED at start of cycle
            }                                  // *************
            else if (ledState == 1 ) {         // *************
                digitalWrite(ledPin, LOW);     // ************* // turn off LED at end of 500 ms
            }                                  // *************
            
            ledState++;                        // ************* // increment state counter
            if (ledState > 10 )  ledState = 0; // ************* // reset ledState when it has reached end of cycle
            
          }                                                     // end of if
        }                                                       // end of loop
,