something missing when calculating Analog values?

I'm adapting the serial input version of a sketch to use analog input values 0-5vdc. I noted the code to explain what I'm doing. Everything works except when it displays analog read value I get the correct value, but moving to value (TravelA) is incorrect. Instead, I'm getting 14194 as TravelA value when my analog_val =1023 . Secondly, there is no movement to that value from home (0) on the stepper regardless of what value TravelA holds. I do see pin 13 going low and the drive enables but no movement. It keeps reading the value and displaying the results as well as "moving to (TravelA value) every 10 seconds.
The homing portion works as it should, and during the troubleshooting process I ran simple analog read serial output sketch using the exact formula with expected results. Also used the original homing sketch with serial input. I manually put in the values up to 146000 down to zero also with the expected results. I'm banging my head trying to figure out why. I got this far googling and doing a lot of reading, but I'm still new to the arduino.

/*  Valve Control with Analog input
 
Created by Paul Wheeler

Based on Motor Homing code using AccelStepper and the Serial Monitor
 
Created by Yvan / https://Brainy-Bits.com

designed to proportionally control large butterfly valve using 0-5VDC input
from Building Management System

*/

#include "AccelStepper.h" 

// AccelStepper Setup
AccelStepper stepperX(1, 2, 3);    // Pin 2 connected to PUL- pin of Driver PUL+ connected to 5v+
                                  // Pin 3 connected to DIR- pin of Driver DIR+ connected to 5v+

// Define the Pins used
#define home_switch 9 // Pin 9 connected to Home Switch (MicroSwitch N/O)
#define ENA 13 //pin 13 is to drive ENA+ and ENA- connected to GND
#define ANALOG_IN A0 //analog 0-5VDC input + to A0 - to GND (External power source)

// Stepper Travel Variables
long TravelA;  // Used to store the first travel value 
int move_finished=1;  // Used to check if move is completed
long initial_homing=-1;  // Used to Home Stepper at startup


