Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: Stepper Motor Array

  1. #1
    Junior Member
    Join Date
    Feb 2021
    Posts
    13

    Stepper Motor Array

    Hi,

    I am using TeensyStep4 with a Teensy 4.1 on PlatformIO. I have 10 stepper motors that I control and so I set up an array of stepper motor objects as shown below:

    Code:
    // Stepper objects
    // Arguments are x & y where
    // x is the pulse output pin
    // y is the direction output pin
    Stepper stepper1(STEPPER1_PULSE_PIN, STEPPER1_DIR_PIN); 
    Stepper stepper2(STEPPER2_PULSE_PIN, STEPPER2_DIR_PIN); 
    Stepper stepper3(STEPPER3_PULSE_PIN, STEPPER3_DIR_PIN); 
    Stepper stepper4(STEPPER4_PULSE_PIN, STEPPER4_DIR_PIN); 
    Stepper stepper5(STEPPER5_PULSE_PIN, STEPPER5_DIR_PIN); 
    Stepper stepper6(STEPPER6_PULSE_PIN, STEPPER6_DIR_PIN); 
    Stepper stepper7(STEPPER7_PULSE_PIN, STEPPER7_DIR_PIN); 
    Stepper stepper8(STEPPER8_PULSE_PIN, STEPPER8_DIR_PIN); 
    Stepper stepper9(STEPPER9_PULSE_PIN, STEPPER9_DIR_PIN);
    Stepper stepper10(STEPPER10_PULSE_PIN, STEPPER10_DIR_PIN);
    Stepper steppers[10] = {stepper1, stepper2, stepper3, stepper4, stepper5, stepper6, stepper7, stepper8, stepper9, stepper10};
    StepperGroup g1{steppers[0], steppers[1], steppers[2], steppers[3], steppers[4], steppers[5], steppers[6], steppers[7], steppers[8], steppers[9]};
    Moving the motors together in a group works beautifully. I have an array of target positions and I pass them to the the stepper objects as shown below:

    Code:
    // Set the new stepper targets
    for (int i = 0; i <= 9; i++) {
      steppers[i].setTargetAbs(stepperTargets[i]);
    }
    // Move the stepper group
    g1.move();
    I'm having a problem though when I want to move only one of the motors. I have written the following subroutine to start testing a homing sequence:

    Code:
    // Home all the spreaders
    void spreaderHoming() {
      Serial.println();
      Serial.println("Homing initiated...");
      Serial.println();
    
      // Set the speed for the stepper motors for the homing routine
      for (int i = 0; i <= 9; i++) {
        steppers[i].setMaxSpeed(HOME_SPEED);
        Serial.print("Spreader ");
        Serial.print(i + 1);
        Serial.print(" array initial position: ");
        Serial.println(steppers[i].getPosition());
      }
    
      steppers[4].moveAbsAsync(steppers[4].getPosition() - 500);
      do {
        inputsUpdate();
        if (inputArray[ADDR_PROXY_6]) {
          Serial.println("Proxy detected...");
        }
      } while (steppers[4].isMoving);
      delay(1000);
      Serial.println();
      for (int i = 0; i <= 9; i++) {
        Serial.print("Spreader ");
        Serial.print(i + 1);
        Serial.print(" array final position: ");
        Serial.println(steppers[i].getPosition());
      }
    }
    I would expect only the 5th stepper motor in the array to move, but all the stepper motors from the 5th to the tenth one move! This is the output that I get from the serial monitor:

    Homing initiated...

    Spreader 1 array initial position: 15915
    Spreader 2 array initial position: 15915
    Spreader 3 array initial position: 15915
    Spreader 4 array initial position: 15915
    Spreader 5 array initial position: 15915
    Spreader 6 array initial position: 15915
    Spreader 7 array initial position: 15915
    Spreader 8 array initial position: 15915
    Spreader 9 array initial position: 15915
    Spreader 10 array initial position: 15915

    Spreader 1 array final position: 15915
    Spreader 2 array final position: 15915
    Spreader 3 array final position: 15915
    Spreader 4 array final position: 15915
    Spreader 5 array final position: 15415
    Spreader 6 array final position: 16415
    Spreader 7 array final position: 16415
    Spreader 8 array final position: 16415
    Spreader 9 array final position: 16415
    Spreader 10 array final position: 16415


    As can be seen, the 5th stepper motor in the array does change its position correctly, but I don't know why the other stepper motors (greater than the 5th one) also change their positions (and in the opposite direction). If anyone could shed any light on this, I would appreciate it.

    Thanks very much.

  2. #2
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,782
    Use an array of pointers or references to the stepper objects, or else define the steppers as an array in the first place (there is some C++ syntax for initializing an array of objects with their constructor parameters that I can never remember!).

    You create 10 stepper objects, then 10 more in an array that are copied from the first 10, AFAICT. I think you are relying on copy constructors being correctly setup for this to work, which might (or might not) explain the issue you are seeing.

  3. #3
    Junior Member
    Join Date
    Feb 2021
    Posts
    13
    I think what you propose is something I should try (although I'll have to try find some examples of pointer array declarations and how to work with them). What I found subsequently to my original post was that if I called getPosition from one of the original stepper motor objects (such as stepper5.getPosition() for example) after making my group move with the array, it reported its position as still being 0. So, the array of stepper objects is definitely separate to the original list of stepper object declarations, which was not the intention.

  4. #4
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,949
    To intialize an array of steppers you can do:
    Code:
    Stepper steppers[] = {
        {STEPPER1_PULSE_PIN, STEPPER1_DIR_PIN},
        {STEPPER2_PULSE_PIN, STEPPER2_DIR_PIN},
        {STEPPER3_PULSE_PIN, STEPPER3_DIR_PIN},
        {STEPPER4_PULSE_PIN, STEPPER4_DIR_PIN},
        {STEPPER5_PULSE_PIN, STEPPER5_DIR_PIN},
        {STEPPER6_PULSE_PIN, STEPPER6_DIR_PIN},
        {STEPPER7_PULSE_PIN, STEPPER7_DIR_PIN},
        {STEPPER8_PULSE_PIN, STEPPER8_DIR_PIN},
        {STEPPER9_PULSE_PIN, STEPPER9_DIR_PIN},
        {STEPPER10_PULSE_PIN, STEPPER10_DIR_PIN}
        };
    As MarkT pointed out, your original code makes copies of the steppers which will not work (I will disable the copy constructor / assignment operator in the next version to avoid this). Let me know if this fixes your intial problem. Might be related to something else..

  5. #5
    Junior Member
    Join Date
    Feb 2021
    Posts
    13
    Thanks luni. I will try this now. If I want to use the stepper objects in a StepperGroup for synchronised motion, would I still declare the object as follows:

    StepperGroup g1{steppers[0], steppers[1], steppers[2], steppers[3], steppers[4], steppers[5], steppers[6], steppers[7], steppers[8], steppers[9]};

  6. #6
    Junior Member
    Join Date
    Feb 2021
    Posts
    13
    I implemented the stepper array as suggested and also the StepperGroup as per my previous post. The group moves all work perfectly as expected, but my homing routine behaves strangely. This is the code for my homing routine:

    Code:
    void spreaderHoming() {
    
      bool proxyDetected[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
      Serial.println("\nHoming initiated...");
    
      // Set the speed for the stepper motors for the homing routine
      for (int i = 0; i <= 9; i++) {
        steppers[i].setMaxSpeed(HOME_SPEED);
      }
    
      // Get the current input status of the proxies
      inputsUpdate();
    
      for (int i = 4; i >= 0; i--) {
        if (!inputArray[ADDR_PROXY_2 + i]) {
          steppers[i].moveAbsAsync(-MAX_STEPS);
          Serial.print("Spreader ");
          Serial.print(i + 1);
          Serial.println(" homing started.");
          do {
            inputsUpdate();
            // Watch for the stop proxy
            if (inputArray[ADDR_PROXY_2 + i] && !proxyDetected[i]) {
              Serial.print("Spreader ");
              Serial.print(i + 1);
              Serial.println(" proxy detected.");
              steppers[i].emergencyStop();
              // Set the spreader position to 0
              steppers[i].setPosition(0);
              // Homing completed
              proxyDetected[i] = true;
            }
          } while (not proxyDetected[i]);
        } else {
          Serial.print("Spreader ");
          Serial.print(i + 1);
          Serial.println(" already homed.");
        }
        delay(100);
        if (!inputArray[ADDR_PROXY_11 - i]) {
          steppers[9 - i].moveAbsAsync(-MAX_STEPS);
          Serial.print("Spreader ");
          Serial.print(10 - i);
          Serial.println(" homing started.");
          do {
            inputsUpdate();
            // Watch for the stop proxy
            if (inputArray[ADDR_PROXY_11 - i] && !proxyDetected[9 - i]) {
              Serial.print("Spreader ");
              Serial.print(10 - i);
              Serial.println(" proxy detected.");
              steppers[9 - i].emergencyStop();
              // Set the spreader position to 0
              steppers[9 - i].setPosition(0);
              // Homing completed
              proxyDetected[9 - i] = true;
            }
          } while (not proxyDetected[9 - i]);
        } else {
          Serial.print("Spreader ");
          Serial.print(10 - i);
          Serial.println(" already homed.");
        }
        delay(100);
      }
    }
    If I do a homing routine as soon as the Teensy boots up, then the stepper motors work as expected, homing one at a time from the inside of the array outwards. Perfect. However, if I try do a homing routine after I've done some group moves, then it's chaos. This is what I've observed:
    - Stepper[4] starts homing as expected, but then at the same time Stepper[5] starts moving in the wrong direction,
    - After Stepper[4] reaches it's proxy, Stepper[3], Stepper[4], Stepper[5] and Stepper[6] start moving,
    - I kill the power

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •