STEPPER SHAFT ANGLE REAL TIME, WITH FOR, AND IF FUCTIONS

All my Apologies, in advance. I’m sure this project has been done one-hundred times, but I cannot seem to get my head around using Millis, so I’m trying to update a variable after the loop.

Google does not give me the answers, at least simple enough for me to understand them.

The Goal is to simply controlling a stepper motor angle with a potentiometer.

analogread pot converts to angle, converts to steps forward or backwards. Ideally stepper shaft should follow pot knob.

Adafruit 7seg displays the angle at beginning of the loop.

Code does not move the stepper. I’m sure it’s obvious to the Arduino Gods, but I am a blind man who is lost. And also rather new.

Can someone help me understand why this code does not work, or suggest a better way to accomplish this.

Thank You,
Chris

 /* 
 POTENIOMETER DETERMINES ANGLE OF STEPPER MOTOR, 360 DEGREES TOTAL, STEPPER SHAFT MOVES REAL TIME.
 ANGLE DISPLAYED ON ADAFRUIT BACKPACK 7 SEG DISPLAY.
 MOMENTARY PUSH BUTTON MOVES STEPPER BACK TO HOME '0 DEGREES'.
 */


 #include <Wire.h>
 #include <Adafruit_GFX.h>
 #include "Adafruit_LEDBackpack.h"

 Adafruit_7segment matrix = Adafruit_7segment();    //Display libraries....

int mButtn = 5; //mom button pin 5
int pot = A0; //poteniometer
int trGr = 7; // 0 degree home switch

int stepp = 9; //Driver step pin
int dir = 10;  //Driver direction pin


float previousAngle = 0;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup () {

pinMode(mButtn, INPUT);
pinMode(pot, INPUT);
pinMode(trGr, INPUT);

pinMode(stepp, OUTPUT);
pinMode(dir, OUTPUT);

Serial.begin(9600);

matrix.begin(0x70);




}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop(){
 

 float angle = analogRead(pot)* 0.351;  //converts 1023 to and angle 360 degrees
  
matrix.print(angle);        //prints angle to 7seg led
matrix.writeDisplay();
delay(50);
                                  
if(angle > previousAngle) {         //if new pot reading is greater, set changeAngle
                                   // to difference beteween (previousAngle - Angle). /1.8 gives number of steps.
   
   float changeAngle  = (angle - previousAngle) / 1.8 ; // to difference beteween (previousAngle - Angle). /1.8 gives number of steps.                      
         Serial.println(changeAngle);
  for (int pulse=0; pulse < changeAngle; pulse++) {
    digitalWrite(dir, HIGH);
    digitalWrite(stepp, HIGH);
    delay(500);
    digitalWrite(stepp, LOW);
    delay(500);}
}


                                      
else {
  float changeAngle = (previousAngle - angle) / 1.8;  //reverse direction if angle is less than previous angle 
    Serial.println(changeAngle);
  for (int pulse=0; pulse < changeAngle; pulse++) {
    digitalWrite(dir, LOW);
    digitalWrite(stepp, HIGH);
    delay(500);
    digitalWrite(stepp, LOW);
    delay(500);}
}

previousAngle = angle;  //updates the angle variable at the end of the loop
delay(100);
}

For an informed answer, please post links to data sheets for your motor, motor driver and motor power supply, and post a picture of a hand drawn wiring diagram (not Fritzing), being careful to clearly label all the connections and pins.

Before tackling a complex project, make sure all the bits work independently, like taking one step with the motor. Have you done that?

Stepper motors work in whole numbers of steps. I think your code would be much easier to develop and debug if you don’t use an floating point maths. In any case, floating point maths is very slow on an Arduino.

And, as @jremington has said, make sure you can do all the parts separately before trying to create a composite program

…R
Stepper Motor Basics
Simple Stepper Code

If you're using Millis, then you're already in trouble. C is case-sensitive. The correct function name is millis().

delay(500) seems awfully slow for a stepper. One step per second is barely moving. I'd be making steps at about 100-500 per second, implying a delay of 5 milliseconds or so.

Rather than taking a reading and then taking the required number of steps towards that point with your eyes and ears closed, why not take a reading from the pot after every step? Then you can just simply decide if the target position is above or below the current position and move one step in that direction. If the target is not very far away, take zero steps.

Hi, If you are using the pot to position the stepper. Do you have a way to set the stepper to a set start position.

How do you know where the stepper is when you power up and the pot is positioned at 0 or 10 or 50 steps?

Tom... :)

Great answers, All. Thanks for your reply.

JRemington: Pot + Display works great alone.

I have ran the stepper with a program that sends a number of steps and direction, 36v nema bipolar 17 stepper + a9488 driver gets a bit to hot, but it works for a while. Motor is not the problem, it's the code.

Robin, Do you think PMW is better for driving a stepper? How do I control the number of steps exactly? Time, Right?

I'm thinking the float is what is hanging things up, found an example on the playground of controlling a stepper motor with the stepper library, and their code was pretty much the same concept as mine, just calling the libraries instead of pin HIGH DELAY PIN LOW.

any suggestions for interpreting the POT without FLOAT?

Tom, Not worried about the actual position. I'll put in a home...limit switch later. Just startup on 'position 0'.

Morgan, previousAngle - Angle = changeAngle, (if positive) and converts that value to steps, (/1.8, of a 200 click stepper). Im thinking the code does exactly what you suggest, resets previousAngle to Angle at end of the loop, then checks for any change in voltage from the pot.

Thanks again. Chris

CASMD33: Robin, Do you think PMW is better for driving a stepper?

No. PWM has nothing to do with stepper motors.

any suggestions for interpreting the POT without FLOAT?

analogRead() gives a value from 0 to 1023.

Just decide how many steps the motor needs to go if the value is 1023. Let's assume it should do 1 full revolution or 200 steps.

Then if analogRead() gives 512 the motor would move 100 steps.

Maybe there would be sufficient accuracy if you divide the analogRead() value by 5 and limit the max to 200 (for my example). That just ignores the last little bit of motion of the pot (from 1000 to 1023).

If you want to move more or less steps in total just make an appropriate change to my simple maths.

If you need fractional divisions do them as a combination of integer multiplications and divisions. For example to divide by 2.65 multiply by 20 and divide by 53. Generally do the multiplication first to preserve precision.

...R

I think the current problem is that your knob is moving less than one stepper step in the time it takes to repeat the loop. The code assumes that the motor has moved but since the step count it zero it has not moved. Robin2’s recommendation to use positions in steps, not degrees, should fix that.

You should make the steps MUCH faster than one per second (two 500 millisecond delays). Try removing the delays completely. If that fails, use delays of 1 millisecond.