Change direction on Stepper based on Analog Read

Having trouble with changing the directions on a stepper.

If i connect 5V to the Direction Pin on my Driver. It wil Reverse.

But What am i missing on the AnalogRead part here?

The Motor will not run Consistent, and will not Reverse based on my Inputs.

LarsPerformance

Valve_Control_with_Comments.ino (854 Bytes)

That did not work as intended!
But here is the Code:

/*Valve control with ClosedLoop based on Potentiometer
*Output is based on HY-DIV268N-5A
*Feedback is Potentiometer 1K with 5V Sweep
*Setpoint is Potentiometer 10K with 5V Sweep
*/

int Feedback =0; //Feedback from Valve
int Setpoint =1; //Setpoint from Potentiometer

void setup() {
pinMode(8, OUTPUT); //Direction Pin on Stepper Driver
pinMode(9, OUTPUT); //Stepper Pulse
}

void loop() {
Feedback = analogRead(Feedback); //Reads position on Valve

Setpoint = analogRead(Setpoint); //Reads Setpoint from Potentiometer

digitalWrite(9, HIGH); //Step HIGH

delay(1);

digitalWrite(9, LOW); //Step LOW

delay(1);

if(Feedback < Setpoint) {digitalWrite(8, HIGH);} //Change direction based on Input State
else (digitalWrite(8, LOW));
}

You can no start and stop a stepper in an instant. You have to
ramp it down to a stop and then ramp it back up in the other
direction.
Do also note that the added loop delay can make it oscillate if
there is not enough dampening on the value being fed back from
the analog input.
Dwight

Please use the code button </>

/*Valve control with ClosedLoop based on Potentiometer
*Output is based on HY-DIV268N-5A
*Feedback is Potentiometer 1K with 5V Sweep
*Setpoint is Potentiometer 10K with 5V Sweep
*/

int Feedback =0;    //Feedback from Valve
int Setpoint =1;     //Setpoint from Potentiometer


void setup() {               
  pinMode(8, OUTPUT);     //Direction Pin on Stepper Driver
  pinMode(9, OUTPUT);    //Stepper Pulse
}

void loop() {
  Feedback = analogRead(Feedback);    //Reads position on Valve
 
  Setpoint = analogRead(Setpoint);    //Reads Setpoint from Potentiometer
 
  digitalWrite(9, HIGH);              //Step HIGH
 
  delay(1);
 
  digitalWrite(9, LOW);               //Step LOW
 
  delay(1); 
 
  if(Feedback < Setpoint) {digitalWrite(8, HIGH);}    //Change direction based on Input State
  else (digitalWrite(8, LOW));       
}

You have not described the symptoms in sufficient detail. You seem to be running the motor at 500 steps per second so, as @dwightthinker has said, you may need to allow time for it to stop before reversing. You can check that by getting it to move a known number of steps (perhaps a full circle) and checking if it misses steps.

You may also find that it is hunting between forward and reverse because you do not allow any "dead" space. Try something like

if (Setpoint - Feedback > 50) {
   // set HIGH
}
if (Feedback - Setpoint > 50) {
   // set LOW
}

Change the value of 50 to suit your application.

...R

Thanks for the information!

Now i did try with some Threshold.
almost same problem, when the input signals is close to eachother, its rotation is flickering.
It will NOT reverse, regardless of inputs.

About ramping the motor!
If i run it at full speed, and do a Hardwire on the Reverse signal straight to 5V headder, it will change direction.
So in my mind it will work, but maybe not.

Probably do some Library Chasing

*Output is based on HY-DIV268N-5A
*Feedback is Potentiometer 1K with 5V Sweep
*Setpoint is Potentiometer 10K with 5V Sweep
*/





int Feedback =0;    //Feedback from Valve
int Setpoint =1;     //Setpoint from Potentiometer


void setup() {                
  pinMode(8, OUTPUT);     //Direction Pin on Stepper Driver
  pinMode(9, OUTPUT);    //Stepper Pulse
}

