0
votes

Am trying to write Arduino code to control few stepper motors from my c++ app through serial communication. the code i wrote seems to be ok but it gives strange type of output when i send serial command from my c++ app or Arduino IDE serial monitor.

code

    #include <AccelStepper.h>
    // BaudRate
    #define BAUD 9600

    #define NO_OF_STEPPERS 3  // total # of stepper motors  + 1 , as our motor count star from 1 not from 0 , 

    struct steppers_struct {
      int stepper_id = 0;  // stepper no
      bool status = false;  // status bool 
      int steps_2_move = 0;  // steps the motor needs to move.

    };
    steppers_struct  steppers_rack[NO_OF_STEPPERS]; // init structure

    // Step and Dir pins Array 
    int step_pin_m[NO_OF_STEPPERS];
    int dir_pin_m[NO_OF_STEPPERS];
    int enable_pin_m[NO_OF_STEPPERS];

    // AcceStepper Stepper Array
    AccelStepper stepper_m[NO_OF_STEPPERS];

    // Driver A4988
    #define motorInterfaceType 1

    // Buffer
    char buf[80];

    // Readline funtion load buffer
    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;
    }

    // Setup 
    void setup() {
        Serial.begin(BAUD);  // init serial

      // stepper dir and step pins. 
      step_pin_m[1] = 2;
      dir_pin_m[1] = 5;
      enable_pin_m[1] = 8; // on CNC shield v3 its pin 8

      step_pin_m[2] = 3;
      dir_pin_m[2] = 6;
      enable_pin_m[2] = 8; // on CNC shield v3 its pin 8


      for(int i=1; i<=NO_OF_STEPPERS; i++)
      {
          stepper_m[i] = AccelStepper(motorInterfaceType, step_pin_m[i], dir_pin_m[i]);   
          stepper_m[i].setMaxSpeed(1000);
          stepper_m[i].setSpeed(1000);  
          pinMode(enable_pin_m[i], OUTPUT);   // Enable Motors
          Serial.print("AccelStepper initalized..");Serial.print("\n");     
      }

      // Some LED
     // pinMode(53, OUTPUT); // Red LED it D53
     // pinMode(52, OUTPUT); // Green LED it D52  
    }


    void loop() {
       // Serial Read Start
       if (readline(Serial.read(), buf, 80) > 0) {
      // command format 1:100;2:200;3:300
      // Read each command pair 

        char* command = strtok(buf, ";");
          while (command != 0)
          {
        // Split the command in two values
        char* separator = strchr(command, ':');
        if (separator != 0)
        {
            // Actually split the string in 2: replace ':' with 0
            *separator = 0;
            int stepperId = atoi(command);
            ++separator;
            int stepperSteps = atoi(separator);

            // Steppers id stars from 1
            if(stepperId != 0){   

            steppers_rack[stepperId].stepper_id = stepperId;
            steppers_rack[stepperId].steps_2_move = stepperSteps;
            if(stepperSteps != 0){
                steppers_rack[stepperId].status = true;
            }else{
                steppers_rack[stepperId].status = false;
            }
               //   Serial.print(" stepper id: "); Serial.print(steppers_rack[stepperId].stepper_id); Serial.print(" stepper steps: "); Serial.print(steppers_rack[stepperId].steps_2_move); Serial.print("\n");    // output OK.
            }   

        } // if end
        // Find the next command in input string
        command = strtok(0, ";");

        }  // while end   
       } // Serial Read End

    // Problems start here when i try to use or change stepper structure data. 

     // Loop on Stepper_Struct
      for(int i=1; i<=NO_OF_STEPPERS; i++)
      {   
        if(steppers_rack[i].steps_2_move != 0 && steppers_rack[i].status == true){
   Serial.print(" stepper id : ");  Serial.print(steppers_rack[i].stepper_id); Serial.print(" Steps to move : ");  Serial.print(steppers_rack[i].steps_2_move);  Serial.print(" status : ");   Serial.print(steppers_rack[i].status);  Serial.print("\n");  // Output not OK
    delay(500);   
              // Lets move stepper motor one step it time so that all motors looks moving it same time , sync
              stepper_m[i].move(1); // this states to move one step ahead
              stepper_m[i].runToPosition();
              steppers_rack[i].steps_2_move -- ;  // deducted one step from the total step motors is told to take
            if(steppers_rack[i].steps_2_move == 0){
              steppers_rack[i].status = false;
            }
        }  // if end
      }  // for end
    } // loop end

so here are few known issues am experiencing with it

1) first when i send command (1:3;2:3) from Arduino Serial Monitor then it not display any output , i have to send it two times then i see output in serial Monitor.

2) another main issue is strange output i get when i sent command : 1:3;2:3 ( mean stepper 1 move 3 steps and stepper 2 also move 3 steps )

 stepper id : 14897 Steps to move : 14848 status : 51
 stepper id : 14897 Steps to move : 59 status : 51
 stepper id : 14897 Steps to move : 12858 status : 51
 stepper id : 14897 Steps to move : 12857 status : 51
 stepper id : 14897 Steps to move : 12856 status : 51
 stepper id : 1 Steps to move : 372 status : 1
 stepper id : 49 Steps to move : 12855 status : 51
 stepper id : 1 Steps to move : 371 status : 1
 stepper id : 49 Steps to move : 12854 status : 51

so am not sure from where these big numbers 14897 , 51 , 49 etc are coming ?

so any idea what am doing wrong and to make the code working so that i can sync multiple stepper motors.

  • sorry i had to add all code in case someone try to run and debug it
1
51 is ASCII code of character '3', 49 is '1'. you can strtok with more separators like ",:"Juraj
some example of strtok stackoverflow.com/questions/56939302/…Juraj
@Juraj am already splitting it by : the output get messy in Loop on Stepper_Struct ... above it you can see i have write output OKuser889030

1 Answers

1
votes

I see an array index out of bounds problem.

You declared an array of struct this way.

#define NO_OF_STEPPERS 2  // total # of stepper motors
steppers_struct  steppers_rack[NO_OF_STEPPERS]; // init structure

The number of elements in steppers_rack is 2.

Now, you are accessing steppers_rack[2] in the for loop below. Index 2 is out of the bounds.

for(int i=1; i<=NO_OF_STEPPERS; i++) {
  if (steppers_rack[i].steps_2_move != 0 && steppers_rack[i].status == true) {

When i is 2, steppers_rack[i].steps_2_move and steppers_rack[i].status return something other than 0 and the if statement evaluates to true.