Stepper Motor Control with Feedback

I’m trying to set up a bipolar stepper motor with feedback. I want the motor to rotate down until a button is pressed and then return to the original position, while assigning the number of steps traveled to a variable.

I’ve set up my circuit according to this (with four pins) and this (bipolar stepper circuit).

arduino.cc/en/Reference/StepperBipolarCircuit

arduino.cc/en/Tutorial/MotorKnob

I plan on using the built-in stepper function, and this is what I have written so far:

#include <Stepper.h>
#include <LiquidCrystal.h>

#define STEPS 48 // change this to the number of steps on
//your motor

Stepper stepper(STEPS, 9, 10, 11, 12); // create an instance of
//the stepper class, specifying the number of steps of the motor
//and the pins it’s attached to

LiquidCrystal lcd(1, 2, 3, 4, 5, 6); // initialize library with
// the numbers of interface pins

int previous = 0; // the previous reading from the analog input

#define BUTTONA 8 // the input pin where the
// pushbutton is connected

int val = 0; // val will be used to store the state
// of the input pin

int old_val = 0; // this variable stores the previous
// value of “val”

int val2 = 0; // val2 will be used to store the state
// of the input pin

int old_val2 = 0; // this variable stores the previous
// value of “val2”

int state = 0; // 0 = STEPPER off and 1 = STEPPER on

#define BUTTONB 7 // Voltage readout from probes

int n = 1; // number of steps

int z = 0; //variable

void setup() {

pinMode(BUTTONA, INPUT); // and BUTTON is an input
pinMode(BUTTONB, INPUT);
stepper.setSpeed(30); // set the speed of the motor to 30 RPMs
lcd.begin(16,2); //set up the LCD’s number of columns and rows
}

void loop(){
val = digitalRead(BUTTONA); // read input value and store it

if ((val == HIGH) && (old_val == LOW)){ // check if there
//was a transition
state = 1 - state;
delay(10);
}
old_val = val; // val is now old, let’s store it
if (state == 1) {
z = 1;
n = 0;
loop(); {
val2 = digitalRead(BUTTONB);
if ((val2 == LOW) && (z = 1)) { //If the sensor is than 5 volts

n=n+1; // number of steps plus one

stepper.step(1); // move 1 step
}
else if (val2 == HIGH) {
stepper.step(-n); // move back up corresponding number
//of steps
z = 2;
lcd.display();
lcd.clear();
lcd.print(“Water Depth”); //Display The water depth is
lcd.setCursor(0,1);
lcd.print(15 - (n * 0.0127)); // Calculate water depth and display it
delay(15000);
lcd.noDisplay();
}
// Store to SD Card
// Display to LCD
} // run STEPPER Loop
}

}

Any thoughts?

