linear slider control with pots

hello, this is only my second project and I need a little bit of help im not looking to make beautiful code just code that works for what I need it to do.

I want to use 2 linear sliders each with there own stepper motor and pot, the plan is to have pre set position that the sliders have to move to in order AKA from (0,0) to (100,200) to (300,100) to (0,0) -- I used arrays to do this...

I believe I am at a point where the code will work however I am not 100% sure.

so I am just looking for some feedback.

thanks for the help

#include <Stepper.h>

// button //
const int buttonPin = 1;
int buttonState = 0;

// Platform //
const int SPR = 200;                                                  // steps Per Revolation
const int Pitch = 5;                                                  // distance between teeth 
const int MS = 4;                                                     // mirco steps per step 
float SPU = ((SPR*MS) / Pitch);                                       // steps Per Unit mm 

// X diretion motor //
const int in1Pin = 2;                                                 //pin step up for motor 1 
const int in2Pin = 3;
const int in3Pin = 4;
const int in4Pin = 5;
Stepper myStepperX(SPR, in1Pin, in2Pin, in3Pin, in4Pin);

// Y direction motor //
const int in5Pin = 6;                                                 //pin set up for motor 2 
const int in6Pin = 7;
const int in7Pin = 8;
const int in8Pin = 9;
Stepper myStepperY(SPR, in5Pin, in6Pin, in7Pin, in8Pin);

// counters//
int countX = 0;                                                       // starts countX at 0 
int countY = 0;                                                       // starts countY at 0 


//Arrays//
int myArrayXH[] = {120, 226, 423, 426, 602, 615, 779, 792};           // analog Values for X Direction
int myArrayX[]  = {116, 222, 419, 422, 598, 611, 775, 788};
int myArrayXL[] = {112, 218, 415, 418, 594, 607, 771, 784};
int myArrayYH[] = {822, 536, 209};
int myArrayY[]  = {818, 532, 205};                                    // analog Values of Y Direction 
int myArrayYL[] = {814, 528, 201};

//smoothing DATA//
const int NumReadings = 20;
int total = 0;
int average = 0;

// sensors //
int sensorReadingx = 0; //analogRead(A0);
int sensorReadingy = 0; //analogRead(A1);

//Setup//
void setup()
{
  Serial.begin(9600);
  Serial.println(MS);
  Serial.println(Pitch);
  Serial.println(SPU);
  Serial.println(countX);
  Serial.println(myArrayX[countX]);
  Serial.println(countY);
  Serial.println(myArrayY[countY]);
  Serial.println("Waiting for Input");
  delay(1000);
START:
  if (Serial.available() > 0)
  {
    buttonState = HIGH;
  } else goto START;
  Serial.println("Start");
  if (buttonState == HIGH)
  {
    CALABRATION();
    delay(50);
  }
}

void YForwards()
{
  int MotorDirection = 1;
  int motorSpeed = 200;
  int STEPS = (SPU * MotorDirection);
  myStepperY.setSpeed(motorSpeed);
  myStepperY.step(STEPS);
  delay(500);
}
void YBackWards()
{
  int MotorDirection = -1;
  int motorSpeed = 200;
  int STEPS = (SPU * MotorDirection);
  myStepperY.setSpeed(motorSpeed);
  myStepperY.step(STEPS);
  delay(500);
}
void YSTOP()
{
  int MotorDirection = 0;
  int motorSpeed = 0;
  int STEPS = (SPU * MotorDirection);
  myStepperY.setSpeed(motorSpeed);
  myStepperY.step(STEPS);
  delay(500);
}

void XForwards()
{
  int MotorDirection = 1;
  int motorSpeed = 200;
  int STEPS = (SPU * MotorDirection);
  myStepperX.setSpeed(motorSpeed);
  myStepperX.step(STEPS);
  delay(500);
}
void XBackWards()
{
  int MotorDirection = -1;
  int motorSpeed = 200;
  int STEPS = (SPU * MotorDirection);
  myStepperX.setSpeed(motorSpeed);
  myStepperX.step(STEPS);
  delay(500);
}
void XSTOP()
{
  int MotorDirection = 0;
  int motorSpeed = 0;
  int STEPSCAL = (SPU * MotorDirection);
  myStepperX.setSpeed(motorSpeed);
  myStepperX.step(STEPSCAL);
  delay(500);
}
the rest of the code 


[code]
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

