Go Down

Topic: Controlling 2 stepper motors with limit switches - super 8 film scanner (Read 337 times) previous topic - next topic

td75

And what happens when you run the program and what do you want it to do that is different?
Only one stepper will move at a time - they both need to move simultaneously if limit switches are activated. Also when the stepper moves it's very slow/jerky.

Both steppers work in code shown in reply #11 but with slow down.

Quote
I think I would keep the tests for the limit switches separate from the tests for the the rewind situation. If a limit switch is triggered it means the system has reached a certain state - i.e. you know where the motor has got to. I know there is a degree of duplication if you have a variable called (for example) motorAtA which would be set to true when the limit switch is triggered but I think it is justified by making the logic clearer. if motorAtA == true then something needs to happen. When that something happens (i.e. motor starts moving towards B) it will probably set motorAtA back to false even though the limit switch may still be triggered.
Not sure how to keep tests separate? I have in the meantime removed the rewind option and only using the two limit switches, but still only one stepper moves at a time.

Do you have an example code using millis() for two steppers working simultaneously?

Slumpert

I am confused,

First,  without turning off the "reset" pin, the driver is going to try to "keep" that stepper motor in that exact arc. 

So if your other stepper motor is pulling on it (any direction), it's a tug of war between the two motors and the result will be full step "jerks" no matter what microsteping value it's set at. 

Second, the rotation speed of two reels winding a tape between them will vary as the tape buildup on the reel adjusts the "gear ratio" between them.  Even with a encoder tracking, it would be very difficult to control two stepper motors working together without the same "tug of war" game playing out and creating ripple strain all along your tape.

td75

I am confused,

First,  without turning off the "reset" pin, the driver is going to try to "keep" that stepper motor in that exact arc.  

So if your other stepper motor is pulling on it (any direction), it's a tug of war between the two motors and the result will be full step "jerks" no matter what microsteping value it's set at.  
When should I turn off the "reset" pin in the code?

Second, the rotation speed of two reels winding a tape between them will vary as the tape buildup on the reel adjusts the "gear ratio" between them.  Even with a encoder tracking, it would be very difficult to control two stepper motors working together without the same "tug of war" game playing out and creating ripple strain all along your tape.
There are tensioners on supply and take-up reel so this isn't a problem. As there is more tension the limit switch is activated, stepper turns and reduces tension.

Perhaps this will make it clearer to understand. There is actually a third stepper motor with film sprocket but this is controlled by the raspberry pi so not shown in image attached.


Slumpert

To turn off the driver, just set the resetpin low again after the step, your already turning it on every step.

Picture helps alot


Slumpert

I think the original code was better suited for this, your "tried" code and it's 25ms delay between steps seems wrong considering the limitswitches are the feedback control, not time.

Robin2

Only one stepper will move at a time - they both need to move simultaneously if limit switches are activated. Also when the stepper moves it's very slow/jerky.
Try this version
Code: [Select]

//Supply Reel DVR8825 Driver Pins (A)

byte stepPinA = 2;         // Define pin 2 as the steps pin
byte dirPinA = 3;          // Define pin 3 as the direction pin
byte limitSwitchPinA = 4;  // Define pin 4 for Limit Switch 1
byte resetPinA = 5;        // Pin 5 connected to RESET pin
byte M0A = 6;              // Define pin 6 as "M0"
byte M1A = 7;              // Define pin 7 as "M1"
byte M2A = 8;              // Define pin 8 as "M2"
byte rewindSwitchPinA = 9; // Define pin 9 for Switch for rewind

//Take-up Reel DVR8825 Driver Pins (B)

byte stepPinB = 10;        // Define pin 3 as the steps pin
byte dirPinB = 11;         // Define pin 4 as the direction pin
byte limitSwitchPinB = 12; // Define pin 12 for limit switch 2
byte resetPinB = 13;       // Define pin 13 connected to reset pin
byte M0B = 14;             // Define pin 14 as "M0"
byte M1B = 15;             // Define pin 15 as "M1"
byte M2B = 16;             // Define pin 16 as "M2"

boolean rewindSwitchAPressed = false;
boolean limitSwitchApressed = false;
boolean limitSwitchBpressed = false;

unsigned long curMillis;
unsigned long prevStepMillisA = 0;
unsigned long prevStepMillisB = 0;
unsigned long millisBetweenSteps = 25; // milliseconds

