Tracking the value of a potentiometer by stepping motor

What's that you are using for a limit switch? How is it connected? Do you have a pullup or pulldown resistor connected to pin 4 so it does not "float" when the switch is open?

Thanks DaveX,
you are very kind and thoughtful.

Ciao JCA34F,
Sto usando un relè reed che ho trovato nel cassetto.
C'è una foto del motore con il relè reed e una specie di indicatore che ha un magnete sulla punta.
Sì, ho messo una resistenza di pulldown.

The software is almost ready, but I have a problem that I cannot solve.
How can I make arduino reading VERY stable.
I have tried several solutions, but it seems that the reading from the arduino A0 channel is randomly interpreted around the read value.
The first solution I adopted was to stabilize the reading with an external circuit by feeding the arduino with a variable voltage from 0 to 4.9V, and this value is very stable.
I get variations over time (1 minute) from 0.1 to 0.3 volts.
But despite this, arduino always reads unstable values with variations from 0.1 volts and sometimes up to 2 volts.
Where am I wrong?
What could be causing this problem?
Could it be due to the wiring on the breadboard?

If the EWMA in Tracking the value of a potentiometer by stepping motor - #37 by DaveX isn't smooth enough, you can use a deadband.

You can check if it is your breadboard by using another pot to simulate the breadboard's or external circuit's input.

Hi DaveX,
you have to excuse me but I don't understand what you are saying.
What should i use?!
I am using the rotor potentiometer these tests were done in the field

I'm saying that if your breadboard wiring is inducing the noise, it would induce it on a pot on your bench.

If it is clean on a bench pot, then the noise is coming from the pot on the rotor and the wires in between, and you need to filter it more strongly, either in code before your control loop, or in silicon before it gets to your ADC.

Hi DaveX,
then I can say that I am satisfied, I found an article on the web that talked about this problem, and using this code the value was much more stable and maintains a good variation
This is the article:

e questo è il codice che ho applicato.

/*
 * Version 1.0 02/03/2022 
 * This program allows you to align the antenna rotor control box needle, 
 * using a stepper motor in order to replace the original mechanism contained 
 * in the control box that works with the belt.
*/

#include "Stepper.h"

// change this to the number of steps on your motor
#define STEPS 64
Stepper stepper(STEPS, 11, 9, 10, 8);

bool debug = true;    // enable or disable debug, false disabled
bool motorOff = false; //
bool motorOn = true;   // 
bool allign = false;   // used in allingment routine
bool initial = true;   // used to fix initial position

int vol_val = 0;
int previous = 0;      // previous rotor position
int mapVal;            // mapped input value
int analogPin = 0;     // rotor input sensor
int button = 2;        // adjust gauge button
int ledButton = 3;     // led button indicator
int zero = 4;          // zero/limit stepper switch
int ledZero = 5;       // led zero stepper position indicator
int rotorPos;          // actual rotor position

void setup() {
  stepper.setSpeed(512);    // set the motor speed to 500 RPMs
  if(debug){
     Serial.begin(9600);    // debugging enabled/disable
  }
  pinMode(ledButton,OUTPUT);
  pinMode(button,INPUT);
  digitalWrite(ledButton,LOW);
  pinMode(ledZero,OUTPUT);
  pinMode(zero,INPUT);
  digitalWrite(ledZero,LOW);
  
}

void loop() {

  static unsigned long lastMotion = 0;
  static bool motorOn = false;
  readRotor();

  if (mapVal != previous){
     stepper.step(previous-mapVal);
     lastMotion = millis();
     motorOn = true;
     previous = mapVal;           // remember the previous value of sensor
  }
  if (digitalRead(button)==LOW){
     digitalWrite(ledButton,LOW); // button pressed control led
     delay(300);
     allign = false;
     gotoHome();                  // gauge alignment routine
  }
  if (digitalRead(zero) == LOW){  // reached the zero point, Zero LED goes on
     digitalWrite(ledZero,HIGH);
  } else {
     digitalWrite(ledZero,LOW);
  }       

}  

void readRotor() {                          // reads the rotor position

//  static float smoothedVal = analogRead(analogPin);
//  int val = analogRead(analogPin);          // get the sensor value
//  smoothedVal += 0.1 * (val - smoothedVal); // smaller = smoother modify this value from 0.1 to 0.001
//  mapVal = map(smoothedVal,0,305,0,2050);   // limits the variations of the read value

  int read_val = 0;
  for (byte i = 0 ; i < 10 ; i++)
  { read_val += analogRead(A0); }
  vol_val = vol_val * 0.9 + (read_val / 10) * 0.1;
  mapVal = map(vol_val,19,1013,0,2050);
  //mapVal = vol_val;
  Serial.print(read_val);
  Serial.print(" - ");
  Serial.print(vol_val);
  Serial.print(" - ");
  Serial.println(mapVal);
}


// gauge alignment routine.
// by pressing the button the system aligns the stepper motor to the zero point. 
// This allows you to align the gauge in case it has moved.
// Once aligned, pressing the button again exits the alignment and the gauge 
// returns to the position read by the rotor.

void gotoHome(void) {                  // alling gudge routine

  while(allign==false){ 
       stepper.step(1);                // Clockwise
       delay(1);
       if (digitalRead(zero) == LOW){  // reached the zero point, data supplied by a reed relay positioned in the zero point
          digitalWrite(ledZero,HIGH);  // zero LED on
          allign=true;                 // exit loop
       } else {
          digitalWrite(ledZero,LOW);   // zero LED off
       }       
   }

   pauseMotor();                                     // stop the stepper motor power
   while(digitalRead(button)==LOW){ delay(300); }    // wait until button is pressed again 
   readRotor();                                      // read rotor position
   stepper.step(-mapVal);                            // counterclockwise
}   

// in theory this routine should turn off the stepper motor, 
// this should avoid unnecessary overheating of the voltage reducers and the stepper motor. 
// In reality all the LEDs should go out, but but some remain on, 
// perhaps the library keeps the output channels active.
// You need to modify the library for this to be possible.

void pauseMotor() {              // Stop stepper
  
    digitalWrite(11,LOW);
    digitalWrite(9,LOW);
    digitalWrite(10,LOW);
    digitalWrite(8,LOW);

}

Now I have to switch off the engine once I have reached the desired point but it must be switched on again immediately as soon as there are any changes.
Suggestions ?

Something like Tracking the value of a potentiometer by stepping motor - #57 by DaveX etc. and maybe a small deadband.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.