MobaTools, TB6600, and coordinating reversing stepper motor with unidirectional stepper motor

Unidirectional stepper motor means it only turns in one direction with my code. It is not about unipolar vs bipolar.

I've been slowly working through a guitar pickup winder. I'm using two bipolar stepper motors, MobaTools, and a couple of TB6600.

I've got the MobaTools and TB6600 working together with just one stepper motor, the one that would continually spin in one direction.

I have been unsuccessful in finding MobaTools examples that answer my questions. I tried. I did not just come here first.

The other stepper motor would operate a threaded rod to create linear motion, which needs to reverse direction after so many turns of the other stepper motor. This motor movement helps make the wire lay down evenly back and forth across the bobbin.

I'm very new to Arduino/C++, but not programming in general, and don't know how to work things in the Loop section of code to coordinate two motors. I'm not sure what the libraries will do in the background. I'm used to coding every damned thing myself when I code other things.

Either there is a slick way to coordinate the two motors, or I need to keep checking in the loop for whenever the main stepper has completed one revolution before it will move the motor on the linear drive a set amount, and then reverse the motor on the linear drive when it has completed X amount of steps.

Any pointers? I haven't debugged this code yet, and not sure of the respective speeds between the two motors. The winder motor will be doing full steps, the linear drive motor will be doing 1/4 steps. Not sure if I handle the 1/4 steps in the TB6600, MobaTools, or both.

I'm not going to be spinning the bobbin motor at maximum speed.

EDIT: I changed the code to convert all measurements to 10ths of a micrometer. 1/10,000,000. However, didn't seem to make a difference between that and a micrometer. I went that small because of my wire width and not wanting to truncate it too much since I'm avoiding floats.

EDIT TUESDAY: Ok, I've put my motor operation code in. It compiles, but I haven't tried it out yet. Just wondering if the way I've structured the loop() is what I need to do.

#include <MobaTools.h>
// Stepper connections - Please adapt to your own needs.
const byte stepPinBobbin = 3;
const byte dirPinBobbin = 2;

const byte stepPinServo = 5;
const byte dirPinServo = 4;

const long NumWindings = 6000;

const int stepsPerRevBobbin = 200;    // Steps per revolution - may need to be adjusted
const int stepsPerRevServo = 200;

byte direction = 1;

//Conversion multipliers to convert to micrometers/10
//All measurements are in micrometers / 10
long mm2mcm = 10000;
long in2mcm = 254000;

// pitch of the linear drive threaded rod, converted to micrometers/10
long linearDrivePitch = .8 * mm2mcm;


long linearMovementPerStepServo = linearDrivePitch/stepsPerRevServo;


long magnetLgt = 14*mm2mcm;

long plateThickness = long(.125*in2mcm);


float wireWidth = long(.0026*in2mcm); //42awg coated
long bobbinWidth =magnetLgt - (2*plateThickness);

long  wrapsPerWidth = long(bobbinWidth/wireWidth);
long  servoStepsPerWireWidth = wireWidth/linearMovementPerStepServo;
MoToStepper stepperBobbin( stepsPerRevBobbin, STEPDIR );  // create a stepper instance
MoToStepper stepperServo( stepsPerRevBobbin, STEPDIR );  // create a stepper instance for drive screw

void setup() {
  stepperBobbin.attach( stepPinBobbin, dirPinBobbin );
  stepperBobbin.setSpeed( 2000 );              
  stepperBobbin.setRampLen( stepsPerRevBobbin ); // Ramp length is 1 revolution

  stepperServo.attach(stepPinServo, dirPinServo);

  //servo requires 16 steps for a wire width.  Bobbin requires 200 steps for a whole wrap
  stepperServo.setSpeed(160);
  stepperServo.setRampLen(stepsPerRevServo);

  stepperBobbin.setZero();
  stepperServo.setZero();
  stepperBobbin.rotate(1);                    // start turning, 1=forward, -1=backwards 
  stepperServo.rotate(1);
  Serial.begin(9600);
  direction=1;

}

void loop() {

  stepperBobbin.writeSteps(NumWindings*stepsPerRevBobbin);

  if(stepperBobbin.moving()) {
    stepperServo.writeSteps(servoStepsPerWireWidth*wrapsPerWidth*direction);
    direction = direction * -1;
  }
  else {
    stepperServo.stop();
  }

  
}

Here is my output from the commented out println statements. Physical dimension values are in 10ths of a micrometer

linearDrivePitch = 8000

LinearMovementPerStepServo = 40

wireWidth= 660

bobbinWidth = 76500

wrapsPerWidth = 115

servoStepsPerWireWidth =16

//How to check if X steps have executed on bobbin motor without throwing things out of sync?

You can check at any time in loop() the position (in steps) of any of the motors. This does not influence the stepping of both motors.

//How to coordinate the speeds of the two motors during ramp up and ramp down?

In MobaTools there is no way to exactly coordinate the speed of two motors during ramp up/down so far.

//How to coordinate the two motors without ramp down and ramp up every time the direction changes on the linear drive motor?

What do you want to coordinate here? The linear drive motor must know when the end of the bobbin is reached and it has to reverse direction. I think the bobbin stepper still rotates the bobbin without stopping in that case?

A picture of your mechanics would be helpful.
Which Arduino are you using? I would recommend not to use float variables. Normally you can calculate everything here with int if you use the smallest relevant distance unit (e.g. 1/100 mm) as a basis.

I'm using Arduino Mega. Ok, gotcha on the floats. I don't think the bobbin motor needs to ramp up and down for each direction change of the linear drive motor. I just wanted to make sure that I didn't need to manually interrupt the bobbin motor, which would then require ramp up and down. Thanks for the rest. The power is not connected in this photo.

I'll repost my code in 10,000ths of a mm, since the wire width is .0026" and I have to resolve down to a number like that. I need to look at it for a while.

I've made some edits to the code. I haven't tested it with the motors yet. Just wondering if my logic regarding reversing the direction of the linear drive/servo (not a servo motor but a stepper motor) that I put in the loop() is how I need to do things?

I changed all the units to micrometer/10, since my wire diameter is .0026". I probably could have gotten away with just micrometer (1/1,000,000), since adding that extra 0 only added an extra zero to some of my measurements, not giving me finer resolution where I could recover non-zero digits.

And I doubt that your mechanics can position to an accuracy of 0.0001mm. Even 1µm is a challenge.

1 Like

Since the linear drive steps per wire width is 16 in this case, mathematically it's feasible. Now, slop in the actual physical mechanism could nullify that. And that fine of placement is not required here since the wire already laid down is going to be having an effect on where the newest wrap lays down, at least if the servo is lagging slightly behind.

But, it’s not the placement of any individual wrap I’m worried about, but the possible cumulative drift that could happen after thousands of windings.