# Two Potentiometers one Stepper Motor. 3 Problems! ££Reward

Hi All,

I’m looking for some help and will pay money for the help in creating a Sketch that covers the following.

I have.

2 10k pots
1 Nema 34 Bipolar Stepper Motor
1 MA860H Stepper Driver
1 Power supply
1 Ardunio Uno
3 Click Buttons
3 Resistors
wires etc

Layman understanding of Logic control and perameters not really Arduino related

Steps to Take per step CW or Step CCW = 50

Button 0 settings
RPM range / 250
Map range / (val 0, 1023, 0, 1023 )
Analog Resolution / 5
Delay Factor / 5

Button 1
RPM range / 150
Map range (val 0, 1023, 255, 767 )
Analog Resolution / 10
Delay Factor / 5

Button 2
RPM range / 50
Map range (val 0, 1023, 383, 640 )
Analog Resolution / 15
Delay Factor / 5

Logic path predicted based on button 1 being active selection

Step 1# Read PotA ( Value is ? out of 1023 )
Step 2# Read Which Button is active ( 0, 1, 2 )
Step 3# If button (1) is active then use map range (val 0, 1023, 255, 767 )
Step 4# Convert PotA value of ? to new map value.
Step 5# Check active buttons Analog Resolution ammount = (10)
Step 7# Compare PotA mapped value to PotB.
Step 8# Check if they are within the (10) digits of each other.
Step 9# If yes. Do nothing and run loop again from step 1.
Step 10# If No. Find out how much that value is.
Step 11# Take the Value and Multiply By ( Steps to Take ) to increase frame range of movement.
Step 11# Find out if it’s higher or Lower than PotA value.
Step 12# Send signal to Move Frame
Step 13# Take ammount of Steps and multiply by delay factor before starting loop again.

Arduino Sketch Something like this (But with correct language code if below is wrong?)

// Generic for all 3 options
int StepsToTake = 50; // Ammount of Steps to take per analog reading missmatch

// Low Setting
int LowRPM = 250; // RPM Value of Stepper Motor
int LowTrack = map ( 0, 1023, 0, 1023 ); // limiting physical range of frame to 1:1.
int LowRes = 20; // Amount of difference between PotA & PotB before stepper action is taken.
int LowPosAtoB = 3 // Amount of delay factor waiting for stepper to go from point A-B

// Med Setting ( This will be used in this example )
int MedRPM = 150; // RPM Value of Stepper Motor
int MedTrack = map ( 0, 1023, 255, 767 ); // limiting physical range of frame to 1:2.
int MedRes = 10; // Amount of difference between PotA & PotB before stepper action is taken.
int MedPosAtoB = 2 // Amount of delay factor waiting for stepper to go from point A-B

// High Setting
int HighRPM = 50; // RPM Value of Stepper Motor
int HighTrack = map ( 0, 1023, 383, 640 ); // limiting physical range of frame to 1:4.
int HighRes = 5; // Amount of difference between PotA & PotB before stepper action is taken.
int HighPosAtoB = 1 // Amount of delay factor waiting for stepper to go from point A-B

What should happen step by step in detail

1. Upon powering up there are 3 buttons. These buttons labelled Low, Med, High. When pressed define a range of numbers to be used later in the sketch. These Values will be used later for tweaking the physical functionality of the hardware. These setting should be the only thing adjusted within the sketch if possible ( assuming the rest of it is working ok ). The button could be pressed any time after power up so will need to be checked per loop. For the example and figures below I am going to imagine what should or could happen if the button was on the Medium Setting.

2. The first Potentiometer is within a hand held controller and adjustable. The knob is dampened so that it can’t be turned really quickly. It could take a second or two to fully rotate the knob within it’s 0-1023 range. This will be automated when final tweaking is complete and therefore automated in future, hence the reason for PotB.

3. The second Potentiometer is attached to a sliding frame that moves forwards and backward within a set physical range, giving an analog signal positional feedback from (0-1023) from full backwards to forward positions as per usual. ( Centre position would be calibrated to (512.5) )

4. The stepper is attached to the frame and drives the frame forwards and backwards, this done under instruction from the Sketch-Driver. The stepper motor is attached to a slip clutch so under heavy quick loads may slip or loose it’s position count. ( 2nd Reason for PotB )

5. If PotA analog raw reading from hand jog controller, for example is 247 out of the full 1023 range. The following int on button 1 should be called up “int = MedTrack map ( 0, 1023, 255, 767 );” in order to define a new figure.

1023 mapped and seen as a percentage is 10.23 positions per 1% so (247) potA reading is equal to 24.14% of the full range.

So if the Medium mapping is between (255 & 767) then this has a full range of only 512 within the (255, 767) range. And should if I’m correct give a figure where by it’s centre position is still 512 but the conversion dulls the amount of movement PotB needs to take to follow the figure, therefore keeping the frame centrally biased regardless of the map value.

So if 24.14% of the 512 range should give a new PotA position of (379) which means the frame will need to move a shorter amount from centre to match the PotA & PotB figures as per step 8.

It needs to work this way rather than just reduce the pot value by a fraction as I need the frame to be central when the PotA is central. if I just divide the 1023 value and apply this to the code the frame will be biased to the low end as the value isn’t relative to the central position.

1. In a bid to stop the Stepper jumping around trying to match PotA and PotB values perfectly within the (0-1023) range there needs to be some code that reduces the resolution of the (0-1023) signal so as to compare the values for our example in 10’s not 1’s, effectively having 102 positions. This figure should be adjustable via the button option as above ( int MedRes = 10; ) By increasing or decreasing the int MedRes figures I can compensate for the Mapping value changes from the Pot’s.

2. If PotA and PotB are within the same ( int MedRes = 10 ); value then it shouldn’t move the Motor. PotA might be the converted figure as per step 5) at (372), PotB might be (376) but the MedRes values are still within the Med set 10 range ( 5 either side of PotA ) and so don’t need to move.

8.) If PotA and PotB are however different, say PotA now reads (405) and potB still reads (376) then this difference should be converted and an appropriate signal of steps should be sent to the driver.

1. When the Stepper moves the frame assuming it hasn’t slipped on the way and PotB now matches the PotA figure of (405) or within 5 either way, PotA is read again and if still within the 10 signal reading it doesn’t move as per step 7). If it isn’t the same because PotA has moved again whilst the stepper has been moving then it repeats Step 8.

2. To allow the motor to “get there” an appropriate delay should be put in place after it sets off. This delay value should dynamically adjust based on how far PotA is to PotB and the motor needs to move. So under Medium settings if it needs to take 500 steps to get from A-B then the delay could be perhaps the step figure of 500 multiplied by the ( int MedPosAtoB = 2 ) so 1000 microseconds if it needs to travel 500 steps

Hopefully this will stop or at least minimise stuttering when it’s in motion as the programme loops and takes another reading from PotB to soon?

To consider are:

These values will be tweaked when the hardware is assembled as this part is not an exact science yet and timing, steps ect won’t be known…

Attachments:

1 wiring diagram showing my current board layout and current pin formation.

Cheers

Jason.

A bit confusing description ...
Can you describe the usage of the pots in simpler words?

What I require is a sketch that will send signals to the stepper motor to adjust the frame reading it's current position (according to pot B) and the position of the hand held slider (potA) so it attempts to match both pot val as close as possible with what the hand held pot position has been adjusted to.

That sounds pretty simple, actually, IF the potentiometer readings are stable and reliable.

If one reading is higher than the other, the stepper needs to move. Which value is higher defines the direction. The difference in values defines how many steps to take. Not that the number of steps really matters, since once you have stepped at all, you need to read both pots again.

The three buttons are needed to adust the ammount the frame moves ( motor steps ) in relation to potA ( 1/4, 1/2, Full ) which I can tweak the values if shown where this variable is on the sketch.

Do you mean 1/4 step, 1/2 step, or a full step? Or does 1/4 mean 1/4 of the frame length?

Does your driver support 1/4 stepping? If so, then a half step is just 2 1/4 steps and a full step is just 4 1/4 steps. I think you are over-complicating the situation with regards to the switches.

its worth noting that i don't need a particulary high resolution of step movments,

That's not what you started out saying, or what the 1/4 stepping requirement indicates.

This i'm hoping will stop the stepper motor bouncing around while it tries to match the 0-1023 resolution of the pots so closely.

