Potentiometer giving wrong values when going from 0 to 100

Hi guys,

I am trying to control a stepper motor using a potentiometer. Everythibg seems fine but the problem is that the potentiometer value jumps drastically while going from 0 to 100. But when coming down from 100 to 0 the output values seems to be fine. Your help is highly appreciated.

Sketch:

#include <Stepper.h>

const int stepsPerRevolution = 400; // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 12, 13);

int stepCount = 0;
int buttonState = 0;

const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
const int pwmA = 3;
const int pwmB = 11;
const int brakeA = 9;
const int brakeB = 8;
const int dirA = 12;
const int dirB = 13;

void setup() {

Serial.begin(9600);

pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
pinMode(pwmA, OUTPUT);
pinMode(pwmB, OUTPUT);
pinMode(brakeA, OUTPUT);
pinMode(brakeB, OUTPUT);
digitalWrite(pwmA, HIGH);
digitalWrite(pwmB, HIGH);
digitalWrite(brakeA, LOW);
digitalWrite(brakeB, LOW);
}

void loop() {

buttonState = digitalRead(buttonPin);
if (buttonState == HIGH)
{

digitalWrite(ledPin, HIGH);
int sensorReading = analogRead(A0);

int motorSpeed = map(sensorReading, 0, 1023, 0, 100);

myStepper.setSpeed(motorSpeed);

myStepper.step(stepsPerRevolution / 100);
Serial.println(motorSpeed);

}
else
{
digitalWrite(ledPin, HIGH);
int sensorReading = analogRead(A0);

int motorSpeed = map(sensorReading, 0, 1023, 0, 100);

myStepper.setSpeed(motorSpeed);

myStepper.step(-stepsPerRevolution / 100);
Serial.println(motorSpeed);

}
}

How are you powering the motor? Is Arduino powered from same source?
As pot goes up motor accelerates, draws more current, more load on PS, voltage droops, signal from pot droops, ADC value droops.
As pot goes down motor slows, less current, no droop, no ADC droop.

Maybe? :grin:

The motor is powered through a wall wart dc supply, while the arduino is powered through the USB.

I have had some sketches that would be very inaccurate without a small delay between of before analogread() (for multiple analog readings though, i really don't know if this is a problem with just one ). Just a thought!

"I am trying to control a stepper motor using a potentiometer. Everythibg seems fine but the problem is that the potentiometer value jumps drastically while going from 0 to 100. But when coming down from 100 to 0 the output values seems to be fine."

Is it like that with the motor disconnected?

Yes it is same.

Can you try a different potentiometer ?

...R

I tried two different potentiometer

Robin2:
Can you try a different potentiometer ?

...R

I tried two different potentiometers (one with 10 rounds) but same problem.

Regards,

Add a 100nF cap between the analog pin and ground - does that improve the readings?
If so then you have scratchy pots or lots of noise getting into the analog signals. Do you
have tight layout for the potentiometer cable and motor wiring?

MarkT:
Add a 100nF cap between the analog pin and ground - does that improve the readings?
If so then you have scratchy pots or lots of noise getting into the analog signals. Do you
have tight layout for the potentiometer cable and motor wiring?

No improvements.

The value goes decreases gradually from 100 to 10 with 10 - 20 degree rotation of the potentiometer.

Ah, you have a log-taper potentiometer! You need a linear taper one.

MarkT:
Ah, you have a log-taper potentiometer! You need a linear taper one.

How can i tell difference between them? Do they look different?
I have B10K potentiometer. (photo attached)

B10.PNG

B is usually linear, but there are variations in coding.

You measure if its linear.

Set it to mid-travel and see if the analogRead() returns somewhere near 512 - if so its linear,
if its very different its log or anti-log.

Have you actually measured the speed of your motor with the pot set to 0%, 25%, 50%, 75% and 100%
of its travel (perhaps you are confused by the brain's in-built logarithmic response to most things
(including speed))

MarkT:
Have you actually measured the speed of your motor with the pot set to 0%, 25%, 50%, 75% and 100%
of its travel (perhaps you are confused by the brain's in-built logarithmic response to most things
(including speed))

Yes, I tried that. But the motor speed changes only between 75% and 100%, Below 75% its moving only at 1 or 2 rpm.

Regards,

I'm running your sketch (basically)

#include <Stepper.h>
const int stepsPerRevolution = 400;  // change to fit the number of steps per rev
// for your motor
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 12, 13);
int stepCount = 0; 
int buttonState = 0;
const byte buttonPin = 2;  // pushbutton pin
const byte ledPin =  13;   // LED pin
const byte pwmA = 3;
const byte pwmB = 11;
const byte brakeA = 9;
const byte brakeB = 8;
const byte dirA = 12;
const byte dirB = 13;
void setup()
{  
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(pwmA, OUTPUT);
  pinMode(pwmB, OUTPUT);
  pinMode(brakeA, OUTPUT);
  pinMode(brakeB, OUTPUT);
  digitalWrite(pwmB, HIGH);
  digitalWrite(brakeA, LOW);
  digitalWrite(brakeB, LOW);
}
void loop() 
{
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) 
  {
    digitalWrite(ledPin, HIGH);
    int sensorReading = analogRead(A0);  
    int motorSpeed = map(sensorReading, 0, 1023, 0, 100);  
    myStepper.setSpeed(motorSpeed); 
    myStepper.step(stepsPerRevolution / 100);
    Serial.print("H  ");
    Serial.println(motorSpeed);    
  }
  else 
  {
    digitalWrite(ledPin, HIGH);
    int sensorReading = analogRead(A0);
    int motorSpeed = map(sensorReading, 0, 1023, 0, 100);  
    myStepper.setSpeed(motorSpeed);
    myStepper.step(-stepsPerRevolution / 100);
    Serial.print("L  ");
    Serial.println(motorSpeed);  
   } 
}

