1. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Download Package Now!
  2. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  3. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant here. Do not following these rules will lead to permanent exclusion from this website: Read the forum rules.

Arduino code for steppers?

Discussion in 'DIY Motion Simulator Building Q&A / FAQ' started by jackon680, Apr 23, 2014.

  1. jackon680

    jackon680 New Member

    Joined:
    Mar 8, 2014
    Messages:
    11
    Location:
    Orange City Midwest US
    Balance:
    299Coins
    Ratings:
    +5 / 1 / -0
    My Motion Simulator:
    3DOF
    I am using stepper motors for my sim and was wondering if anyone had a code that could run 2-4 steppers on arduino. I am new to this so i have no clue how to make code that would work. so if you all are knowledgeable I'd appreciate help with a code for arduino.
    I am using an arduino uno r3, and i have nema 34 steppers 3.5a.
    this is the driver that comes with them.
    Stepper driver.jpg
    • Like Like x 2
  2. Ads Master

    Ads Master

    Balance:
    Coins
    Ratings:
    +0 / 0 / -0
  3. eaorobbie

    eaorobbie Well-Known Member Staff Member SimTools Developer Gold Contributor

    Joined:
    May 26, 2009
    Messages:
    2,593
    Occupation:
    CAD Detailer
    Location:
    Ellenbrook, Western Australia
    Balance:
    19,695Coins
    Ratings:
    +1,655 / 22 / -2
    My Motion Simulator:
    2DOF, DC motor, JRK, SimforceGT, 6DOF
    Wow steppers are crawling out of the woodwork today.
    Hint: look up AccelStepper library for the Ard, I have got my unit running with it.
    Still playing with it.
    And yes the Ard is capable of running 2 - 4 steppers.
    As for the driver above.
    Here is where I got my idea started from.
    • Like Like x 6
    • Informative Informative x 3
  4. jackon680

    jackon680 New Member

    Joined:
    Mar 8, 2014
    Messages:
    11
    Location:
    Orange City Midwest US
    Balance:
    299Coins
    Ratings:
    +5 / 1 / -0
    My Motion Simulator:
    3DOF
    would the accelstepper library code allow me to connect my ard to simtools and run 4 steppers?
    • Like Like x 1
    • Optimistic Optimistic x 1
  5. eaorobbie

    eaorobbie Well-Known Member Staff Member SimTools Developer Gold Contributor

    Joined:
    May 26, 2009
    Messages:
    2,593
    Occupation:
    CAD Detailer
    Location:
    Ellenbrook, Western Australia
    Balance:
    19,695Coins
    Ratings:
    +1,655 / 22 / -2
    My Motion Simulator:
    2DOF, DC motor, JRK, SimforceGT, 6DOF
    it needs only a 2 wires connected from the driver to the ard and all 5v and Gnds link to one spot.
    So to drive 4 motors we need 4 pwm pins and 4 digital outputs and all will use the 5v and GND from the Ard. Without checking the specs, Im sure a uno would be able.

    But in turn , 2 or even 4 Ard Uno can be run from SimTools to make all things simpler. They pretty cheap to add on. Sorry thinking out loud.
    • Like Like x 3
  6. jackon680

    jackon680 New Member

    Joined:
    Mar 8, 2014
    Messages:
    11
    Location:
    Orange City Midwest US
    Balance:
    299Coins
    Ratings:
    +5 / 1 / -0
    My Motion Simulator:
    3DOF
    alright, do you think you could make me a wiring schematic to make this more understanding for me. I get what you're saying but it would be a lot easier to have a schematic to go off of.
    • Like Like x 1
  7. markus

    markus New Member Gold Contributor

    Joined:
    Oct 29, 2014
    Messages:
    5
    Location:
    Germany
    Balance:
    276Coins
    Ratings:
    +19 / 0 / -0
    Hi,
    thanks to eaorobbie i connected an arduino uno and two servos with the simtools an it works. Now i try to connect a Stepper Motor via pololu a4988. Can someone please give me an arduino sketch or a link to a similar project?

    My wiring looks like this:

    [​IMG]
    Thanks!
    • Like Like x 3
    • Informative Informative x 1
  8. markus

    markus New Member Gold Contributor

    Joined:
    Oct 29, 2014
    Messages:
    5
    Location:
    Germany
    Balance:
    276Coins
    Ratings:
    +19 / 0 / -0
    Hi,

    i've now "puzzled" this little code:


    Code:
    #include <AccelStepper.h>
    
    
    AccelStepper stepper1(1, 31, 30); // pin 3 = step, pin 6 = direction
    
    
    int pos = 0;
    
    
    enum TPortState { psReadActuator, psReadValue }; 
    TPortState currentState = psReadActuator;
    const int kActuatorCount = 1;
    
    
    // the letters ("names") sent from Sim Tools to identify each actuator
    // NB: the order of the letters here determines the order of the remaining constants kPins and kActuatorScale
    const char kActuatorName[kActuatorCount] = {'L'};
    const int kActuatorScale[kActuatorCount][2] = { {0, 100} };  //Scaling 
    const char kEOL = '~';  // End of Line - the delimiter for our acutator values
    const int kMaxCharCount = 3;  // some insurance...
    int actuatorPosition[kActuatorCount] = {0};  // current Actuator positions, initialised to 90
    int currentActuator;  // keep track of the current Actuator being read in from serial port
    int valueCharCount = 0;  // how many value characters have we read (must be less than kMaxCharCount!!
    
    
    void setup()
    { 
      stepper1.setMaxSpeed(2700);
      stepper1.setAcceleration(2500);
      Serial.begin(9600);
    }
    
    
    void loop()
    
    
    {
    
    
      if (stepper1.distanceToGo() == 0)
      {
      stepper1.moveTo((pos * 50));
      }
      stepper1.run();
     
    }
    
    
    void serialEvent() {
      char tmpChar;
      int tmpValue;
    
    
      while (Serial.available()) {
      // if we're waiting for a Actuator name, grab it here
      if (currentState == psReadActuator) {
      tmpChar = Serial.read();
      // look for our actuator in the array of actuator names we set up
    
    
      for (int i = 0; i < kActuatorCount; i++) {
      if (tmpChar == kActuatorName[i]) {
    
    
      currentActuator = i;  // remember which actuator we found
      currentState = psReadValue;  // start looking for the Actuator position
      actuatorPosition[currentActuator] = 0;  // initialise the new position
      valueCharCount = 0;  // initialise number of value chars read in
      break;
      }
      }
      }
    
    
      // if we're ready to read in the current Actuator's position data
      if (currentState == psReadValue) {
      while ((valueCharCount < kMaxCharCount) && Serial.available()) {
      tmpValue = Serial.read();
      if (tmpValue != kEOL) {
      tmpValue = tmpValue - 48;
      if ((tmpValue < 0) || (tmpValue > 9)) tmpValue = 0;
      actuatorPosition[currentActuator] = actuatorPosition[currentActuator] * 10 + tmpValue;
      valueCharCount++;
      }
      else break;
      }
    
    
      // if we've read the value delimiter, update the Actuator and start looking for the next Actuator name
      if (tmpValue == kEOL || valueCharCount == kMaxCharCount) {
    
    
      // scale the new position so the value is between 0 and 179
      actuatorPosition[currentActuator] = map(actuatorPosition[currentActuator], 0, 255, kActuatorScale[currentActuator][0], kActuatorScale[currentActuator][1]);
    
    
      updateActuator(currentActuator);
      currentState = psReadActuator;
      }
      }
      }
    }
    
    
    // write the current Actuator position to the passed in Actuator
    void updateActuator(int thisActuator) {
      if (pos =! actuatorPosition[thisActuator]);
      pos = (actuatorPosition[thisActuator]);
    }
    One stepper is working in test-mode, but when i move the axis to -20 it turns 3 rotations and not only a few degrees. If i change
    the output-bit range it turns near by -50 or -70. I think there are some errors in scaling, but i dont know how to fix this.

    The second problem is that it works with only one stepper (stepper1). How can i get one position for one stepper?

    Can you please help me? Thanks.
    • Like Like x 1
  9. eaorobbie

    eaorobbie Well-Known Member Staff Member SimTools Developer Gold Contributor

    Joined:
    May 26, 2009
    Messages:
    2,593
    Occupation:
    CAD Detailer
    Location:
    Ellenbrook, Western Australia
    Balance:
    19,695Coins
    Ratings:
    +1,655 / 22 / -2
    My Motion Simulator:
    2DOF, DC motor, JRK, SimforceGT, 6DOF
    Here is something I have been slowly working on, this is not driven by any lib like AccelStepper as the library has a blocking function in it, basically it pauses the code until the stepper has finished moving before the code continues and if another block of data hits the serial port and the stepper is moving the data will be ignored , a lot stepper dashes I have seen in the past don't achieve smooth movements or seem to lag or suddenly a gauge works then doesn't work, this is why.

    2dof 360 model wiring_bb.jpg
    Please note this was designed to run a model only but you can upscale the schem by using the right bigger stepper driver , ie One that's compatible with a 5v input command, then we can drive them with an Ard.
    • Informative Informative x 3
    • Like Like x 2
  10. markus

    markus New Member Gold Contributor

    Joined:
    Oct 29, 2014
    Messages:
    5
    Location:
    Germany
    Balance:
    276Coins
    Ratings:
    +19 / 0 / -0
    Hi eaorobbie, thanks for helping.
    This is what i'm searching for.
    Do you have the Arduino sketch for this?

    Thanks a lot
    Markus
    • Like Like x 1
  11. markus

    markus New Member Gold Contributor

    Joined:
    Oct 29, 2014
    Messages:
    5
    Location:
    Germany
    Balance:
    276Coins
    Ratings:
    +19 / 0 / -0
    Hi,

    i've puzzled a little bit again, to set the stepper 'step by step'. But it works only in the negative axis movement, and not really good.

    Here is my code:

    Code:
    
    int Distance = 0;
    int Pos = 0;
    
    enum TPortState { psReadActuator, psReadValue };  
    TPortState currentState = psReadActuator;
    const int kActuatorCount = 1;
    
    // the letters ("names") sent from Sim Tools to identify each actuator
    // NB: the order of the letters here determines the order of the remaining constants kPins and kActuatorScale
    const char kActuatorName[kActuatorCount] = {'L'};
    const int kActuatorScale[kActuatorCount][2] = { {0, 100} };  //Scaling   
    const char kEOL = '~';                              // End of Line - the delimiter for our acutator values
    const int kMaxCharCount = 5;                        // some insurance...
    int actuatorPosition[kActuatorCount] = {0};         // current Actuator positions, initialised to 90
    int currentActuator;                                // keep track of the current Actuator being read in from serial port
    int valueCharCount = 0;                             // how many value characters have we read (must be less than kMaxCharCount!!
    
    void setup()
    { 
      pinMode(30, OUTPUT);    
      pinMode(31, OUTPUT);
      digitalWrite(30, LOW);
      digitalWrite(31, LOW);
      Serial.begin(115200);
    }
    
    void loop()
    
    {
    // Stepper run...
    if (Distance != Pos) {
      digitalWrite(31, HIGH);
      delayMicroseconds(20);         
      digitalWrite(31, LOW);
      delayMicroseconds(20);
      if (digitalRead(30) == LOW)
        {
            Distance = Distance - 1;   // record this step
        }
        else
        {
            Distance = Distance + 1;   // record this step
        }
    }
      // Check to see if we are at the end of our move
      if (Distance > Pos)
      {
        // We are! Reverse direction (invert DIR signal)
        if (digitalRead(30) == LOW)
        {
          digitalWrite(30, HIGH);
        }
        else
        {
          digitalWrite(30, LOW);
        }
        // Reset our distance back to zero since we're
        // starting a new move
        Distance = 0;
        // Now pause for half a second
        delay(5);
      }
    }
    
    void serialEvent() {
      char tmpChar;
      int tmpValue;
    
      while (Serial.available()) {
        // if we're waiting for a Actuator name, grab it here
        if (currentState == psReadActuator) {
          tmpChar = Serial.read();
          // look for our actuator in the array of actuator names we set up
    
          for (int i = 0; i < kActuatorCount; i++) {
            if (tmpChar == kActuatorName[i]) {
    
              currentActuator = i;          // remember which actuator we found
              currentState = psReadValue;                 // start looking for the Actuator position
              actuatorPosition[currentActuator] = 0;      // initialise the new position
              valueCharCount = 0;                         // initialise number of value chars read in
              break;
            }
          }
        }
    
        // if we're ready to read in the current Actuator's position data
        if (currentState == psReadValue) {
          while ((valueCharCount < kMaxCharCount) && Serial.available()) {
            tmpValue = Serial.read();
            if (tmpValue != kEOL) {
              tmpValue = tmpValue - 48;
              if ((tmpValue < 0) || (tmpValue > 9)) tmpValue = 0;
              actuatorPosition[currentActuator] = actuatorPosition[currentActuator] * 10 + tmpValue;
              valueCharCount++;
            }
            else break;
          }
    
          // if we've read the value delimiter, update the Actuator and start looking for the next Actuator name
          if (tmpValue == kEOL || valueCharCount == kMaxCharCount) {
    
            // scale the new position so the value is between 0 and 179
            actuatorPosition[currentActuator] = map(actuatorPosition[currentActuator], 0, 255, kActuatorScale[currentActuator][0], kActuatorScale[currentActuator][1]);
    
            updateActuator(currentActuator);
            currentState = psReadActuator;
          }
        }
      }
    }
    
    // write the current Actuator position to the passed in Actuator
    void updateActuator(int thisActuator) {
       if (Pos =! actuatorPosition[thisActuator]);
              Pos = (actuatorPosition[thisActuator]);
    }
    

    I hope someone can help me.
    • Like Like x 2
    • Informative Informative x 2
  12. markus

    markus New Member Gold Contributor

    Joined:
    Oct 29, 2014
    Messages:
    5
    Location:
    Germany
    Balance:
    276Coins
    Ratings:
    +19 / 0 / -0
    Hi again,

    now the code is working, but in a very simple way. It can be used to handle up to 6 stepper Drivers (or more, i think) on a arduino mega, so it it very scalable. Must the code use ramps, if the direction is turned?

    Is it possible to build a 6dof stewart platform with steppers? I found nema42 steppers with 33 Nm. Is that enough?

    Best wishes
    Markus

    Code:
    // #define DEBUG 1                                    // comment out this line to remove debuggin Serial.print lines
    
    // Declare pins
    int STEP[] = {31,33,35,37,39,41};    // Step Pins,  active HIGH
    int DIR[] = {30,32,34,36,38,40};     // Direction Pins, active HIGH
    byte DIR_ACTIVE[] = {LOW, LOW, LOW, LOW, LOW, LOW};
    
    const int kAxisCount = 6;                          // how many axis we are handling
    
    int Pos[] = {0,0,0,0,0,0}; //Position logging
    
    const char kAxisName[kAxisCount] = {'R','P','H','Y','S','U'};    // the letters ("names") sent from Sim Tools to identify each axis
    const int kAxisScale[kAxisCount][6] = { {0,999},{0,999},{0,999},{0,999},{0,999},{0,999} };  //Scaling
    const char kEOL = '~';                             // End of Line - the delimiter for our acutator values
    const int kMaxCharCount = 3;                       // some insurance to 8 bit...
    int axisPosition[kAxisCount] = {0,0,0,0,0,0};         // current Axis positions, initialised to 127 middle for 8 bit
    int currentAxis;                                   // keep track of the current Axis being read in from serial port
    int valueCharCount = 0;                            // how many value characters have we read (must be less than kMaxCharCount!!
    
    // set up some states for our state machine
    // psReadAxis = next character from serial port tells us the Axis info that follows
    // psReadValue = next characters from serial port until we hit our kMaxCharCount or kEOL which tells us the value
    enum TPortState { psReadAxis, psReadValue };  
    TPortState currentState = psReadAxis;
    
    void setup()  {
      Serial.begin(921600);
     
      // Define pins
      for (int i=0; i < kAxisCount; i++)  {
        pinMode(STEP[i], OUTPUT);
        pinMode(DIR[i], OUTPUT);
      }
    }
    
    void loop()
    {
    for (int i = 0; i < kAxisCount; i++) {
    // check new position
    if (Pos[i] != axisPosition[i])  { 
     
      // check direction and write DIR pin
      if (Pos[i] >= axisPosition[i])  { 
      digitalWrite(DIR[i], LOW);
      Pos[i] = Pos[i] - 1;
        }
       
      if (Pos[i] < axisPosition[i])  { 
      digitalWrite(DIR[i], HIGH);
      Pos[i] = Pos[i] + 1;
        }
       
        // make one step
        digitalWrite(STEP[i], HIGH);
        delayMicroseconds(500);
        digitalWrite(STEP[i], LOW);
        delayMicroseconds(500);
       
        //break;
    }}}
    
    // this code only runs when we have serial data available. ie (Serial.available() > 0).
    void serialEvent() {
        char tmpChar;
        int tmpValue;
    
        while (Serial.available()) {
            // if we're waiting for a Axis name, grab it here
            if (currentState == psReadAxis) {
                tmpChar = Serial.read();
               
    #ifdef DEBUG           
    Serial.print("read in ");           
    Serial.println(tmpChar);           
    #endif
            for (int i = 0; i < kAxisCount; i++) {    // look for our axis in the array of axis names we set up
            if (tmpChar == kAxisName[i]) {
    #ifdef DEBUG           
    Serial.print("which is axis ");           
    Serial.println(i);           
    #endif
                        currentAxis = i;                            // remember which axis we found
                        currentState = psReadValue;                 // start looking for the Axis position
                        axisPosition[currentAxis] = 0;              // initialise the new position
                        valueCharCount = 0;                         // initialise number of value chars read in
                        //break;
                    }
                }
            }
           
            // if we're ready to read in the current Axis position data
            if (currentState == psReadValue) {
                while ((valueCharCount < kMaxCharCount) && Serial.available()) {
                    tmpValue = Serial.read();
                    if (tmpValue != kEOL) {
                        tmpValue = tmpValue - 48;
                        if ((tmpValue < 0) || (tmpValue > 9)) tmpValue = 0;
                        axisPosition[currentAxis] = axisPosition[currentAxis] * 10 + tmpValue;
                        valueCharCount++;
                    }
                    else break;
                }
               
                // if we've read the value delimiter, update the Axis and start looking for the next Axis name
                if (tmpValue == kEOL || valueCharCount == kMaxCharCount) {
                 
                 
                  // scale the new position so the value is between 0 and 179
                  axisPosition[currentAxis] = map(axisPosition[currentAxis], 0, 255, kAxisScale[currentAxis][0], kAxisScale[currentAxis][1]);
                  // updateAxis(currentAxis);
                 
    #ifdef DEBUG           
    Serial.print("read in ");           
    Serial.println(axisPosition[currentAxis]); 
    Serial.print("Position ");           
    Serial.println(Pos[currentAxis]);  
    #endif
                   
                    currentState = psReadAxis;
                }
            }
        }
    }
    • Like Like x 7
    • Informative Informative x 2
  13. madmaik

    madmaik New Member

    Joined:
    Mar 2, 2015
    Messages:
    6
    Balance:
    - 23Coins
    Ratings:
    +3 / 0 / -0
    My Motion Simulator:
    2DOF, Arduino
    Hi,

    great work. i modify the sketch a little bit an use it with leadshines M542 and stepper inear acutators with a arduino uno.

    cheers Maik
    • Like Like x 3
  14. eightbit

    eightbit Active Member

    Joined:
    May 20, 2013
    Messages:
    108
    Occupation:
    Fish Farmer
    Location:
    Trentham Cliffs
    Balance:
    342Coins
    Ratings:
    +45 / 0 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino
    Hello :) thank you very much for the sketch Markus!! I've got 2 arduino uno running on simtools advice about to hook up a couple of stepper drivers I have around and I'll post a video and pics as soon as possible. And again thank you this has been an exciting past sleepless 24hours;)
  15. Alexandre Kostik

    Alexandre Kostik Member

    Joined:
    Jul 2, 2014
    Messages:
    42
    Occupation:
    realtor
    Location:
    Brasil
    Balance:
    370Coins
    Ratings:
    +17 / 1 / -0
    My Motion Simulator:
    2DOF
    Hello!! @markus
    Did you make the simtools drive the step motors? I want to make my linear actuators and I would like more information about the ard code .... Here in Brazil it is impossible to import something because the rates are absurd !!! Sorry for the english .... by google translator ...
    Thanks.[/CODE]
    • Informative Informative x 1
  16. vehbi sogucakli

    vehbi sogucakli New Member Gold Contributor

    Joined:
    Dec 20, 2016
    Messages:
    1
    Location:
    konya
    Balance:
    - 169Coins
    Ratings:
    +1 / 0 / -0
    My Motion Simulator:
    2DOF, Arduino, Motion platform
    Hello, first of all thank you very much for the code. I use a 15cm linear actuator. I want you to go up to 7cm without giving your first move. It will be 7cm 0 point. I would like to add this to the existing code. I'm very happy if you can help me with this.
    • Like Like x 1
  17. Flymen

    Flymen Flymen Gold Contributor

    Joined:
    May 19, 2018
    Messages:
    208
    Location:
    Montreal, Canada
    Balance:
    1,557Coins
    Ratings:
    +123 / 2 / -0
    My Motion Simulator:
    DC motor, Arduino, 6DOF

    Hi . Do you used the microstep driver for your simulator ?
    • Like Like x 1
    • Optimistic Optimistic x 1
  18. Andrea 1968

    Andrea 1968 Member

    Joined:
    Jul 1, 2015
    Messages:
    60
    Location:
    italia
    Balance:
    160Coins
    Ratings:
    +37 / 0 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino
    hi, would it be possible to put a picture of the simtools interface setting for the aforementioned arduino code?
    Thank you for your work.
    • Like Like x 1
  19. felixtruck

    felixtruck New Member

    Joined:
    Aug 24, 2018
    Messages:
    1
    Balance:
    61Coins
    Ratings:
    +1 / 0 / -0
    Good, I like it, thank you for support.
    • Like Like x 1
  20. Joey

    Joey Member

    Joined:
    Jul 16, 2019
    Messages:
    39
    Occupation:
    Technician
    Location:
    Nijmegen
    Balance:
    146Coins
    Ratings:
    +15 / 0 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino
    Can you share that code? I've almost got it working with a couple of TB6600's .
  21. Ivan Zaharov

    Ivan Zaharov New Member Gold Contributor

    Joined:
    Jul 6, 2019
    Messages:
    25
    Balance:
    91Coins
    Ratings:
    +6 / 0 / -0
    My Motion Simulator:
    2DOF, DC motor, AC motor, Arduino, 6DOF
    Hello. I am doing a 4dof simulator. For him, I bought the AC servomotors 4Nm 3000 rpm, I want to make them
    actuator. The servo controller is controlled by step / dir.
    I tried your code, but it works for me a little incorrectly.
    Probably something is wrong in the settings of SimTools. When I connect the control with SimTools, the motor spins a little. Impulses come from the Arduino. I have Arduino MEGA 2560. Can you help me?
    I will be very grateful to you. Sorry for my English.