void CALABRATION()
{
  //calabration code//
  Serial.println("Calabration");                                         
  Serial.println("moving to center position");
  Serial.println("Calabrating Y");
  do {
    total = 0;
    for ( int i = 0; i < NumReadings; i++)
    {
      sensorReadingy = analogRead(A1);
      total = total + (sensorReadingy);
      delay(10);
    }
    average = total / NumReadings;
    Serial.println(average);
    int DistanceY = ( 532 - average );
    if ( DistanceY > 4 )
    {
      Serial.println("Forwards");
      YForwards();
      delay(500);
    }
    if (DistanceY < -4 )
    {
      Serial.println("Backwards");
      YBackWards();

      delay(500);
    }
    if (DistanceY > -4 && DistanceY < 4)
    {
      Serial.println("STOP");
      YSTOP();
      delay(500);
    }
    delay(500);
  } while ( average <= 528 || average >= 536);
  if (average >= 528 && average <= 536)
  {
    Serial.println("Y Calabration Complete");
  } else {
    Serial.println("Rerunning Calabration");
    CALABRATION();
  }
  delay(500);
  Serial.println("Calabrating X");
  do {
    total = 0;
    for ( int i = 0; i < NumReadings; i++)
    {
      sensorReadingx = analogRead(A0);
      total = total + (sensorReadingx);
      delay(10);
    }
    average = total / NumReadings;
    Serial.println(average);
    int DistanceX = (450 - average);
    if ( DistanceX > 4 )
    {
      Serial.println("Forwards");
      XForwards();
      delay(500);
    }
    if (DistanceX < -4 )
    {
      Serial.println("BackWards");
      XBackWards();
      delay(500);
    }
    if (DistanceX > -4 && DistanceX < 4)
    {
      Serial.println("STOP");
      XSTOP();
      delay(500);
    }
    delay(500);
  } while ( average <= 446 || average >= 454 );
  if (average <= 446 || average >= 454 )
  {
    Serial.println("Rerunning Calabration");
    CALABRATION();
  }
  Serial.println("X CALABRATION COMPLETED");
  delay(500);
  Serial.println("X,Y Calabration Completed");
}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

void XAXIS()
{
  Serial.println("RUNNING [X]");                                                                            
  if (countX >= 9)
  {
    Serial.println("Resetting CountX");                                                                     
    delay(100);
    countX = countX - 9;
  }
  do {
    total = 0;
    for ( int i = 0; i < NumReadings; i++)
    {
      sensorReadingx = analogRead(A0);
      total = total + (sensorReadingx);
      delay(10);
    }
    average = total / NumReadings;
    Serial.println(average);
    int DistanceX = (myArrayX[countX] - average);                                                         
    if ( DistanceX > 4 )
    {
      Serial.println("FORWARD");
      XForwards();
      delay(500);
    }
    if (DistanceX < -4 )
    {
      Serial.println("BACKWARDS");
      XBackWards();
      delay(500);
    }
    if (DistanceX > -4 && DistanceX < 4)
    {
      Serial.println("STOP");
      XSTOP();
      delay(500);
    }
    delay(500);                                                                                          
  } while ( average <= myArrayXL[countX] || average >= myArrayXH[countX]);                             
  if ( average >= myArrayXL[countX] || average <= myArrayXH[countX])                                    
  {
    Serial.println("correct position increase countX");
    countX = countX + 1;                                                                                 
  } else XAXIS();
}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

