0

I am trying to run a Stepper motor from my c++ application, from which I sent commands but its not running not sure why would it not run, outside serial check it run but inside serial check it not run.

Here is my code, not sure what am doing wrong, my first time with Arduino.

#include <AccelStepper.h>

#define BAUD 9600

// CNC Shield V3  Step and Dir pins on Mega 2560
#define step_pin_x 2
#define dir_pin_x 5
#define MOTOR_X_ENABLE_PIN 8
// Drive A4988
#define motorInterfaceType 1

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

void setup() {
  Serial.begin(BAUD);
  pinMode(53, OUTPUT);   // for red led it pin # 53
  pinMode(MOTOR_X_ENABLE_PIN, OUTPUT);  // for X stepper motor

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

void loop() {
    String input;
  //If any input is detected in arduino
  if(Serial.available() > 0){
    //read the whole string until '\n' delimiter is read
    input = Serial.readStringUntil('\n');

    if (input.equals("ON")){
       digitalWrite(53, HIGH);   // Turn ON RED LED
       stepper_X.runSpeed();      // Suppose to run stepper motor .. but not working    
       Serial.println("X Motors:: "+input);

    }else if (input.equals("OFF")){
       stepper_X.stop(); 
       digitalWrite(53, LOW);    // Turn OFF RED LED
       Serial.println("X Motors:: "+input);
    }

  }else{
  //  stepper_X.runSpeed();      // if uncommented stepper motor will run
  }
}

Update so it seems its code blocking issues

i update my code according to tut : https://majenko.co.uk/blog/reading-serial-arduino

    char buf[80];

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

        if (readch > 0) {
            switch (readch) {
                case '\r': // Ignore CR
                    break;
                case '\n': // Return on new-line
                    rpos = pos;
                    pos = 0;  // Reset position index ready for next time
                    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);

        }
    }
}

now its working ok

Update 2 : c++ sending command via Serial

    std::string input_command = "ON"; 
    //Creating a c string
     char *c_string = new char[input_command.size() + 1];
     //copying the std::string to c string
     std::copy(input_command.begin(), input_command.end(), c_string);
     //Adding the delimiter
     c_string[input_command.size()] = '\n';

// using this serial lib : https://github.com/manashmndl/SerialPort
   writeSerialPort(c_string, MAX_DATA_LENGTH);  
  • Have you checked, if the data get's correctly transmitted by echoing it back and showing it in your application? – chrisl Jul 10 at 17:59
  • @chrisl ya data reached correctly even i get reply from Arduino like X Motors ON , OFF etc – user889030 Jul 10 at 18:16
  • Are you sure you are sending "ON\n" rather than "ON\r" or "ON\r\n"? – Edgar Bonet Jul 10 at 18:51
  • @EdgarBonet Yes am Sending "ON\n" .... the red LED turn ON and OFF with ON/OFF command which mean that if (input.equals("ON")) check become valid also i get reply that X motor :: ON – user889030 Jul 10 at 19:08
2

Per the documentation of the AccelStepper’s runSpeed() method:

You must call this as frequently as possible, but at least once per step interval,

It appears the AccelStepper library is not compatible with blocking code. Not a big deal, blocking code is almost always bad practice anyway. However, Serial.readStringUntil() is a blocking function: it will prevent the program from doing any useful work.

You have to read the serial port in a non-blocking fashion, use the commands to set the motor speed, and always call runSpeed() as frequently as possible.

  • Botne , thanks for valuable information , one another Question i have , i noticed serial communication is slow , i mean it take about 2 sec to arduino to get message and the motor start moving , so can you tell how to make it robust , i mean something like real time communication , as am working on SMT project so i will need to move stepper motors to their locations fast as soon as possible but this is slow it take about 3 sec to get response and then motor move – user889030 Jul 11 at 6:52
  • @user889030: Slow communication is most commonly the sign of a Stream input method timing out. For example, readStringUntil() times out when it can't find the terminator character in the input stream (are you sure you send the '\n'?). The default timeout duration is one second. See here the list of timeout-based Stream methods. You shouldn't have this problem if you do send the terminator character, or if you parse the input stream as in Majenko's tutorial. – Edgar Bonet Jul 11 at 7:45
  • Botnet ya ma sending '\n' with it , you can see i added some c++ code , thanks – user889030 Jul 11 at 11:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.