void loop() {
  Feedback = analogRead(Feedback);    //Reads position on Valve
  
  Setpoint = analogRead(Setpoint);    //Reads Setpoint from Potentiometer
  
  
  if(Feedback - Setpoint < 800) {digitalWrite(8, HIGH);}    //Change direction based on Input State
  
  if(Feedback - Setpoint > 800) {digitalWrite(8, LOW);}     

  digitalWrite(9, HIGH);              //Step HIGH
  
  delay(1); 
  
  digitalWrite(9, LOW);               //Step LOW
  
  delay(1);

It might be that the analog read is noisy and producing a noise step direction.
Dwight

This code

 if(Feedback - Setpoint < 800) {
  digitalWrite(8, HIGH);
   }    //Change direction based on Input State
 
  if(Feedback - Setpoint > 800) {
  digitalWrite(8, LOW);
  }

is not logically equivalent to the similar code in your Original Post

if(Feedback < Setpoint) {digitalWrite(8, HIGH);}    //Change direction based on Input State
  else (digitalWrite(8, LOW));

Study them carefully. (I's nothing to do with the 800)
I don't know which approach is correct - just that they are different. My guess is that the first one is correct. Have a look, also, at the suggestion I made

if (Setpoint - Feedback > 50) {
   // set HIGH
}
if (Feedback - Setpoint > 50) {
   // set LOW
}

If, in fact, the second one is what you want then you still don't have any hysteresis in your system.

...R

I don't think this is a good idea:

Setpoint = analogRead(Setpoint);

If you do an analog read Setpoint changes and who knows
what it does with it on the next read??
analogRead(AnalogPort)
You have Setpoint as a variable that changes as a port to read from?

If you are able to change the direction of the stepper running at full speed,
it only means you are over currenting the stepper and have no inertial
load on the output.
Dwight

This cheap fleabay sucker "HY-DIV268N-5A"
Is giving me some trouble.
There is optocouplers on the inputs, but the direction input is wery sensitive.
It will not work with the examples in IDE.
I can see the output from the Arduino is pulsing with a Scope, but voltage as low as 100mV will still hold the Input HIGH.
Ill try with another optocoupler.

Maybe i have to try with some transistors between Arduino pins and Input.
Have tried with PullDown, Pullup, Negative Switching and Positive Switching.

I will try with an Easydriver, when it drops down in my Mailbox, eliminating problems with my code.

And then maybe try with transistors on the Driver input driven from the Arduino pins.

Lars

Also, you may want to read up on PID controllers.
Dwight

dwightthinker:
I don't think this is a good idea:

Setpoint = analogRead(Setpoint);

If you do an analog read Setpoint changes and who knows
what it does with it on the next read??
analogRead(AnalogPort)
You have Setpoint as a variable that changes as a port to read from?

If you are able to change the direction of the stepper running at full speed,
it only means you are over currenting the stepper and have no inertial
load on the output.
Dwight

It looks like this was the problem. It now runs without any Hysteresis at all.
I did map the signal 0-100% thou.

I also added an LCD, to show the Feedback. ( needs some tuning ).

I will probably add som filtering later on, when the Valve is connected ( only running with pots now ).
And use wirewound potentiometers.

By the way!
I am reading on PID. Do not think i need it for this code.
But am working on a Speed Controller on an Engine Dyno.
So i will need to meassure the revs of the engine, implement a PID, and use the output to set the "Setpoint" of this Valve. (This Valve will brake the Engine).

Thanks!
LarsPerformance

If there is any lag in time between when you send
something to be controlled and when you receive an update
on the result, you will need some form of PID or suffer
poor response. If you try to improve the response, it can
break into oscillations. On an engine dyno, this can be dangerous.
The lag can be simply time delay or inertia of what is being controlled.
It is just life in the real world with real things.
You can often get by with proportional if the gain of the loop ( the control
loop ) is small. This mean poor response and it never reaches the proper level.
In some case a PD or a PI can work when compensating for some
factor of the control loop. Setting up a PID is not hard. The math is easy
but the coefficients can take some time to get right.
Do a search for calibrating PID coefficients. Many temperature controllers
manuals can be useful.
Dwight

Thanks for the responce!

By the way, im working as Automation Technician.
I do know a couple of things about PID, and the real world.

The problem for me is the Code.
Im pretty new to Arduino.
But im getting there.
There is a lot of Arduino stuff to do in the Car/Engine World. So i have to Learn.

Im pretty sure i will get away with PI, since this is a pretty fast reacting prosess.

There is a Capacity regulating valve on the Brake-Absorber that adjusts the maximum Torque. (Will probably put a Stepper on this later on).

So im trying to use Fixed parameters in the Code for kP, kI, kD. If it is to slow. It is possible to crank the Knob on the Absorber. To get better responce.

I was also thinking about putting the kP, kI, on potentiometers. But i am afraid of the Users to adjust it out of Tune. When im not there. (Keep it Simple, or they will Fu%# Up).

Ill Update the Post when i have my Computer.(code)

Lars Performance

Usually when I do PID, I keep every thing as integers but most
like floating point.
I find integers work well if the I is a double precision and I use
the MSBs as the part of the I that goes to the control.
The amount to add to the LSBs as the coefficient for the I term.
Using it this way, means there is no division in the math, just
a fetch.
Scaling is simpler.
At most you might use a shift on the output.
I hope this makes some sense. ( avoid floating point that little
8 bitters really don't like ).
Dwight

Larsperformance:
Having trouble with changing the directions on a stepper.
If i connect 5V to the Direction Pin on my Driver. It wil Reverse.
But What am i missing on the AnalogRead part here?
The Motor will not run Consistent, and will not Reverse based on my Inputs.
LarsPerformance

Hello Larsperformance , I posted on another one of your threads , and see you have made some progress here.

What brand water brake engine dyno are you trying to control load on ? Any pictures ?

How is this project coming along using a Arduino UNO R3 to control a Stepper motor NEMA17 to open and close a water gate valve ?

Bye