if (state == 1) {
     z = 1;
     n = 0;
    [glow] loop();[/glow] {

Do not even think about doing this.

if ((val2 == LOW) && (z = 1)) { //If the sensor is than 5 volts

Also note that = is the assignment operator, not the equality operator (==).

What is the problem of using the loop function? Also, what is the difference between the assignment operator, and the equality operator? This is my first time doing this so I really appreciate the help.

What is the problem of using the loop function?

Limited stack.
Google term “recursion”

Also, what is the difference between the assignment operator, and the equality operator?

Algol or Pascal make it clearer:
a := 3; (in C “a = 3;”)
is assignment. Read it as “a becomes equal to 3”,

a == 3

Read it as “does a have the same value as 3?”

And another thing, when you’re posting code, can you use the # icon on the editor’s toolbar, please?

Ok thanks, I took out the loop but now the big problem I seem to be having is that my stepper only moves forward instead of forwards and then backwards. Any ideas?

Any ideas?

Oooh. Oooh. I have one! Call on me!

Post your current code!

Here is the current code.

#include <Stepper.h>
#include <LiquidCrystal.h>

#define STEPS 48 // change this to the number of steps on 
   //your motor
   
Stepper stepper(STEPS, 9, 10, 11, 12); // create an instance of 
   //the stepper class, specifying the number of steps of the motor 
   //and the pins it's attached to

LiquidCrystal lcd(1, 2, 3, 4, 5, 6); // initialize library with
   // the numbers of interface pins
   
int previous = 0; // the previous reading from the analog input

#define BUTTONA 8 // the input pin where the
   // pushbutton is connected
   
int val = 0; // val will be used to store the state
   // of the input pin

int old_val = 0; // this variable stores the previous
   // value of "val"

int val2 = 0; // val2 will be used to store the state
   // of the input pin

int old_val2 = 0; // this variable stores the previous
   // value of "val2"
   
int state = 0; // 0 = STEPPER off and 1 = STEPPER on

#define BUTTONB 7 // Voltage readout from probes

int n = 1; // number of steps

int z = 0; //variable

void setup() {

pinMode(BUTTONA, INPUT); // and BUTTON is an input
pinMode(BUTTONB, INPUT);
stepper.setSpeed(30); // set the speed of the motor to 30 RPMs
lcd.begin(16,2); //set up the LCD's number of columns and rows
}

void loop(){
val = digitalRead(BUTTONA); // read input value and store it

   if ((val == HIGH) && (old_val == LOW)){ // check if there 
      //was a transition 
      state = 1 - state;
   delay(10);
   }
   old_val = val; // val is now old, let's store it
   if (state == 1) {
      z = 1;
      n = 0;
      val2 = digitalRead(BUTTONB);
      while((val2 == LOW) && (z ==1)){ 
     
         n=n+1; // number of steps plus one
  
         stepper.step(1); // move 1 step
      }
      if (val2 == HIGH) {
         stepper.step(-n); // move back up corresponding number 
               //of steps
         z = 2;    
         lcd.display();
         lcd.clear();
         lcd.print("Water Depth"); //Display The water depth is 
         lcd.setCursor(0,1);
         lcd.print(15 - (n * 0.0127)); // Calculate water depth and display it
         delay(15000);
         lcd.noDisplay();
      }
      // Store to SD Card
      // Display to LCD
   }     // run STEPPER Loop 
}

Whenever I use the above code the motor only goes down, it does not go back up the number of steps it went down once the second button is pressed it just continues to go down. Any thoughts on how to solve this problem?

It could be a hardware problem or a software problem.

Create a new sketch that makes the stepper step one step in one direction 20 times, with a short delay between steps.

Then, make it step back one step 20 times, with a short delay between steps.

If the stepper turns both ways, the problem is with this sketch. If not, the problem is either with the new sketch or the hardware.

If the motor does not turn both ways, post the (simpler) new sketch, and we'll review it for correctness.

Thanks for all of your help. I was able to get it working.

Now im trying to have it store the last 10 sensor values it records and the last 10 step numbers before it goes back up. It keeps giving me an error of error: invalid type ‘int[10][int[10]]’ for array subscript.

Here is the most recent code.

#include <Stepper.h>
#include <LiquidCrystal.h>

#define STEPS 48 // change this to the number of steps on 
   //your motor
   
Stepper stepper(STEPS, 9, 10, 11, 12); // create an instance of 
   //the stepper class, specifying the number of steps of the motor 
   //and the pins it's attached to

LiquidCrystal lcd(1, 2, 3, 4, 5, 6); // initialize library with
   // the numbers of interface pins
   
int previous = 0; // the previous reading from the analog input

#define BUTTON 8 // the input pin where the
   // pushbutton is connected 
#define VOLTAGE 7 // Voltage readout from probes

int val = 0; // val will be used to store the state
   // of the input pin
int old_val = 0; // this variable stores the previous
   // value of "val"
   
int state = 0; // 0 = STEPPER off and 1 = STEPPER on

int n = 0; // number of steps

int z = 0; //variable

int sensor_val = 0;

#define MAX_SAMPLES 10// number of samples taken  
int step_sample[MAX_SAMPLES];
int voltage_sample[MAX_SAMPLES];
int index[10];

void setup() 
{
pinMode(BUTTON, INPUT); // and BUTTON is an input
pinMode(VOLTAGE, INPUT);
stepper.setSpeed(210); // set the speed of the motor to 60 RPMs
lcd.begin(16,2); //set up the LCD's number of columns and rows
}

void loop()
{
val = digitalRead(BUTTON); // read input value and store it

   if ((val == HIGH) && (old_val == LOW))
   { // check if there 
      //was a transition 
      state = 1 - state;
   delay(10);
   }
   old_val = val; // val is now old, let's store it
   if (state == 1)
   {
      z = 1;
      sensor_val = analogRead(VOLTAGE);// this variable stores the 
         //voltage measurement from the probe
      voltage_sample[index] = sensor_val;
 
      if ((sensor_val < 1023) && (z == 1))//If the sensor is
         //less than 5 volts
      {        
         stepper.step(-1); // move 1 step
         
          n=n+1; // number of steps plus one
          
          step_sample[index] = n++;
          index = (index+1) % MAX_SAMPLES;
      }
      else if (z == 1) 
      {
         delay(2000);
         stepper.step(n); // move back up corresponding number 
               //of steps
         z = 2;
         n = 0;
         lcd.display();
         lcd.clear();
         lcd.print("Water Depth"); //Display The water depth is 
         lcd.setCursor(0,1);
         lcd.print(15 - (n * 0.0127)); // Calculate water depth and display it
         delay(15000);
         lcd.noDisplay();
      }
      // Store to SD Card
      // Display to LCD
   }     // run STEPPER Loop 
}

Not sure what the error means, or how to fix it. Thoughts?

keeps giving me an error of error: invalid type 'int[10][int[10]]' for array subscript

You sure about that?

int index[10];
index = (index+1) % MAX_SAMPLES;

I set MAX_SAMPLES to 10 so it should be right but it definitely keeps giving me that error for lines 61 and 70 . Then it gives me another error of error: invalid operands of 'int*' and 'int' to binary 'operator%' on line 71.

You have declared index to be an array, and yet you are treating it as a scalar variable.

Is it an array or not?

It should be an array. I want to have two arrays, one to hold the voltage value taken for each step and one for what number step it is.

and one for what number step it is.

But that's a scalar, not a vector.

Yes the number nis scalar but I want it to store that number everytime it takes a step, so for the first ten steps there would be an array of {1,2,3,4,5,6,7,8,9,10} and then the voltages associated with each of these steps in a another array ten digit array.

Hey guys,

So I'm working on a project which is kind of along these lines.. I'm looking to store / change variables which correspond to a certain spot the stepper is at.

Basically I'd like to make a moving mount which I can control X and Y values ( accurate within a few mm if possible ) and change them and have the mount scoot to a (X,Y) coordinate

So my main question here is .. how are you guys storing the location of where the stepper motor is at.. is it....

total degrees of rotation ?? some other more efficient way?

Thanks in advance!