Hysteresis will deal with that. Do nothing unless the difference exceeds some threshold.

I will try and answer your questions and provide as much clarity as possible to other comments.

1st quote)

Yes, assumung the loop gets to the point where it compares both pot values and they are both within a 0-10 position or has moved but still within the 0-10 comparison the stepper doesn't move. If however potA hasn't moved out of the 0-10 range of potB then then it's false and needs to compare how much difference that is ( could be now be 400 out ) and moves that ammount before taking another look.

2nd quote)

This is for the frame movment, PotA will still use the full range 0-1023 but I need the ammount the frame moves to be fractional. By taking the PotB position and reducing it's figure so when potA is all the way to the left, the frame only moves 1/4 of it's position from centre. When PotA is in the middle, so the frame moves to the middle and when potA is all the way over to the Right, again the frame moves 1/4 of its full range to the right. These three buttons set the 1:1 1:2 1:4 range of movment.

3rd quote)

The mention of a lower resoulution was in relation to the 1023-102.3 (more accurately) reduction of the 0-1023 signal the pot's give. Could this be mapped via: map(val ,0-1023,0,102) and worked with from there?
in reality the pots will give the full 0-1023 range but the sketch should reduce the resolution or actual frame positions down to around 102 positions from left to right.

4th quote)

Hysteresis shouldn't be a problem like you say if the loop takes the positional difference between pots, acts on it and then mabye waits for the stepper to get there with some kind of tweakable dynamic range based on the ammount the stepper motor has to move. So if the frame has to go from the left all the way over from the right it will take the range difference and work out a suitable delay before it re-reads the pot differences, if it's just a small fram movment it naturally reduces the delay. Hopefully it won't lag too much but a little lag is not a problem.

I will update the first post to reflect new posts.

Thanks again

Jason.

1. Ok, so when "full width" button is on, the cotroll pot pot will control the stepper across the full width of the frame. When 'quarter width' is on, the range of the control pot (1024) will select output values with a quarter of that range. This will do ... odd things. The code will have to treat wherever the frame was at the moment you hit the button as being the new center. It's do-able, of course, but you'll want a

2. why even bother with this sensing pot? The whole point of a stepper is that it counts the number of steps it takes. You move the mechanics to a center spot, indicate to your arduino that "ok, the motor is now centered", and from that point it computes where the frame is. The only way this can get unreliable is if you are using components that slip, or if the load is so strong that the stepper skips a notch.

3. The link you have provided does not match the set-up you are describing here. In the link, the input pots are controlling a horizontal and vertical etch-a-sketch arrangement; it's not the case that one is a controller and one a sensor.

4. I don't have the hardware you describe - the motor and driver. Is there a library for the driver so I can program to its public specification? I could write code that calls a pair of "move_up_one_step" and "move_down_one_step" functions that you would have to supply. the structure of the code would be

``````void loop() {
fiddle with indicator lights, buttons, etc;
work out where I want the sensor pot to be;
if the senbsor pot is too low
move_up_one_step() // this fuction supplied by you
else if the senbsor pot is too high
move_down_one_step() // this function supplied by you
else
do nothing;
}
``````

That is more or less do-able.

We can do this if you like. Are you comfortable with github?

(EDIT) PM Sent.

Hi,

PaulMurrayCbr:

1. Ok, so when "full width" button is on, the cotroll pot pot will control the stepper across the full width of the frame. When 'quarter width' is on, the range of the control pot (1024) will select output values with a quarter of that range. This will do ... odd things. The code will have to treat wherever the frame was at the moment you hit the button as being the new center. It's do-able, of course, but you'll want a

2. why even bother with this sensing pot? The whole point of a stepper is that it counts the number of steps it takes. You move the mechanics to a center spot, indicate to your arduino that "ok, the motor is now centered", and from that point it computes where the frame is. The only way this can get unreliable is if you are using components that slip, or if the load is so strong that the stepper skips a notch.

3. The link you have provided does not match the set-up you are describing here. In the link, the input pots are controlling a horizontal and vertical etch-a-sketch arrangement; it's not the case that one is a controller and one a sensor.

4. I don't have the hardware you describe - the motor and driver. Is there a library for the driver so I can program to its public specification? I could write code that calls a pair of "move_up_one_step" and "move_down_one_step" functions that you would have to supply. the structure of the code would be

