Как запустить шаговый двигатель через последовательную связь

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

Вот мой код, не знаю, что я делаю не так, мой первый раз с Arduino.

#include <AccelStepper.h>

#define BAUD 9600

// Штифты Step и Dir CNC Shield V3 на Mega 2560
#define step_pin_x 2
#define dir_pin_x 5
#define MOTOR_X_ENABLE_PIN 8
// Диск A4988
#define motorInterfaceType 1

AccelStepper stepper_X = AccelStepper(motorInterfaceType, step_pin_x, dir_pin_x);

void setup() {
  Serial.begin(BAUD);
  pinMode(53, OUTPUT);   // для красного светодиода это пин № 53
  pinMode(MOTOR_X_ENABLE_PIN, OUTPUT);  // для шагового двигателя X

    stepper_X.setMaxSpeed(1000);
    stepper_X.setSpeed(500); 
}

void loop() {
    String input;
  //Если какой-либо ввод обнаружен в arduino
  if(Serial.available() > 0){
    //читаем всю строку, пока не будет прочитан разделитель '\n'
    input = Serial.readStringUntil('\n');

    if (input.equals("ON")){
       digitalWrite(53, HIGH);   // Включаем КРАСНЫЙ светодиод
       stepper_X.runSpeed();      // Допустим, работает шаговый двигатель.. но он не работает
       Serial.println("X Motors:: "+input);

    }else if (input.equals("OFF")){
       stepper_X.stop(); 
       digitalWrite(53, LOW);    // ВЫКЛЮЧИТЬ КРАСНЫЙ СВЕТОДИОД
       Serial.println("X Motors:: "+input);
    }

  }else{
  // stepper_X.runSpeed(); // если будет работать незакомментированный шаговый двигатель
  }
}

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

я обновляю свой код согласно инструкции: https://majenko.co.uk/blog/reading-serial -ардуино

    char buf[80];

    int readline(int readch, char *buffer, int len) {
        static int pos = 0;
        int rpos;

        if (readch > 0) {
            switch (readch) {
                case '\r': // Игнорировать CR
                    break;
                case '\n': // Возврат на новую строку
                    rpos = pos;
                    pos = 0;  // Сбросить индекс позиции, готовый к следующему разу
                    return rpos;
                default:
                    if (pos < len-1) {
                        buffer[pos++] = readch;
                        buffer[pos] = 0;
                    }
            }
        }
        return 0;
    } 

void loop() {
   if (readline(Serial.read(), buf, 80) > 0) {
   if(strcmp("n", buf) == 0){
          digitalWrite(53, HIGH);
         stepper_X.setMaxSpeed(1000);
         stepper_X.setSpeed(500); 
          stepper_X.runSpeed();
          Serial.print("All Motors:: ");
          Serial.print(buf);

        }
    }
}

теперь все работает нормально

Обновление 2: отправка команды c++ через последовательный порт

    std::string input_command = "ON"; 
    //Создание строки переменного тока
     char *c_string = new char[input_command.size() + 1];
     // копирование std::string в строку c
     std::copy(input_command.begin(), input_command.end(), c_string);
     //Добавление разделителя
     c_string[input_command.size()] = '\n';

// используя эту последовательную библиотеку: https://github.com/manashmndl/SerialPort
   writeSerialPort(c_string, MAX_DATA_LENGTH);  

, 👍0

Обсуждение

Вы проверили, правильно ли передаются данные, отражая их обратно и показывая их в своем приложении?, @chrisl

@chrisl, данные получены правильно, даже если я получаю ответ от Arduino, например X Motors ON, OFF и т. д., @user889030

Вы уверены, что отправляете "ON\n", а не "ON\r" или "ON\r\n"?, @Edgar Bonet

@EdgarBonet Да, я отправляю «ON\n» .... красный светодиод включается и выключается с помощью команды ON / OFF, что означает, что если проверка (input.equals («ON»)) становится действительной, также я получаю ответ, что двигатель X :: НА, @user889030


1 ответ


Лучший ответ:

2

Согласно документации по runSpeed() AccelStepper. метод:

Вы должны вызывать это как можно чаще, но не реже одного раза в интервал шага,

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

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

,

Ботне, спасибо за ценную информацию, друг другу Вопрос, который у меня есть, я заметил, что последовательная связь медленная, я имею в виду, что Arduino получает сообщение и двигатель начинает двигаться около 2 секунд, так что вы можете сказать, как сделать его надежным, я имею в виду что-то вроде связи в реальном времени, так как я работаю над проектом SMT, поэтому мне нужно будет как можно скорее переместить шаговые двигатели в их места, но это медленно, требуется около 3 секунд, чтобы получить ответ, а затем двигатель движется, @user889030

@ user889030: Медленная связь чаще всего является признаком тайм-аута метода ввода Stream. Например, readStringUntil() истекает, когда он не может найти символ конца во входном потоке (вы уверены, что отправляете '\n'?). Длительность тайм-аута по умолчанию составляет одну секунду. См. здесь [список методов Stream, основанных на тайм-ауте](https://www.arduino.cc/reference/en/language/functions/communication/stream/streamsettimeout/#_notes_and_warnings). У вас не должно быть этой проблемы, если вы отправляете символ терминатора или если вы анализируете входной поток, как в учебнике Маженко., @Edgar Bonet

Ботнет, я отправляю с ним '\n', вы можете видеть, что я добавил код C++, спасибо, @user889030