1. Do not share user accounts! Any account that is shared by another person will be blocked and closed. This means: we will close not only the account that is shared, but also the main account of the user who uses another person's account. We have the ability to detect account sharing, so please do not try to cheat the system. This action will take place on 04/18/2023. Read all forum rules.
    Dismiss Notice
  2. 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 Now a Download Plan!
  3. 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
  4. 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. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

Issues while communicating to Arduino

Discussion in 'DIY Motion Simulator Building Q&A / FAQ' started by Tintin Boulsard, Feb 7, 2024.

  1. early_m

    early_m Active Member

    Joined:
    Jul 28, 2016
    Messages:
    320
    Location:
    Chelmsford
    Balance:
    826Coins
    Ratings:
    +345 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, Motion platform
    @yobuddy sorry to drag you into this bud, but it's a bit of R&d I'm doing and we could do with your expertise!

    As stated, serial monitor works, but in interface testing using the settings in the post above, we get either none, or erratic behaviour from the stepper motor (which stops when testing is stopped).

    I'm not going back to V2.....

    Any ideas would be hugely appreciated!
  2. early_m

    early_m Active Member

    Joined:
    Jul 28, 2016
    Messages:
    320
    Location:
    Chelmsford
    Balance:
    826Coins
    Ratings:
    +345 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, Motion platform
    Thanks for your input.

    I'm using a clone Arduino Uno, which I've been using with Simtools V3 for multiple projects, always works perfectly. As you can see I've requested the help of the guru
  3. Tintin Boulsard

    Tintin Boulsard Member

    Joined:
    Dec 23, 2022
    Messages:
    40
    Location:
    France
    Balance:
    152Coins
    Ratings:
    +17 / 0 / -0
    My Motion Simulator:
    3DOF, Arduino
    The code and the settings work perfectly fine for me...
    If what I told you above doesn't work, there's nothing more I can do for you. Maybe @yobuddy can solve your problem...

    Best regards,
    Tintin Boulsard
    Last edited: Feb 14, 2024
  4. early_m

    early_m Active Member

    Joined:
    Jul 28, 2016
    Messages:
    320
    Location:
    Chelmsford
    Balance:
    826Coins
    Ratings:
    +345 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, Motion platform
    This sorted the issue for me - thanks
    • Like Like x 1
  5. Tintin Boulsard

    Tintin Boulsard Member

    Joined:
    Dec 23, 2022
    Messages:
    40
    Location:
    France
    Balance:
    152Coins
    Ratings:
    +17 / 0 / -0
    My Motion Simulator:
    3DOF, Arduino
    That's perfect!
    Do not hesitate to try different stepper configurations, maybe you'll find one that works even better...

    Best regards,
    Tintin Boulsard
  6. early_m

    early_m Active Member

    Joined:
    Jul 28, 2016
    Messages:
    320
    Location:
    Chelmsford
    Balance:
    826Coins
    Ratings:
    +345 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, Motion platform
    Yeah I'll have a play around

    Will you be publishing code for 2 motors?
  7. Tintin Boulsard

    Tintin Boulsard Member

    Joined:
    Dec 23, 2022
    Messages:
    40
    Location:
    France
    Balance:
    152Coins
    Ratings:
    +17 / 0 / -0
    My Motion Simulator:
    3DOF, Arduino
    Of course I will! I had planned to modify the code for 4 motors, but can do for 2 motors if you want.
    Actually, I'm not at my home for 4 days, so I don't have my computer and steppers to test the code. I can anyway modify it on my phone, but can't be shure it will run properly.

    Can I ask you what are you building with the steppers? I saw that you previously built a 2DOF motion simulator and then upgraded it to 3DOF. Impressive....

    Best regards,
    Tintin Boulsard
    • Friendly Friendly x 1
  8. early_m

    early_m Active Member

    Joined:
    Jul 28, 2016
    Messages:
    320
    Location:
    Chelmsford
    Balance:
    826Coins
    Ratings:
    +345 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, Motion platform
    Please, do not rush on account of me, I'm in no hurry! I've got lots of testing I can do with one motor.
    I'm looking to see if steppers are a viable option for a gseat
  9. Tintin Boulsard

    Tintin Boulsard Member

    Joined:
    Dec 23, 2022
    Messages:
    40
    Location:
    France
    Balance:
    152Coins
    Ratings:
    +17 / 0 / -0
    My Motion Simulator:
    3DOF, Arduino
    Hi @early_m,
    I'm testing my code again and again... Unfortunately, I'm having the same issue as you : the motor moves randomly. It works well in the Serial Monitor, but not perfectly in Simtools, I can adjust the slider slowly but no fast movements either it rotates in multiple directions fastly. I opened a thread here.
    I'm going to modify it for your 2 axis but I won't be able to test it properly...

    Best regards,
    Tintin Boulsard
  10. early_m

    early_m Active Member

    Joined:
    Jul 28, 2016
    Messages:
    320
    Location:
    Chelmsford
    Balance:
    826Coins
    Ratings:
    +345 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, Motion platform
    It's almost like the motors can not keep up with the positional data being sent to them. I am finding that if the scale is turned down to 1600 they work without issue. For my testing requirements this is ok, so a 2 motor version of the sketch would be fantastic. Thanks in advance
  11. Tintin Boulsard

    Tintin Boulsard Member

    Joined:
    Dec 23, 2022
    Messages:
    40
    Location:
    France
    Balance:
    152Coins
    Ratings:
    +17 / 0 / -0
    My Motion Simulator:
    3DOF, Arduino
    Here is the version for 2 motors :
    Code:
    #include <BasicStepperDriver.h>
    
    //------------------------- Can be modified --------------------------//
    #define STEP_M1 3
    #define DIR_M1 4
    #define STEP_M2 3
    #define DIR_M2 4
    #define RPM 120
    #define MICROSTEPS 16
    #define MOTOR_STEPS 200
    //#define DEBUG 1
    //--------------------------------------------------------------------//
    
    BasicStepperDriver M1(MOTOR_STEPS, DIR_M1, STEP_M1);
    BasicStepperDriver M2(MOTOR_STEPS, DIR_M2, STEP_M2);
    const int kActuatorCount = 2;
    const char kActuatorName[kActuatorCount] = {'R', 'L'};
    const int kActuatorScale[kActuatorCount][2] = { { -10000, 10000 }, { 10000, -10000 } };
    const char kEOL = '~';
    const int kMaxCharCount = 3;
    int actuatorPosition[kActuatorCount] = {0, 0};
    int actuatorPosition2[kActuatorCount] = {0, 0};
    int currentActuator;
    int valueCharCount = 0;
    int remember[kActuatorCount] = {0, 0};
    enum TPortState { psReadActuator, psReadValue };
    TPortState currentState = psReadActuator;
    
    void setup(){
      Serial.begin(9600);
      M1.begin(RPM, MICROSTEPS);
      M1.begin(RPM, MICROSTEPS);
    }
    void loop(){}
    void serialEvent(){
        char tmpChar;
        int tmpValue;
    
        while (Serial.available()) {
            if (currentState == psReadActuator) {
                tmpChar = Serial.read();
     
    #ifdef DEBUG           
    Serial.print("Read in : ");           
    Serial.println(tmpChar);           
    #endif
    
                for (int i = 0; i < kActuatorCount; i++) {
                    if (tmpChar == kActuatorName[i]) {
    
    #ifdef DEBUG           
    Serial.print("Which is defined as : ");           
    Serial.println(i);           
    #endif
    
                        currentActuator = i;
                        currentState = psReadValue;             
                        actuatorPosition[currentActuator] = 0;
                        valueCharCount = 0;         
                        break;
                    }
                }
            }
          
            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 (tmpValue == kEOL || valueCharCount == kMaxCharCount) {
    
    #ifdef DEBUG           
    Serial.print("Read position : ");           
    Serial.println(actuatorPosition[currentActuator]);           
    #endif
    
    
                    actuatorPosition[currentActuator] = map(actuatorPosition[currentActuator], 0, 255, kActuatorScale[currentActuator][0], kActuatorScale[currentActuator][1]);
    #ifdef DEBUG           
    Serial.print("Scaled to ");           
    Serial.println(actuatorPosition[currentActuator]); 
    #endif
    
    actuatorPosition2[currentActuator] = actuatorPosition[currentActuator] - remember[currentActuator];
    remember[currentActuator] = actuatorPosition[currentActuator];
                    updateActuator();
                    currentState = psReadActuator;
                }
            }
        }
    }
    
    void updateActuator() {
        M1.rotate(actuatorPosition2[0]);
        M2.rotate(actuatorPosition2[1]);
    }
    
    /* For more precision, replace the entire "void updateActuator()" by the following :
    
    
    void updateActuator() {
        M1.move(actuatorPosition2[0]);
        M2.move(actuatorPosition2[1]);
    }
    
    
    */
    Please read what I wrote at the end of the code.
    Thank you for your reply, I will try the '1600' micro stepping. I will also try adding delay before the next move, which will correspond to the time that takes the motor to execute the actual move. Maybe that will solve the problem...

    Best regards,
    Tintin Boulsard
  12. early_m

    early_m Active Member

    Joined:
    Jul 28, 2016
    Messages:
    320
    Location:
    Chelmsford
    Balance:
    826Coins
    Ratings:
    +345 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, Motion platform
    Thanks so much, I look forward to testing this out.

    To be clear, it wasn't changing micro stepping settings it was this

    Code:
    const int kActuatorScale[kActuatorCount][2] = { { -1600, 1600 }, { 1600, -1600 } };
  13. early_m

    early_m Active Member

    Joined:
    Jul 28, 2016
    Messages:
    320
    Location:
    Chelmsford
    Balance:
    826Coins
    Ratings:
    +345 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, Motion platform
    I have updated the code as there where some issues with it. It is working for me, although I have had to reduce scaling to 400, which is only about 1/2 a turn (fine for my use case). So it still needs some work to become reliable and viable for most requirements. If anyone with some knowledge could shed some light that wouldbe most appreciated.

    Code:
    #include <BasicStepperDriver.h>
    
    //------------------------- Can be modified --------------------------//
    #define STEP_M1 3
    #define DIR_M1 4
    #define STEP_M2 5
    #define DIR_M2 6
    #define RPM 1000
    #define MICROSTEPS 16
    #define MOTOR_STEPS 200
    //#define DEBUG 1
    //--------------------------------------------------------------------//
    
    BasicStepperDriver M1(MOTOR_STEPS, DIR_M1, STEP_M1);
    BasicStepperDriver M2(MOTOR_STEPS, DIR_M2, STEP_M2);
    
    const int kActuatorCount = 2; //Number of actuators
    const char kActuatorName[kActuatorCount] = {'R', 'L'};
    const int kActuatorScale[kActuatorCount][2] = { { -400, 400 }, { 400, -400 } }; //Scaling, where 1000 is the range
    const char kEOL = '~';
    const int kMaxCharCount = 3;
    int actuatorPosition[kActuatorCount] = {0, 0};
    int actuatorPosition2[kActuatorCount] = {0, 0};
    int currentActuator;
    int valueCharCount = 0;
    int remember[kActuatorCount] = {0, 0};
    enum TPortState { psReadActuator, psReadValue };
    TPortState currentState = psReadActuator;
    
    void setup(){
      Serial.begin(9600);
      M1.begin(RPM, MICROSTEPS);
      M2.begin(RPM, MICROSTEPS);
    }
    void loop()
    {
    }
    
    void serialEvent(){
        char tmpChar;
        int tmpValue;
    
        while (Serial.available()) {
            if (currentState == psReadActuator) {
                tmpChar = Serial.read();
     
    #ifdef DEBUG           
    Serial.print("Read in : ");           
    Serial.println(tmpChar);           
    #endif
    
                for (int i = 0; i < kActuatorCount; i++) {
                    if (tmpChar == kActuatorName[i]) {
    
    #ifdef DEBUG           
    Serial.print("Which is defined as : ");           
    Serial.println(i);           
    #endif
    
                        currentActuator = i;
                        currentState = psReadValue;             
                        actuatorPosition[currentActuator] = 0;
                        valueCharCount = 0;         
                        break;
                    }
                }
            }
          
            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 (tmpValue == kEOL || valueCharCount == kMaxCharCount) {
    
    #ifdef DEBUG           
    Serial.print("Read position : ");           
    Serial.println(actuatorPosition[currentActuator]);           
    #endif
    
    
    actuatorPosition[currentActuator] = map(actuatorPosition[currentActuator], 0, 255, kActuatorScale[currentActuator][0], kActuatorScale[currentActuator][1]);
    #ifdef DEBUG           
    Serial.print("Scaled to ");           
    Serial.println(actuatorPosition[currentActuator]);
    #endif
    
    actuatorPosition2[currentActuator] = actuatorPosition[currentActuator] - remember[currentActuator];
    remember[currentActuator] = actuatorPosition[currentActuator];
                    updateActuator();
                    currentState = psReadActuator;
                }
            }
        }
    }
    
    
    
    
    void updateActuator() {
        M1.move(actuatorPosition2[0]);
        M2.move(actuatorPosition2[1]);
    }
    
  14. early_m

    early_m Active Member

    Joined:
    Jul 28, 2016
    Messages:
    320
    Location:
    Chelmsford
    Balance:
    826Coins
    Ratings:
    +345 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, Motion platform
  15. Tintin Boulsard

    Tintin Boulsard Member

    Joined:
    Dec 23, 2022
    Messages:
    40
    Location:
    France
    Balance:
    152Coins
    Ratings:
    +17 / 0 / -0
    My Motion Simulator:
    3DOF, Arduino
    Hi,
    I haven't tested reducing the scale yet but, when increasing the RPM, I don't have random movements anymore.
    I had checked the StepperDriver library's keywords, and had found the rotate function, that can be used if you don't need a precise movement, that ends on the exact needed step. An error message concerning the rotate function appeared but after a few tests, there was no error anymore, I don't know why, and that was working great. So just keep the move function, rotate is not reliable...
    Unfortunately, I'm not sure that the code can be upgraded a lot. I found a thread where someone has the same issue : his stepper turns randomly, but he is using a different code, with another library as motor controller. The only thing the codes have in common is that they are based on @eaorobbie's code. So, either the issue is comming from steppers : "It could be that by their functional nature a stepper is challenging" (what @noorbeast said), or the code. I think it is the first option... Let me know your point of view.
    Lastly, I don't want to criticize @eaorobbie's job. He did an awesome job, and we couldn't be here without him.

    Best regards,
    Tintin Boulsard
  16. Tintin Boulsard

    Tintin Boulsard Member

    Joined:
    Dec 23, 2022
    Messages:
    40
    Location:
    France
    Balance:
    152Coins
    Ratings:
    +17 / 0 / -0
    My Motion Simulator:
    3DOF, Arduino
    I just wanted to add that, before modifying the code using the StepperDriver library, I tested one that uses the AccelStepper libray, but the motor was never going backward. Impossible to make it turn in the opposite direction...
  17. Tintin Boulsard

    Tintin Boulsard Member

    Joined:
    Dec 23, 2022
    Messages:
    40
    Location:
    France
    Balance:
    152Coins
    Ratings:
    +17 / 0 / -0
    My Motion Simulator:
    3DOF, Arduino
    Hi @early_m,
    I have a list of things to do :
    1. I'm going to test adding delay between each move. This is what @Lebois did when he used steppers, and he succeed to drive them without problem.
    2. If this doesn't work, I'll write the entire code myself, instead of using @eaorobbie's code as base.
    3. I'll test again the code published by @Lebois for the SRT100, and also the one used for the SRT80, which is almost the same, even a little bit more developed. I previously tested it, but it didn't work. Maybe adjusting the sketch would make it work...

    I hope our problem will be solved soon,
    Best regards,
    Tintin Boulsard
  18. Tintin Boulsard

    Tintin Boulsard Member

    Joined:
    Dec 23, 2022
    Messages:
    40
    Location:
    France
    Balance:
    152Coins
    Ratings:
    +17 / 0 / -0
    My Motion Simulator:
    3DOF, Arduino
    Problem fixed!
    I'm so delighted that my actuators work!!!
    1. I added delay : no random movements anymore. Totally fixed! I'll share you the code.
    2. I tested Lebois' code, and with some modifications, it worked! The adventage of his code is that the motors are not noisy, because unlike the StepperDriver libray, it doesn't stop at each step. As we receive datas every 1-50 ms, the controller which is the library, moves stepper and stop it. Lebois' code doesn't work like that, it doesn't stop at each step. We could still modify the library in the "%USERPROFILE%/Documents/Arduino/libraries/" folder and remove the stop function but it is more complicated...

    Which one do you prefer?

    Best regards,
    Tintin Boulsard
    • Like Like x 1
    • Winner Winner x 1
  19. early_m

    early_m Active Member

    Joined:
    Jul 28, 2016
    Messages:
    320
    Location:
    Chelmsford
    Balance:
    826Coins
    Ratings:
    +345 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, Motion platform
    Well done! That's great news!

    Would you mind sharing both codes so that I can do my own testing?

    Thanks
  20. Tintin Boulsard

    Tintin Boulsard Member

    Joined:
    Dec 23, 2022
    Messages:
    40
    Location:
    France
    Balance:
    152Coins
    Ratings:
    +17 / 0 / -0
    My Motion Simulator:
    3DOF, Arduino
    Here are the codes :
    Code:
    #include <BasicStepperDriver.h>
    
    //------------------------- Can be modified --------------------------//
    #define STEP_M1 3
    #define DIR_M1 4
    #define STEP_M2 5
    #define DIR_M2 6
    #define RPM 1000
    #define MICROSTEPS 2
    #define MOTOR_STEPS 200
    #define DELAY 5
    //#define DEBUG 1
    //--------------------------------------------------------------------//
    
    BasicStepperDriver M1(MOTOR_STEPS, DIR_M1, STEP_M1);
    BasicStepperDriver M2(MOTOR_STEPS, DIR_M2, STEP_M2);
    
    const int kActuatorCount = 2; //Number of actuators
    const char kActuatorName[kActuatorCount] = {'R', 'L'};
    const int kActuatorScale[kActuatorCount][2] = { { -1600, 1600 }, { 1600, -1600 } }; //Scaling, where 1000 is the range
    const char kEOL = '~';
    const int kMaxCharCount = 3;
    int actuatorPosition[kActuatorCount] = {0, 0};
    int actuatorPosition2[kActuatorCount] = {0, 0};
    int currentActuator;
    int valueCharCount = 0;
    int remember[kActuatorCount] = {0, 0};
    enum TPortState { psReadActuator, psReadValue };
    TPortState currentState = psReadActuator;
    
    void setup(){
      Serial.begin(9600);
      M1.begin(RPM, MICROSTEPS);
      M2.begin(RPM, MICROSTEPS);
    }
    void loop()
    {
    }
    
    
    void serialEvent(){
        char tmpChar;
        int tmpValue;
    
        while (Serial.available()) {
            if (currentState == psReadActuator) {
                tmpChar = Serial.read();
     
    #ifdef DEBUG          
    Serial.print("Read in : ");          
    Serial.println(tmpChar);          
    #endif
    
                for (int i = 0; i < kActuatorCount; i++) {
                    if (tmpChar == kActuatorName[i]) {
    
    #ifdef DEBUG          
    Serial.print("Which is defined as : ");          
    Serial.println(i);          
    #endif
    
                        currentActuator = i;
                        currentState = psReadValue;            
                        actuatorPosition[currentActuator] = 0;
                        valueCharCount = 0;        
                        break;
                    }
                }
            }
         
            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 (tmpValue == kEOL || valueCharCount == kMaxCharCount) {
    
    #ifdef DEBUG          
    Serial.print("Read position : ");          
    Serial.println(actuatorPosition[currentActuator]);          
    #endif
    
    
    actuatorPosition[currentActuator] = map(actuatorPosition[currentActuator], 0, 255, kActuatorScale[currentActuator][0], kActuatorScale[currentActuator][1]);
    #ifdef DEBUG          
    Serial.print("Scaled to ");          
    Serial.println(actuatorPosition[currentActuator]);
    #endif
    
    actuatorPosition2[currentActuator] = actuatorPosition[currentActuator] - remember[currentActuator];
    
                    delay(DELAY);
                    updateActuator();
                    currentState = psReadActuator;
                    delay(DELAY);
                    remember[currentActuator] = actuatorPosition[currentActuator];
                }
            }
        }
    }
    
    
    
    
    void updateActuator() {
        M1.move(actuatorPosition2[0]);
        M2.move(actuatorPosition2[1]);
    }
    
    Code:
    // www.lebois-racing.fr/en
    // For Uno only
    
    // WIRING : IT CAN'T BE CHANGED. SAME AS OPENSFX100
    #define StepPin1  8
    #define StepPin2  9
    #define StepPin3  10
    #define StepPin4  11
    
    #define DirPin1   4
    #define DirPin2   5
    #define DirPin3   6
    #define DirPin4   7
    
    #define RelayPin  A0 //used to control the PSU thougth a relay
    
    #define pulseDelay 7     // mostly set the speed of the actuator : the lower the faster. Don't go below 6 or it will fail.
    #define directionDelay 7
    
    byte buffer           = 0 ;    // It takes the value of the serial data
    byte buffercount      = 0 ;    // To count where we are in the serial datas
    byte commandbuffer[8] = {0};   // To stock the serial datas in the good order.  
    
    unsigned m1Target = 0,   m2Target = 0,   m3Target = 0,   m4Target = 0;
    unsigned m1Position = 0, m2Position = 0, m3Position = 0, m4Position = 0;
    byte pulseM1 = B00000000, pulseM2 = B00000000, pulseM3 = B00000000, pulseM4 = B00000000;
    int  dir1 = -1, dir2 = -1, dir3 = -1, dir4 = -1;         //Will be used to set the motors direction
    byte dirChange = 0;
    bool noData = true;
    bool servoEnabled = true;
    
    void setup() {
      Serial.begin(9600);    //To communicate with FlyPT. In FlyPT, put that number in "Serial speed".
    
      pinMode(RelayPin, OUTPUT);
     
    
      pinMode(StepPin1, OUTPUT);
      pinMode(DirPin1, OUTPUT);
      digitalWrite(DirPin1, HIGH);
    
      pinMode(StepPin2, OUTPUT);
      pinMode(DirPin2, OUTPUT);
      digitalWrite(DirPin2, HIGH);
    
      pinMode(StepPin3, OUTPUT);
      pinMode(DirPin3, OUTPUT);
      digitalWrite(DirPin3, HIGH);
    
      pinMode(StepPin4, OUTPUT);
      pinMode(DirPin4, OUTPUT);
      digitalWrite(DirPin4, HIGH);
    
    
    }
    
    void loop() {
      SerialReader();                     //Get the datas from Simtools
      moveMotor();                        //Move the motors
    }
    
    void SerialReader() {       // FlyPT output : P<Axis1a><Axis2a><Axis3a><Axis4a>, Data bits : 8 bits, Parity : None, stop bits : 1
      while (Serial.available())
      {
        if (buffercount == 0)
        {
          buffer = Serial.read();
    
                if (buffer != 'P') {  
                         
            buffercount = 0; // "S" is the marquer. If we read P, the next data is Motor1
          } else {
            buffercount = 1;
          }
        }
        else   //  if(buffercount>=1)
        {
          buffer = Serial.read();
          commandbuffer[buffercount-1] = buffer; // The first value next to "P" is saved in commandbuffer in the place "buffercount"
          buffercount++;
          if (buffercount >= 9) {
              m1Target = commandbuffer[0] * 256 + commandbuffer[1];      //because the communication is 8bits, and the data are 16 bits, their is two bytes to combine
              m2Target = commandbuffer[2] * 256 + commandbuffer[3];
              m3Target = commandbuffer[4] * 256 + commandbuffer[5];
              m4Target = commandbuffer[6] * 256 + commandbuffer[7];
              buffercount = 0;
            break;
          }
        }
      }
    }
    
    
    void moveMotor() {
      directionManager(); //set the directions of each motor
      singleStep(); //make the motor move one step
    }
    
    void directionManager() {
    
      if ((m1Target > m1Position) && (dir1 == -1)) {
        PORTD &= B11101111;
        dir1 = 1;
        dirChange = 1;
      }
    
      if ((m1Target < m1Position ) && (dir1 == 1)) {
        PORTD |= B00010000;
        dir1 = -1;
        dirChange = 1;
      }
    
      if ((m2Target > m2Position) && (dir2 == -1)) {
        PORTD &= B11011111;
        dir2 = 1;
        dirChange = 1;
      }
     
      if ((m2Target < m2Position ) && (dir2 == 1)) {
        PORTD |= B00100000;
        dir2 = -1;
        dirChange = 1;
      }
    
      if ((m3Target > m3Position) && (dir3 == -1)) {
        PORTD &= B10111111;
        dir3 = 1;
        dirChange = 1;
      }
     
      if ((m3Target < m3Position ) && (dir3 == 1)) {
        PORTD |= B01000000;
        dir3 = -1;
        dirChange = 1;
      }
    
      if ((m4Target > m4Position) && (dir4 == -1)) {
        PORTD &= B01111111;
        dir4 = 1;
        dirChange = 1;
      }
     
      if ((m4Target < m4Position ) && (dir4 == 1)) {
        PORTD |= B10000000;
        dir4 = -1;
        dirChange = 1;
      }
     
      if (dirChange == 1) {
        delayMicroseconds(directionDelay);
        dirChange = 0;
      }
    }
    
    void singleStep() {
      //pulse is 8, 9, 10, 11
      if (m1Target != m1Position) {
        pulseM1 = B00000001;
        m1Position += dir1;
      }
      else{pulseM1 = B00000000;}
     
      if (m2Target != m2Position) {
        pulseM2 = B00000010;
        m2Position += dir2;
      }
      else{pulseM2 = B00000000;}
       
      if (m3Target != m3Position) {
        pulseM3 = B00000100;
        m3Position += dir3;
      }
      else{pulseM3 = B00000000;}
    
      if (m4Target != m4Position) {
        pulseM4 = B00001000;
        m4Position += dir4;
      }
      else{pulseM4 = B00000000;}
       
      if((pulseM1 == B00000000) && (pulseM2 == B00000000) && (pulseM3 == B00000000) && (pulseM4 == B00000000)){return;}
          PORTB |= pulseM1 | pulseM2 | pulseM3 | pulseM4;
          delayMicroseconds(pulseDelay);
          PORTB &= B11110000;
    }
    This is Lebois code for 4 motors. The wiring can't be change unfortunately, otherwise it won't work.
    • Winner Winner x 1
    Last edited: Feb 22, 2024