``````void loop() {
``````

fiddle with indicator lights, buttons, etc;
work out where I want the sensor pot to be;
if the senbsor pot is too low
move_up_one_step() // this fuction supplied by you
else if the senbsor pot is too high
move_down_one_step() // this function supplied by you
else
do nothing;
}

``````

That is more or less do-able.

We can do this if you like. Are you comfortable with github?
``````
1. I appreciate its going to need some kind of conversion code that reads potA and reduces its value to lower the proposed movement depending on which button has been pressed, and therefore decrease the movement of the stepper. A trick if you will that gives a false reading of potA so that after this point in the loop it continues as if the factor was 1:1?

2. The Stepper will slip from time to time as it's on a clutch for short increased load bursts. If the frame slips I need the Motor to keep pushing in the direction until it matches pot values. A second Pot reading is the only thing I can think that will do this and maintain position?

3. The link to the sketch was just a side note to show how I have it hooked up to my breadboard. and that it was working. I understand the pots need to give signals to the stepper motor and not etch-a-sketch but it's as close to a full setup as I could find where all the hardware was being read correctly so thought it was a good area to start.

4. Thanks for the makings of the code, the more I talk about it and look into comments the more I feel I am understanding the concepts. I will update the first post to reflect all the comments.

Not sure how GitHub works or if it's required for the one off setup I need? what are the benefits?

Thanks again

Jason.

Jason187781:
Not sure how GitHub works or if it’s required for the one off setup I need? what are the benefits?

Ok. I think that the sketch I have so far should more-or-less do what you were after.

‘git’ is version control software, and ‘github’ is a public place that you can use as a repository for code. It’s a handy way to exchange code, although it’s usually overkill for arduino sketches.

The github repository is here GitHub - PaulMurrayCbr/arduino_topic_377515.

And the sketch itself is this:

``````// Sketch for Jason187781
// http://forum.arduino.cc/index.php?topic=377515

// comment this out to remove the DEV mockup
#define DEV
// comment this out to remove the printing to serial
// #define PRINT

const int NBUTTONS = 3;

struct ButtonAndLed {
const byte buttonPin;
const byte ledPin;
const int divisionFactor;
};

struct ButtonAndLed pinout[NBUTTONS] = {
{2, 5, 1}, // full speed button anbd indicator led
{3, 6, 2}, // half speed button anbd indicator led
{4, 7, 4}  // quarter speed button anbd indicator led
};

const byte sensorPotPin = A0;
const byte controlPotPin = A1;

#ifdef DEV
////////////////////////////////////////////////////////
// THIS BLOCK IS FOR TESTING AND DEVELOPMENT
//
// I don't have the hardware to properly demo this, so these
// stub functions must be provided by my client Jason187781.
////////////////////////////////////////////////////////

// in the real sketch, this gets removed.
int test_dev_frame_location = 0;

// in the real sketch, this will be replaced with
return test_dev_frame_location;
}

void moveStepperUp() {
// in the real sketch, this function must talk to the stepper controller
Serial.print(" UP ");
if (++test_dev_frame_location >= 1024) test_dev_frame_location = 1024;
}

void moveStepperDown() {
Serial.print(" DN ");
// in the real sketch, this function must talk to the stepper controller
if (--test_dev_frame_location <= 0) test_dev_frame_location = 0;
}

////////////////////////////////////////////////////////
// END OF TEST/DEV BLOCK
////////////////////////////////////////////////////////
#endif

int targetOffset = 0;
int currentSelection = 0;

void setup() {
#ifdef PRINT
///////////////// TEST/DEV //////////////
Serial.begin(57600);
while(!Serial);
#endif

for (int i = 0; i < NBUTTONS; i++) {
pinMode(pinout[i].buttonPin, INPUT_PULLUP);
pinMode(pinout[i].ledPin, OUTPUT);
}

digitalWrite(pinout[currentSelection].ledPin, HIGH);
}