void YAXIS()
{
  Serial.println("RUNNING [Y]");
  if ( countY == 3)
  {
    Serial.println("Resetting CountY");
    delay(100);
    countY = countY - 3;
    Serial.println("RERUNNING [Y]");
  }
  do {
    total = 0;
    for ( int i = 0; i < NumReadings; i++)
    {
      sensorReadingx = analogRead(A0);
      total = total + (sensorReadingy);
      delay(10);
    }
    average = total / NumReadings;
    Serial.println(average);                                          
    int DistanceY = (myArrayY[countY] - average);              
    if ( DistanceY > 4 )
    {
      Serial.println("FORWARD");
      YForwards();
      delay(500);
    }
    if (DistanceY < -4 )
    {
      Serial.println("BACKWARD");
      YBackWards();
      delay(500);
    }
    if (DistanceY > -4 && DistanceY < 4)
    {
      Serial.println("STOP");
      YSTOP();
      delay(500);
    }
    delay(500);                                                                                          
  } while ( average <= myArrayYL[countY] || average >= myArrayYH[countY]);                 
  if ( average >= myArrayYL[countY] || average <= myArrayYH[countY])
  {
    Serial.println("correct position increase countY");
    countY = countY + 1;
  }
  else YAXIS();
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

void CrossGate()
{
  do {
    total = 0;
    for ( int i = 0; i < NumReadings; i++)
    {
      sensorReadingx = analogRead(A0);
      total = total + (sensorReadingy);
      delay(10);
    }
    average = total / NumReadings;
    Serial.println(average);
    Serial.println("RUNNING[CROSSGATE]");                                           
    int DistanceY = ( myArrayY[1] - average );
    if ( DistanceY > 4 )
    {
      Serial.println("FORWARD");
      YForwards();
      delay(500);
    }
    if (DistanceY < -4 )
    {
      Serial.println("BACKWARD");
      YBackWards();
      delay(500);
    }
    if (DistanceY > -4 && DistanceY < 4)
    {
      Serial.println("STOP");
      YSTOP();
      delay(500);
    }
    delay(500);
  }  while ( average <= myArrayYL[1] || average >= myArrayYH[1]);                  
  if ( average >= myArrayYL[1] || average <= myArrayYH[1])
  {
    Serial.println("back in CrossGate");
  }
  else CrossGate();
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

void POSITION()
{
  switch ( countX )
  {
    case 1:
      Serial.println("Reverse Gear");
      delay(1000);
      break;
    case 2:
      Serial.println("first Gear");
      delay(1000);
      break;
    case 3:
      Serial.println("Second Gear");
      delay(1000);
      break;
    case 4:
      Serial.println("third Gear");
      delay(1000);
      break;
    case 5:
      Serial.println("Fourth Gear");
      delay(1000);
      break;
    case 6:
      Serial.println("Fifth Gear");
      delay(1000);
      break;
    case 7:
      Serial.println("Sixth Gear");
      delay(1000);
      break;
    case 8:
      Serial.println("Seventh Gear");
      delay(1000);
      break;
  }
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

void loop()
{

  if (buttonState == HIGH) {
    XAXIS();
    delay(10);
    YAXIS();
    delay(10);
    POSITION();
    delay(10);
    CrossGate();
  } else if (buttonState == LOW)
  {
    exit(0);
  }
}

// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

[/code]

What does the code actually do?
What do you want it to do?
How do those differ?

What problem do you need help solving?

sorry that's second post is the same code just the rest of it, I want to to move the linear slider to pre set positions on a loop aka from position 1 to 2 to 3 back to 1 again on a loop,

void CALABRATION()
{
  //calabration code//
  <snip>
  if (average >= 528 && average <= 536)
  {
    Serial.println("Y Calabration Complete");
  } else {
    Serial.println("Rerunning Calabration");
    CALABRATION();
  }

Having a function call itself is generally not a good idea.

Calibration is NOT spelled that way.

I could probably count on one hand the number of times I've used do/while loops in code I've written in the last 30 years, and still have fingers left over. I can't help thinking that do/while statements are probably not the best statements to be using.

I am CERTAIN that the recursive calls in your code are wrong.

okay thank you for your help, how would I change the code so that I do not need to have the function call itself ?

also what is wrong with a do while loop? and how would I change it ?

I replaced the do while loops with for loops ?

 for ( average; average <= 528 || average >= 536;)
  {
    total = 0;
    for ( int i = 0; i < NumReadings; i++)
    {
      sensorReadingy = 532;//analogRead(A1);
      total = total + (sensorReadingy);
      delay(10);
    }
    average = total / NumReadings;
    Serial.println(average);
    int DistanceY = ( 532 - average );
    if ( DistanceY > 4 )
    {
      Serial.println("Forwards");
      YForwards();
      delay(500);
    }
    if (DistanceY < -4 )
    {
      Serial.println("Backwards");
      YBackWards();

      delay(500);
    }
    if (DistanceY > -4 && DistanceY < 4)
    {
      Serial.println("STOP");
      YSTOP();
      delay(500);
    }
    delay(500);
  }

how would I change the code so that I do not need to have the function call itself ?

Start by explaining WHY the function needs to call itself. The analogRead() function does not call itself over and over. It may take some time to get a reading, but it simply waits until it has done all that it needs to do before it returns.

The sqrt() function iterates, trying to improve the accuracy of the result, until it no longer converges on a better answer. But, it does NOT call itself over and over.

replaced the do while loops with for loops ?

No. In most cases, a while statement is a far better choice than a do/while. Do some research to understand why. In particular, pay attention to the minimum number of times that the statement may iterate. A while statement may iterate 0 times. How many times, at a minimum, will a do/while statement iterate? Is that appropriate in ALL the places where you use do/while loops?

Thomaswates:
I want to use 2 linear sliders each with there own stepper motor and pot,

Are the sliders controlling the motors or are the motors moving the sliders?

I believe I am at a point where the code will work however I am not 100% sure.

so I am just looking for some feedback.

Test the program before you ask for help. Then, if it does work you won't need help. And if it does not work you will be able to tell us what it actually does and what you want it to do that is different. The Arduino system is great for learning-by-doing.

Please don't post programs in parts - it is too easy to introduce errors when joining the parts. If the code is too long for inclusion in a reply then attach the .ino file.

And you should have been doing a huge amount of testing before your program got so big that it won't fit in a single Reply. Test every time you make a change.

...R

PaulS:
In most cases, a while statement is a far better choice than a do/while. Do some research to understand why.

In this case the OP was attempting:

do{
      try_calibration
}while( not calibrated );

Which is a suitable construct for the task.

In that cal. function:

  } while ( average <= 528 || average >= 536);
  if (average >= 528 && average <= 536)
  {
    Serial.println("Y Calabration Complete");
  } else {
    Serial.println("Rerunning Calabration");
    CALABRATION();
  }

As has been said DO NOT call functions from inside themselves, all sorts of bad things can happen.
In this case, that call is of no use anyway.

The while() will continue to loop until average is in the range 529 to 535, then it will exit.
The program cannot get to the following lines until that happens, so, as far as your logic goes, it cannot get out of that while() loop and still be un-calibrated.

In this section of the original code:

START:
  if (Serial.available() > 0)
  {
    buttonState = HIGH;
  } else goto START;
  Serial.println("Start");
  if (buttonState == HIGH)
  {
    CALABRATION();
    delay(50);
  }

I think it is fair to say: NEVER EVER EVER use 'goto'.

You want some loop to wait for Serial.available(), while it is not yet available you not want to do anything
so:

while( Serial.available() == 0 ){
  // do nothing, wait for serial to be available
}

Yours,
TonyWilk

Thomaswates:
hello, this is only my second project and I need a little bit of help im not looking to make beautiful code just code that works for what I need it to do.

I want to use 2 linear sliders each with there own stepper motor and pot, the plan is to have pre set position that the sliders have to move to in order AKA from (0,0) to (100,200) to (300,100) to (0,0) -- I used arrays to do this...

I believe I am at a point where the code will work however I am not 100% sure.

So have you built any hardware and connected it to your controller?
If not, then ALL this code is untested.
Can I make a suggestion.

  • Get your hardware.
  • Connect it to your controller.
  • Write your code in stages.
  • Each stage sending a control or receiving an input value from the slider
  • When you have got working code for the input and output to the slider and can reliably control it.
  • THEN begin writing the code to do what you want.

Writing code en-mass is not the way to do it efficiently.
It will be filled with bugs believe me, the problem being so many bugs that you will not know where to start to debug or which bug is causing other bugs.

We are at post #10, and know nothing about how to drive your slider or how you read its position output.

Please post links to data/specs of your slider and a starting schematic on how you envisage connecting it all together,

What model Arduino are you using?

Can you please tell us your electronics, programming, Arduino, hardware experience?

Thanks.. Tom.. :slight_smile:

No. In most cases, a while statement is a far better choice than a do/while.

Pauls - I do want the loop to always run once - so I believe a do while is correct here.

So have you built any hardware and connected it to your controller?

TomGeorge - yes it is untested. I have 2 L298N motor drives 2 Stepper motors which I had lying about. 2 rotary potentiometers( which I'm going to use to simulate the linear sliders ) I wanted to try and Write some code that I was fairly confident will work before spending lots of money on motorised linear sliders.

As has been said DO NOT call functions from inside themselves

tonyWilk - I have Removed this part now.. I was worried that the slider might over shoot the mark so if this happened I wanted it to rerun that function.

Are the sliders controlling the motors or are the motors moving the sliders

Robin- the motors drive the sliders, using the linear potentiometers as feedback control....

everyone --- I hope this clears some things up, I will start testing straight away as your correct its pointless to write a program without testing it as you go.

thank you all for the help

Thomas.

HI,

TomGeorge - yes it is untested. I have 2 L298N motor drives 2 Stepper motors which I had lying about. 2 rotary potentiometers( which I'm going to use to simulate the linear sliders ) I wanted to try and Write some code that I was fairly confident will work before spending lots of money on motorised linear sliders.

Okay, but you have some hardware to test your concept. so connect it together and start DEVELOPING your code in stages.

Tom...... :o