I changed buttonPin so that it's using the "internal pullup".
And I am using a 20K [10turn] pot (with 470ohm between the top of the pot and +5.)
I have smooth transitions throughout the range.

Hi Runaway,

I tried your code but now nothings happening, the motor is not rotating and the serial monitor also isn't showing anything.

regards,

Hi Runaway,

I tried using your code but nothings working, the motor is not moving and the serial monitor displays nothing. I have noticed one thing; when i remove the map function the readings of the potentiometer seems to be fine as they increase gradually but the values go very high and the motor stops working. Is there any other way to limit the range of the potentiometer?

regards,

Hi Runaway,

I tried using your code but nothings working, the motor is not moving and the serial monitor displays nothing. I have noticed one thing; when i remove the map function the readings of the potentiometer seems to be fine as they increase gradually but the values go very high and the motor stops working. Is there any other way to limit the range of the potentiometer?

regards,

It is not "my" code - it is yours.
The only difference is the addition of pinMode(buttonPin, INPUT_PULLUP);
and you can comment that out
and the addition of a couple of extra Serial.print to let me know buttonPin status (you can comment those out).

#include <Stepper.h>
const int stepsPerRevolution = 400; 
Stepper myStepper(stepsPerRevolution, 12, 13);
int stepCount = 0; 
int buttonState = 0;       // should be BYTE, not INT
const byte buttonPin = 2;  // pushbutton pin
const byte ledPin =  13;   // LED pin
const int pwmA = 3;
const int pwmB = 11;
const int brakeA = 9;
const int brakeB = 8;
const int dirA = 12;
const int dirB = 13;
void setup()
{  
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  //pinMode(buttonPin, INPUT_PULLUP);
  pinMode(pwmA, OUTPUT);
  pinMode(pwmB, OUTPUT);
  pinMode(brakeA, OUTPUT);
  pinMode(brakeB, OUTPUT);
  digitalWrite(pwmB, HIGH);
  digitalWrite(brakeA, LOW);
  digitalWrite(brakeB, LOW);
}
void loop() 
{
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) 
  {
    digitalWrite(ledPin, HIGH);
    int sensorReading = analogRead(A0);  
    int motorSpeed = map(sensorReading, 0, 1023, 0, 100);  
    myStepper.setSpeed(motorSpeed); 
    myStepper.step(stepsPerRevolution / 100);
    //Serial.print("H  ");
    Serial.println(motorSpeed);    
  }
  else 
  {
    digitalWrite(ledPin, HIGH);
    int sensorReading = analogRead(A0);
    int motorSpeed = map(sensorReading, 0, 1023, 0, 100);  
    myStepper.setSpeed(motorSpeed);
    myStepper.step(-stepsPerRevolution / 100);
    //Serial.print("L  ");
    Serial.println(motorSpeed); 
   } 
}

I changed all of the CONSTs from INT to BYTE.
That may have been OK for testing the pot circuit, which was all that I was interested in, but not good for the other stuff.
So, I changed those back (above).
Still OK here (smooth 0-100 and 100-0)

Hi Runaway,

Thanks alot for the help. the code is working great now, but the only problem is that when the potentiometer value is zero the code stops. To continue the reset (on the motor shield) button has to be pressed.

I am also facing another problem, the code dosent work if I power he Arduino directly through a Wall Wart supply ( 5V 1A) but works fine when powered through USB cable. Any idea why is that?

#include <Stepper.h>

const int stepsPerRevolution = 400;  



Stepper myStepper(stepsPerRevolution, 12, 13);

int stepCount = 0; 
int buttonState = 0;


const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin
const int pwmA = 3;
const int pwmB = 11;
const int brakeA = 9;
const int brakeB = 8;
const int dirA = 12;
const int dirB = 13;

int potPin = 2;    // select the input pin for the potentiometer

int val = 0;   
int motorSpeed = 0;// variable to store the value coming from the sensor

void setup() {

  pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
pinMode(pwmA, OUTPUT);
pinMode(pwmB, OUTPUT);
pinMode(brakeA, OUTPUT);
pinMode(brakeB, OUTPUT);
digitalWrite(pwmA, HIGH);
digitalWrite(pwmB, HIGH);
digitalWrite(brakeA, LOW);
digitalWrite(brakeB, LOW);
pinMode(ledPin, OUTPUT);  // declare the ledPin as an OUTPUT
Serial.begin(9600);
}

void loop() {
    
  buttonState = digitalRead(buttonPin);
 if (buttonState == HIGH)
 {
  val = analogRead(potPin);  
  motorSpeed = map(val, 0, 1023, 0, 100);
  myStepper.setSpeed(motorSpeed);
  myStepper.step(stepsPerRevolution / 100);
  Serial.print("CW  ");
  Serial.println(motorSpeed);
  digitalWrite(ledPin, HIGH); 
 }
 else
 {
  val = analogRead(potPin);  
  motorSpeed = map(val, 0, 1023, 0, 100);
  myStepper.setSpeed(motorSpeed);
  myStepper.step(-stepsPerRevolution / 100);
  Serial.print("CCW  ");
  Serial.println(motorSpeed);
  digitalWrite(ledPin, HIGH);
 }
}