void loop() {

// I unconditionally read the buttons. this means that
// while any button is being held down, nothing happens.
// you can use this to recenter the control pot if you want
for (int i = 0; i < NBUTTONS; i++) {
digitalWrite(pinout[currentSelection].ledPin, LOW);
currentSelection = i;
digitalWrite(pinout[currentSelection].ledPin, HIGH);
// pick values so that wherever the pots are right now
// becomes the new target once the button is released
targetOffset = sensor - (control / pinout[currentSelection].divisionFactor);
return;
}
}

int target = targetOffset + (control / pinout[currentSelection].divisionFactor);
target = constrain(target, 0, 1023);

// we permit a little slop to handle the fact that pots are a bit noisy
if (target < sensor-1) moveStepperDown();
else if (target > sensor+1) moveStepperUp();
else /* do nothing */ ;

#ifdef PRINT
Serial.print(" selection ");
Serial.print(currentSelection);
Serial.print(" control ");
Serial.print(control);
Serial.print(" targetOffset ");
Serial.print(targetOffset);
Serial.print(" target ");
Serial.print(target);
Serial.print(" sensor ");
Serial.print(sensor);
Serial.println();
delay(50);
#endif
}
``````

Press a button to select scale (default is 1:1). To recenter the pot, just hold down the button - the movement of the input pot will be ignored while a button is being held down. If you hold more than one button at a a time, the sketch just uses the lowest one.

The sketch simulates the sensor pot operation just by counting the steps and pretending that the stepper that it will be hooked to is accurate.

PaulMurrayCbr:
Ok. I think that the sketch I have so far should more-or-less do what you were after.

‘git’ is version control software, and ‘github’ is a public place that you can use as a repository for code. It’s a handy way to exchange code, although it’s usually overkill for arduino sketches.

The github repository is here GitHub - PaulMurrayCbr/arduino_topic_377515.

And the sketch itself is this:

``````// Sketch for Jason187781
``````

// comment this out to remove the DEV mockup
#define DEV
// comment this out to remove the printing to serial
// #define PRINT

const int NBUTTONS = 3;

struct ButtonAndLed {
const byte buttonPin;
const byte ledPin;
const int divisionFactor;
};

struct ButtonAndLed pinout[NBUTTONS] = {
{2, 5, 1}, // full speed button anbd indicator led
{3, 6, 2}, // half speed button anbd indicator led
{4, 7, 4}  // quarter speed button anbd indicator led
};

const byte sensorPotPin = A0;
const byte controlPotPin = A1;

#ifdef DEV
////////////////////////////////////////////////////////
// THIS BLOCK IS FOR TESTING AND DEVELOPMENT
//
// I don’t have the hardware to properly demo this, so these
// stub functions must be provided by my client Jason187781.
////////////////////////////////////////////////////////

// in the real sketch, this gets removed.
int test_dev_frame_location = 0;

// in the real sketch, this will be replaced with
return test_dev_frame_location;
}

void moveStepperUp() {
// in the real sketch, this function must talk to the stepper controller
Serial.print(" UP ");
if (++test_dev_frame_location >= 1024) test_dev_frame_location = 1024;
}

void moveStepperDown() {
Serial.print(" DN ");
// in the real sketch, this function must talk to the stepper controller
if (–test_dev_frame_location <= 0) test_dev_frame_location = 0;
}

////////////////////////////////////////////////////////
// END OF TEST/DEV BLOCK
////////////////////////////////////////////////////////
#endif

int targetOffset = 0;
int currentSelection = 0;

void setup() {
#ifdef PRINT
///////////////// TEST/DEV //////////////
Serial.begin(57600);
while(!Serial);
#endif

for (int i = 0; i < NBUTTONS; i++) {
pinMode(pinout[i].buttonPin, INPUT_PULLUP);
pinMode(pinout[i].ledPin, OUTPUT);
}

digitalWrite(pinout[currentSelection].ledPin, HIGH);
}

void loop() {

// I unconditionally read the buttons. this means that
// while any button is being held down, nothing happens.
// you can use this to recenter the control pot if you want
for (int i = 0; i < NBUTTONS; i++) {
digitalWrite(pinout[currentSelection].ledPin, LOW);
currentSelection = i;
digitalWrite(pinout[currentSelection].ledPin, HIGH);
// pick values so that wherever the pots are right now
// becomes the new target once the button is released
targetOffset = sensor - (control / pinout[currentSelection].divisionFactor);
return;
}
}

