Go Down

Topic: Stepper motors don't go as fast as they should. (Read 687 times) previous topic - next topic

Robin2

I send the 31 processing data 1 frame out of 6 to the serial port of the Arduino.
I have 30 frame in one sec, so I send position 5 time in one seconde.
Please provide a good description of the project you are trying to create. That will make it much easier to understand your comments.

As things stand phrases like "1 frame out of 6" mean nothing to me. What are "frames"? Why have you got 30 in one second? These are all things I can't understand without an overall description of the project. At the moment this is a typical XY Problem.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

MarkT

Do you have a feel for how often run() is being called for each motor?  If you want fast stepping that
number really needs to be up in the high thousands or even 10's of thousands calls a second per motor.
AccelStepper can only send step pulses as often as run() is called.   As it uses floats it will be struggling
with lots of motors.

Have you thought to try with just one motor, then 2, then 4, to see if this is simply a scalability problem?
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

bvking

#17
Sep 09, 2020, 08:04 pm Last Edit: Sep 09, 2020, 08:16 pm by bvking
Please provide a good description of the project you are trying to create. That will make it much easier to understand your comments.
 
...R
The speed of my animation depends on the number of "refreshed photo" (frame) in one second.
Contrary to the speed of a film in the cinema, if we put 1 or 24 frames per second, the speed of the animation is the same, but the film appears jerky and not smooth.

In my Processing program, if I update the frame once per second, then the animation will run 30 times slower.

I made a video here trying to explain it to you with my bad accent. HERE.

My problem is if I reduce the number of data refreshed in one seconde, my animation goes slower.

When I send 31 data every two frame, my motors don't run more smoothly .

So for the moment, I really need to send the 31 data from Processing to the Arduino 30 times per second. Hope all of this information can help you.

Thank you sincerely.

bvking

#18
Sep 09, 2020, 08:20 pm Last Edit: Sep 09, 2020, 08:32 pm by bvking
Do you have a feel for how often run() is being called for each motor?  If you want fast stepping that
number really needs to be up in the high thousands or even 10's of thousands calls a second per motor.
AccelStepper can only send step pulses as often as run() is called.   As it uses floats it will be struggling
with lots of motors.

Have you thought to try with just one motor, then 2, then 4, to see if this is simply a scalability problem?
I send 31 int. Data come in the void loop and are use directly in the void loop.

Code: [Select]


void loop() {

   recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(tempChars, receivedChars);
            // this temporary copy is necessary to protect the original data
            //   because strtok() used in parseData() replaces the commas with \0
        parseData(); // 31 datas marked and separated with a coma.  
        showPosition();
   //     showPhazisScaled();
   //     showTrigBangWithRevolution();
      
        newData = false;
    }

      
    
       stepper[9].moveTo(PC0);
       stepper[9].run();
       stepper[8].moveTo(PC1);
       stepper[8].run();      
       stepper[7].moveTo(PC2);
       stepper[7].run();
       stepper[6].moveTo(PC3);
       stepper[6].run();
       stepper[5].moveTo(PC4);  
       stepper[5].run();

  
       stepper[4].moveTo(PC5);
       stepper[4].run();
       stepper[3].moveTo(PC6);
       stepper[3].run();      
       stepper[2].moveTo(PC7);
       stepper[2].run();
       stepper[1].moveTo(PC8);
       stepper[1].run();
       stepper[0].moveTo(PC9);  
       stepper[0].run();
  
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

//============

void parseData() {      // split the 31 data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars,",");      // get the first part - the string
 
    integerFromPC0 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC1 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC2 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC3 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC4 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC5 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC6 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC7 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC8 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC9 = atoi(strtokIndx);     // convert this part to an integer

    
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PC0 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PC1 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PC2 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PC3 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PC4 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PC5 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PC6 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PC7 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PC8 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PC9 = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PCTer0 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PCTer1 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PCTer2 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PCTer3 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PCTer4 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PCTer5 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PCTer6 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PCTer7 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PCTer8 = atoi(strtokIndx);     // convert this part to an integer
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    PCTer9 = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    orderCohesion  = atoi(strtokIndx); // convert this part to an integer
 
}


 
Have you thought to try with just one motor, then 2, then 4, to see if this is simply a scalability problem?
You want to mean, I keep on receiving 31 data in one seconde, but I control only one motor, then two...?

I will try this or an other advice it in 24 h. Thanks  :)

Robin2

I have watched your video but I'm still at a loss to understand the system. Your video shows coloured lights on a screen but the problem seems to be about stepper motors.

Please try to describe the thing that you want to create rather than the problem you are having. If we have a good understanding of the project we may be able to suggest a different approach from what you have in mind.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

bvking

I have watched your video but I'm still at a loss to understand the system. Your video shows coloured lights on a screen but the problem seems to be about stepper motors.

Please try to describe the thing that you want to create rather than the problem you are having. 

...R
In animation, the faster the balls turn, the more the position between each image or "frame" increases.

When I send only the position of a ball to 1 or 10 motors, the motors go much faster (10 turns in 5 seconds) than if I send the 10 different positions to 10 motors (10 turns in 9 seconds).


On the other hand if I send 31 data the motors make 10 turns in 10 s, the difference with 10 data is not great

So I have a data saturation issue being received by the Arduino board, I imagine?

Robin2

#21
Sep 11, 2020, 03:17 pm Last Edit: Sep 11, 2020, 03:18 pm by Robin2
If you are not prepared to describe the thing you are trying to create (as requested in Replies #19 and #15) I'm not going to be able to help.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

bvking

I'm trying to drive my stepper at 2 rounds in one sec.

I need in a normal driving 200 step to make one revolution
I have found a solution by doing 800 step in on round, and not 1600 as before.
I set my driver at 1/4 step, and not 1/8 step.

It's quite good but my motor make more noise and I lost precision but I go down the acceleration it's quite good.

Robin2

I'm trying to drive my stepper at 2 rounds in one sec.
I know that.

But I need to see a good description of the project in which the stepper is being used so I can visualize what you are making and understand your questions in context. This is the last time of asking.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

bvking

I know that.

But I need to see a good description of the project in which the stepper is being used so I can visualize what you are making and understand your questions in context. This is the last time of asking.

...R
I just put on youtube an old video where you can see the animation with 5 motors driven frame by frame.
HERE.


Stepper motor animations and drivers have been tuned to 200 steps / revolution.

It was very nice because it was very fast and the movement was very wide, but 30 seconds after the start I lost precision.

Now I am setting 800 steps / rev which is good but not as precise as 1600 steps / rev (with this setup I also gain power). The problem is that with 1600 steps / revolution, my motors do not go above one revolution / sec.

 I hope I have been a little clearer. Otherwise, thank you already for all the help you gave me.


Have a good day.

 

Robin2

I just put on youtube an old video where you can see the animation with 5 motors driven frame by frame.
The video gives me an idea of what the stepper motors are trying to achieve but I can't relate that to the problem you are having with your code.

All you keep telling us is how many steps or frames you are achieving, but you are not explaining the project in a way from which I might be able to say X seems to be an unnecessary waste of time OR it looks like an Arduino just isn't fast enough for what you want to do

Maybe you could simplify the description by assuming there is only a single stepper motor and then explain what data needs to be sent to it to make it move as you want.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up