void setup() {
   analogReference(EXTERNAL); //reference external 5V power source
   Serial.begin(9600);  // Start the Serial monitor with speed of 9600 Bauds to monitor if needed
  
   
   pinMode(home_switch, INPUT_PULLUP);
   pinMode(ENA, OUTPUT);          // sets the digital pin 13 as output
   
  
   digitalWrite(ENA, LOW);       // sets digital pin 13 enabling drive

   //  Set Max Speed and Acceleration of each Steppers at startup for homing
  stepperX.setMaxSpeed(4000.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  stepperX.setAcceleration(2000.0);  // Set Acceleration of Stepper
 

// Start Homing procedure of Stepper Motor at startup

  Serial.print("Stepper is Homing . . . . . . . . . . . ");

  while (digitalRead(home_switch)) {  // Make the Stepper move CW until the switch is activated   
    stepperX.moveTo(initial_homing);  // Set the position to move to
  
    initial_homing--;  // increase by 1 for next move if needed
    stepperX.run();  // Start moving the stepper
}

  stepperX.setCurrentPosition(0);  // Set the current position as zero for now
  stepperX.setMaxSpeed(4000.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  stepperX.setAcceleration(2000.0);  // Set Acceleration of Stepper
  initial_homing=1;

  while (!digitalRead(home_switch)) { // Make the Stepper move CCW until the switch is deactivated
    stepperX.moveTo(initial_homing);  
    stepperX.run();
    initial_homing++;
  }
  
  stepperX.setCurrentPosition(0);
  digitalWrite(ENA, HIGH);        // sets digital pin 13 disabling drive
  Serial.println("Homing Completed");
  Serial.println("");
  stepperX.setMaxSpeed(4000.0);      // Set Max Speed of Stepper (Faster for regular movements)
  stepperX.setAcceleration(2000.0);  // Set Acceleration of Stepper
  
}

void loop() {

 // Read new position after 10 seconds
 delay (10000);
  int analog_val = analogRead(ANALOG_IN);
  
  move_finished=0;  // Set variable for checking move of the Stepper
   Serial.println(analog_val); //for monitoring
  long TravelA = (analog_val*142); // need close to 146000 steps to get from home(closed) to full Open
  if (TravelA < 0 || TravelA > 146000) {  // Make sure the position calculated is not outside of the HOME or MAX position
   } else {
    Serial.print("Moving stepper into position: ");
    Serial.println(TravelA);
    
  
  digitalWrite(ENA, LOW);       // sets digital pin 13 enabling drive

  stepperX.moveTo(TravelA);  // Set new moveto position of Stepper
  
  delay(1000);  // Wait 1 seconds before moving the Stepper
  }
  

  if (TravelA >= 0 && TravelA <= 146000) {
  
// Check if the Stepper has reached desired position
  if ((stepperX.distanceToGo() != 0)) {
    
   stepperX.run();  // Move Stepper into position
    
  }

// If move is completed display message on Serial Monitor
  if ((move_finished == 0) && (stepperX.distanceToGo() == 0)) {
    Serial.println("COMPLETED!");
    move_finished=1;  // Reset move variable
  digitalWrite(ENA, HIGH);       // sets digital pin 13 disabling drive
  }
  }
}
  long TravelA = ( analog_val * 142L );

Thank you! It worked. I have the correct numbers but still no movement. My apologies I forgot to mention I'm running this on an UNO and using a HBS860H driver for my stepper.

What do the prints tell you is going-on?

the prints give me analog_val then "Moving Stepper into position:" and the TravelA value (which is now correct). Also the drive enables on initial reading and stays enabled while it keeps reading every 10 seconds.

  while (!digitalRead(home_switch)) { // Make the Stepper move CCW until the switch is deactivated
    stepperX.moveTo(initial_homing); 
    stepperX.run();
    initial_homing++;
  }

I really would expect you to KNOW how many steps this takes, and just step that number of times.

// Check if the Stepper has reached desired position
  if ((stepperX.distanceToGo() != 0)) {
   
   stepperX.run();  // Move Stepper into position
   
  }

If you call run(), and the stepper is at the commanded position, run() will do nothing. So the if statement is unnecessary.

Disabling the motor means that it will not hold position. Is that what you want?

Your indentation is awful. With Tools + Auto Format so easy to use, there is no excuse for that.

I think it would be useful to print the distanceToGo() value periodically.

You don't need this

 if ((stepperX.distanceToGo() != 0)) {
   
   stepperX.run();  // Move Stepper into position
   
  }

just have

stepperX.run();

and it will automatically stop when it gets to the destination.

And DO NOT use delay() as it prevents stepperX.run() from being called as frequently as it should. Have a look at how millis() is used to manage timing without blocking inSeveral Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

...R

Paul S. ,
Apologies for the sloppy indentation. I am still new to this type of code and in the learning process. Thank you for your time and the tip.
I do NOT know how many steps it takes to get to home If power is removed while the valve is off Home (closed )position. This is there in case of power interruption and the quarter turn valve is in partial or open position.
Disabling the drive is fine for this application. The stepper is coupled to a 50:1 gearbox which is coupled to the gear drive on a 350mm (14 inch) butterfly valve. It would require forces greater than what exists to move the valve by flow alone.

Robin,

Thank you for your time and advice. Most of those delays were in the original sketch I had adapted, and probably there for the authors driver. I have removed most of them with no ill effects and I will look into cleaning the rest of the delays up. the only one I do need to keep is the 10 second delay. that would be the rate at which the Arduino will look at the analog input for any changes.

The whole reason for this project is to control a diversion valve on a condenser water circuit, so we can close loop the water through the chiller during the spring, and fall months without damaging the compressors PaulS You seem to be in the same area, you would understand the climate. The cooling tower water is too cold at startup so we need to "preheat" the condenser circuit before introducing colder water. Our building management software measures the temperatures and provides the logic. We have it set to provide an analog output 0-5VDC.

So I made the changes to the code and still getting the same results. No motor movement with analog values. When I made the recommended changes this is the output on the serial monitor after 2 measurements at 5VDC :

Stepper is Homing . . . . . . . . . . . Homing Completed

1023
Moving stepper into position: 145266
1023
Moving stepper into position: 145266

this is the changed code;

/*  Valve Control with Analog input

  Created by Paul Wheeler

  Based on Motor Homing code using AccelStepper and the Serial Monitor

  Created by Yvan / https://Brainy-Bits.com

  designed to proportionally control large butterfly valve using 0-5VDC input
  from Building Management System

*/

#include "AccelStepper.h"

// AccelStepper Setup
AccelStepper stepperX(1, 2, 3);    // Pin 2 connected to PUL- pin of Driver PUL+ connected to 5v+
// Pin 3 connected to DIR- pin of Driver DIR+ connected to 5v+

// Define the Pins used
#define home_switch 9 // Pin 9 connected to Home Switch (MicroSwitch N/O)
#define ENA 13 //pin 13 is to drive ENA+ and ENA- connected to GND
#define ANALOG_IN A0 //analog 0-5VDC input + to A0 - to GND (External power source)

// Stepper Travel Variables
long TravelA;  // Used to store the first travel value
int move_finished = 1; // Used to check if move is completed
long initial_homing = -1; // Used to Home Stepper at startup


void setup() {
  analogReference(EXTERNAL); //reference external 5V power source
  Serial.begin(9600);  // Start the Serial monitor with speed of 9600 Bauds to monitor if needed


  pinMode(home_switch, INPUT_PULLUP);
  pinMode(ENA, OUTPUT);          // sets the digital pin 13 as output


  digitalWrite(ENA, LOW);       // sets digital pin 13 enabling drive

  //  Set Max Speed and Acceleration of each Steppers at startup for homing
  stepperX.setMaxSpeed(4000.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  stepperX.setAcceleration(2000.0);  // Set Acceleration of Stepper


  // Start Homing procedure of Stepper Motor at startup

  Serial.print("Stepper is Homing . . . . . . . . . . . ");

  while (digitalRead(home_switch)) {  // Make the Stepper move CW until the switch is activated
    stepperX.moveTo(initial_homing);  // Set the position to move to

    initial_homing--;  // increase by 1 for next move if needed
    stepperX.run();  // Start moving the stepper
  }

  stepperX.setCurrentPosition(0);  // Set the current position as zero for now
  stepperX.setMaxSpeed(4000.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  stepperX.setAcceleration(2000.0);  // Set Acceleration of Stepper
  initial_homing = 1;

  while (!digitalRead(home_switch)) { // Make the Stepper move CCW until the switch is deactivated
    stepperX.moveTo(initial_homing);
    stepperX.run();
    initial_homing++;
  }

  stepperX.setCurrentPosition(0);
  digitalWrite(ENA, HIGH);        // sets digital pin 13 disabling drive
  Serial.println("Homing Completed");
  Serial.println("");
  stepperX.setMaxSpeed(4000.0);      // Set Max Speed of Stepper (Faster for regular movements)
  stepperX.setAcceleration(2000.0);  // Set Acceleration of Stepper

}

void loop() {

  // Read new position after 10 seconds
  delay (10000);
  int analog_val = analogRead(ANALOG_IN);

  move_finished = 0; // Set variable for checking move of the Stepper
  Serial.println(analog_val); //for monitoring
  long TravelA = (analog_val * 142L); // need close to 146000 steps to get from home(closed) to full Open
  if (TravelA < 0 || TravelA > 146000) {  // Make sure the position calculated is not outside of the HOME or MAX position
  } else {
    Serial.print("Moving stepper into position: ");
    Serial.println(TravelA);


    digitalWrite(ENA, LOW);       // sets digital pin 13 enabling drive

    stepperX.moveTo(TravelA);  // Set new moveto position of Stepper


  }


  if (TravelA >= 0 && TravelA <= 146000) {


    stepperX.run();  // Move Stepper into position

  }

  // If move is completed display message on Serial Monitor
  if ((move_finished == 0) && (stepperX.distanceToGo() == 0)) {
    Serial.println("COMPLETED!");
    move_finished = 1; // Reset move variable
    digitalWrite(ENA, HIGH);       // sets digital pin 13 disabling drive
  }
}

pwheeler:
the only one I do need to keep is the 10 second delay. that would be the rate at which the Arduino will look at the analog input for any changes.

But do not use delay() for that purpose. Use millis() for non-blocking timing.

The motor needs to keep stepping during those 10 seconds.

...R

Actually this instance the delay works for me because I don't want anything else going on for the set time period. I set it at 10 seconds for testing purposes. In actual implementation the delay will be extended to 30 seconds, which is more than ample time. I need to keep the drive off, and the changes coming in from the control will be less frequent than that. My issue is it will not run after homing when I have an analog input. I tried using the milli() as suggested to see if it would change anything but ended up with the same results. I got the values correct based on my serial reports. I may be missing something particular with this library, I'm not sure.

pwheeler:
Actually this instance the delay works for me because I don't want anything else going on for the set time period. I set it at 10 seconds for testing purposes. In actual implementation the delay will be extended to 30 seconds, which is more than ample time. I need to keep the drive off, and the changes coming in from the control will be less frequent than that. My issue is it will not run after homing when I have an analog input.

That is not surprising. Because of your 10 second delay() these lines

  if (TravelA >= 0 && TravelA <= 146000) {


    stepperX.run();  // Move Stepper into position

  }

can only be called once every 10 seconds. The function stepperX.run() needs to be called many times per second.

I tried using the milli() as suggested to see if it would change anything but ended up with the same results.

I can't comment on that because you have not posted the program in which you tried it.

...R

OK so my problem was in the stepperX.run(); command. with the code originally, my loop() the flow was like this:
wait 10s -> read value -> make sure position is not outside the HOME or MAX positions -> set new target position -> take ONE step if a step is due -> check for movement completed never returns true -> wait 10s -> read value ->...

I ended up using the millis() but extended it to 30 second interval and its working flawless. this is the current working code;

/*  Valve Control with Analog input v2

  Created by Paul Wheeler

  designed to proportionally control large butterfly valve using 0-5VDC input
  from Building Management System

*/

#include "AccelStepper.h"

#define ANALOG_READ_INTERVAL 30000  //30000ms

// AccelStepper Setup
AccelStepper stepperX(1, 2, 3);    // Pin 2 connected to PUL- pin of Driver PUL+ connected to 5v+
// Pin 3 connected to DIR- pin of Driver DIR+ connected to 5v+

// Define the Pins used
#define home_switch 9 // Pin 9 connected to Home Switch (MicroSwitch N/O)
#define ENA 13 //pin 13 is to drive ENA+ and ENA- connected to GND
#define ANALOG_IN A0 //analog 0-5VDC input + to A0 - to GND (External power source)

// Stepper Travel Variables
long TravelA;  // Used to store the first travel value
int move_finished = 1; // Used to check if move is completed
long initial_homing = -1; // Used to Home Stepper at startup

unsigned long time_last_analog_read = 0L;       //last time the analog value was read
    // Read new position every 10 seconds
    if (millis() - time_last_analog_read > ANALOG_READ_INTERVAL)
    {
      time_last_analog_read = millis();     //reset timer

      int analog_val = analogRead(ANALOG_IN);

      move_finished = 0; // Set variable for checking move of the Stepper
      Serial.println(analog_val); //for monitoring
      long TravelA = (analog_val * 142L); // need close to 146000 steps to get from home(closed) to full Open
      if (TravelA < 0 || TravelA > 146000) {  // Make sure the position calculated is not outside of the HOME or MAX position
      } else {
        Serial.print("Moving stepper into position: ");
        Serial.println(TravelA);

      }


      if (TravelA >= 0 && TravelA <= 146000) {
        digitalWrite(ENA, LOW);       // sets digital pin 13 enabling drive

        stepperX.moveTo(TravelA);  // Set new moveto position of Stepper
      }
    }

    // If move is completed display message on Serial Monitor
    if ((move_finished == 0) && (stepperX.distanceToGo() == 0)) {
        Serial.println("COMPLETED!");
        move_finished = 1; // Reset move variable
        digitalWrite(ENA, HIGH);       // sets digital pin 13 disabling drive
    }

pwheeler:
I ended up using the millis() but extended it to 30 second interval and its working flawless.

Good to hear it is working.

For the future, always post a complete program so we can see everything in context.

...R