int target = targetOffset + (control / pinout[currentSelection].divisionFactor);
target = constrain(target, 0, 1023);

// we permit a little slop to handle the fact that pots are a bit noisy
if (target < sensor-1) moveStepperDown();
else if (target > sensor+1) moveStepperUp();
else /* do nothing */ ;

#ifdef PRINT
Serial.print(" selection “);
Serial.print(currentSelection);
Serial.print(” control “);
Serial.print(control);
Serial.print(” targetOffset “);
Serial.print(targetOffset);
Serial.print(” target “);
Serial.print(target);
Serial.print(” sensor ");
Serial.print(sensor);
Serial.println();
delay(50);
#endif
}

``````

Press a button to select scale (default is 1:1). To recenter the pot, just hold down the button - the movement of the input pot will be ignored while a button is being held down. If you hold more than one button at a a time, the sketch just uses the lowest one.

The sketch simulates the sensor pot operation just by counting the steps and pretending that the stepper that it will be hooked to is accurate.
``````

Thanks Paul,

It’s a great start.

The Stepper is likely to slip so this is the reason for the second pot. I could add a swich or censor ( via interrupt ) for when the frame passes the centre point therefore signalling the sketch that the frame is now central as a tradeoff?

Just looking for good compromises if possible if my wishlist at the top isn’t possible.

Cheers

Jason.

Jason187781:
The Stepper is likely to slip so this is the reason for the second pot. I could add a swich or censor ( via interrupt ) for when the frame passes the centre point therefore signalling the sketch that the frame is now central as a tradeoff?

You are operating this thing by eye anyway, so there's no need to keep count. It would be different if your system was "move to this position" or executed a recorded series of commands. But if an operator is there twiddling a controller - does it matter?

PaulMurrayCbr:
You are operating this thing by eye anyway, so there's no need to keep count. It would be different if your system was "move to this position" or executed a recorded series of commands. But if an operator is there twiddling a controller - does it matter?

I need the position to be matched via hand jog for testing, tweaking variables and setup now for each 0,1,2 button option but in the future the pot may be attached to other hardware that doesn't require an opperator and will need to be tracked as human control at this point will be removed and the whole thing and automated.

I appreciate I'm may be asking for alot of control options and need to be able to adjust many factors to get it just right but I can't compromise on the list of basic requirments at this point otherwise it just won't be what I need. I have thought long and hard on what I can loose and potentially come back to later but I keep going round in circles realising that I need all these options to achieve the goal.

The absolute minimum hardware requirment is as follows:

1. Pot A ( on hand jog wheel for initial testing and tweaking, then onto other hardware input in future without human "By eye" control )

2. Pot B ( on Frame, reading actual position for comparison use later )

3. 3 Buttons that define the following preset perameters listed below ( I need to be able to adjust these to perfection on the sketch via trial and error ) Once these peramiters are however finalised they won't be altered for future tweaking. I can do this further down the sketch if need be to make sketch creation easier but thought having peramiters called upon from a list at the top of the sketch for each button would be a better approach?

In the sketch, the minimum needs for adjustment are:

//Stepper Motor Speed or RPM
//Range of frame movment left and right but must be from centre Pot position 1:1, 1:2, 1:4 ( Pot Mapping? )
//Adjustment of comparison before action range between PotA & PotB. ( See first Post note 6,7,8 & 9 )
//Delay allowing stepper motor to get to new position ( based on number of steps to take for fluid movment. This can be a factor adjustment based on the number of steps required. )

And that's it..

I appreciate the time you have spent already and will be gifting you some £££ later today. But if we can build from here then great

I will be trying your sketch out later too, adding the stepper motor information and let you know the results. But as said before I do need these extra features by the time we are finished and don't mind sending some more money over for your further assistance

Let me know what you think

Thanks again Paul

Jason

This is an old Post, but I am doing something very similar. so hopefully you will reply.

my question is how would you convert the difference between POTA and POTB to number of Steps,

ATM I use the difference to change the number of steps from a list for example,

when there difference is >500 the stepper does 300 steps
when there difference is >400 the stepper does 200 steps and so on until it only does one step at a time,

although this works and it does find the correct position, it is very very slow and gets slower the closer you get to the target position.

thanks for the help.

Thomas.