i have used a 12v dc motor with a pot connected in the feedback .when asked to go to a certain position the dc motor goes to approx +-20 of that particular position and stops . my pot has a range from 60-960. Im using h bridge(L298N) to drive the motor and an arduino uno.
can you suggest me ways to fine it in such a way that it goes exactly that position and stops.
int enB = 5;
int pin1 = 7;
int pin2 = 6;
int pot=A0;
int CurrentValue;
int DesiredValue;
void setup()
{
pinMode(enB, OUTPUT);
pinMode(pin1, OUTPUT);
pinMode(pin2, OUTPUT);
Serial.begin(9600);
}
void loop()
{
if(Serial.available()>0)
{
DesiredValue=Serial.parseInt();
}
CurrentValue = analogRead(A0);
if(DesiredValue>CurrentValue)//left
{
digitalWrite(pin1, LOW);
digitalWrite(pin2, HIGH);
analogWrite(enB,255);
}
if (DesiredValue< CurrentValue) //right
{
digitalWrite(pin1,HIGH);
digitalWrite(pin2, LOW);
analogWrite(enB,255);
}
if(abs(DesiredValue-CurrentValue)<20)
{
CurrentValue = analogRead(A0);
analogWrite(enB,255);
digitalWrite(pin1, LOW);
digitalWrite(pin2, LOW);
}
Serial.println(CurrentValue);
}
It takes some time to stop the motor. Consequently you should reduce the speed when approaching the desired position.
Also don't reset the motor to full speed in the next iteration. Check the amount of difference before applying full speed in a direction.
Here is a sketch that I use to control the positioning of a DC brushed motor with integral pot. I use a DRV8801 motor driver. It is a simple proportional control with 2 P terms. One (smaller) P term for when the error is large to get the motor towards the set point and a larger P term for when the error is small to help keep the position close to the set point. The motor will not move for an analogWrite of 50 or less so the high P term helps to keep the position close to the set point. Set point in the range 0 to 1023.
The sketch includes a set of positions, in an array, for the motor to go to, in order.
Maybe give you some ideas
const byte potPin = A0;
const byte dirPin = 4;
const byte pwmPin = 3;
//int sp = 512;
int input = 0;
int error = 0;
byte output = 0;
byte KpLow = 1; // high error move to sp
byte KpHigh = 7; // low error keep close to sp
byte Kp = KpLow; // start low P
// an array to hold the positions to move to
const int angles[] = {30, 120, 300, 500, 800, 990};
byte numAngles;
void setup()
{
numAngles = sizeof(angles) / sizeof(angles[0]);
Serial.begin(115200);
pinMode(dirPin, OUTPUT);
digitalWrite(dirPin, HIGH);
analogWrite(pwmPin, 0);
analogRead(potPin);
}
void loop()
{
nextMove();
pTerm();
}
void nextMove()
{
static byte index = 0;
static unsigned long moveTimer = 0;
unsigned long moveInterval = 2000;
if (millis() - moveTimer >= moveInterval)
{
moveTimer = millis();
sp = angles[index];
index ++;
if(index >= numAngles)
{
index = 0;
}
}
}
void pTerm()
{
static unsigned long timer = 0;
unsigned long interval = 10;
if (micros() - timer >= interval)
{
timer = micros();
input = analogRead(potPin);
error = sp - input;
if (error < 10)
{
digitalWrite(dirPin, LOW);
Kp = KpHigh;
}
else if (error > 10)
{
digitalWrite(dirPin, HIGH);
Kp = KpHigh;
}
else
{
Kp = KpLow;
}
int output = Kp * abs(error);
if (output > 255)
{
output = 255;
}
//Serial.println(output);
analogWrite(pwmPin, output);
}
}