void setup() {

    //Supply Reel Setup
   
    pinMode(stepPinA, OUTPUT);        // Configures "STEP" as output
    pinMode(dirPinA, OUTPUT);         // Configures "DIR" as output
    pinMode(limitSwitchPinA, INPUT);  // Configures "limit switch" as input
    pinMode(resetPinA, OUTPUT);       // Configures reset pin as output
    pinMode(M0A, OUTPUT);             // Configures "M0" as output
    pinMode(M1A, OUTPUT);             // Configures "M1" as output
    pinMode(M2A, OUTPUT);             // Configures "M2" as output
    pinMode(rewindSwitchPinA, INPUT); // Configures "rewind switch" as input

    //Take-up Reel Setup
   
    pinMode(stepPinB, OUTPUT);       // Configures "STEP" as output
    pinMode(dirPinB, OUTPUT);        // Configures "DIR" as output
    pinMode(limitSwitchPinB, INPUT); // Configures "limit switch" as input
    pinMode(resetPinB, OUTPUT);      // Configures reset pin as output
    pinMode(M0B, OUTPUT);            // Configures "M0" as output
    pinMode(M1B, OUTPUT);            // Configures "M1" as output
    pinMode(M2B, OUTPUT);            // Configures "M2" as output
   
    digitalWrite(resetPinA, HIGH); // Turn on driver A
    digitalWrite(M0A, HIGH);       // Configures the steps division (1/32 step)
    digitalWrite(M1A, HIGH);       // As above
    digitalWrite(M2A, HIGH);       // As above
   
    digitalWrite(resetPinB, HIGH); // Turn on driver B
    digitalWrite(M0B, HIGH);       // Configures the steps division (1/32 step)
    digitalWrite(M1B, HIGH);       // As above
    digitalWrite(M2B, HIGH);       // As above
   
}

void loop() {

    curMillis = millis();
    readButtons();
    actOnButtons();
   
}

void readButtons() {

    rewindSwitchAPressed = false;
    limitSwitchApressed = false;
    limitSwitchBpressed = false;

    if (digitalRead(rewindSwitchPinA) == HIGH) {
        rewindSwitchAPressed = true;
    }
    if (digitalRead(limitSwitchPinA) == HIGH) {
        limitSwitchApressed = true;
    }
    if (digitalRead(limitSwitchPinB) == HIGH) {
        limitSwitchBpressed = true;
    }
   
}

void actOnButtons() {
   
    //~ if (rewindSwitchAPressed == true && limitSwitchApressed == false && limitSwitchBpressed == false) {
        //~ digitalWrite(resetPinA, HIGH); // Turn on driver A
        //~ digitalWrite(dirPinA, HIGH);   // Rotate clockwise 
        //~ digitalWrite(M0A, LOW);        // Configures the steps division (Full step)
        //~ digitalWrite(M1A, LOW);        // As above
        //~ digitalWrite(M2A, LOW);        // As above
        //~ singleStepA();
    //~ }
   
    if (limitSwitchApressed == true) {
        digitalWrite(dirPinA, LOW);    // Rotate anticlockwise
        singleStepA();
    }
   
    if (limitSwitchBpressed == true) {
        digitalWrite(dirPinB, LOW);    // Rotate anticlockwise
        singleStepB();
    }
   
}

void singleStepA() {
   
    if (curMillis - prevStepMillisA >= millisBetweenSteps) {
        prevStepMillisA = curMillis;
        digitalWrite(stepPinA, HIGH);
        digitalWrite(stepPinA, LOW);   
    }
   
}

void singleStepB() {
   
    if (curMillis - prevStepMillisB >= millisBetweenSteps) {
        prevStepMillisB = curMillis;
        digitalWrite(stepPinB, HIGH);
        digitalWrite(stepPinB, LOW);   
    }
   
}


I have moved some of the code into setup() but the main change I have made is to create separate prevStepMillis variable for each motor.

Separately, I find it very strange that you want the motors to move when the limit switches are pressed. In most cases the purpose of a limit switch is to stop a motor - and maybe signal the need for a change of direction.

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

td75

Still same jerky movements.

Thanks for your help with this but will use original code which is good enough for now.

Robin2

Still same jerky movements.

Thanks for your help with this but will use original code which is good enough for now.
If you are using the same timing variable for both motors that can't possibly be correct if you want both motors to be able to move at the same time, but independently.

There is some other problem that has not yet come to light.

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

td75

If you are using the same timing variable for both motors that can't possibly be correct if you want both motors to be able to move at the same time, but independently.
Sorry not sure I understand what you mean, can you please reiterate?

Quote
Separately, I find it very strange that you want the motors to move when the limit switches are pressed. In most cases the purpose of a limit switch is to stop a motor - and maybe signal the need for a change of direction.
Stepper motor will only move for a split second when limit switch is activated to create slack on film. Not sure how it can be used any other way for this setup?

I still can't figure out why there is slow down when both stepper motors are activated. Would it be better to run two Arduino boards at the same time (one for each stepper motor)?

Robin2

Sorry not sure I understand what you mean, can you please reiterate?
Study the code in my Reply #20. Note how I have prevStepMillisA and prevStepMillisB

Quote
Stepper motor will only move for a split second when limit switch is activated to create slack on film. Not sure how it can be used any other way for this setup?
I understand that. It is your use of the name 'limit switch' that I find strange. I think I would call it a slackSwitch or a takeUpSwitch

You certainly don't need two Arduinos. My 3D printer drives 4 motors with one Arduino.

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

Go Up