How do i control the position of my dc motor by using a pot?

I have a diy h bridge, encoder, dc motor and a pot. how do i program it so that whenever i turn my pot, the motor will turn exactly how the pot is turning?
For example, whenever im turning my pot to 90 degree angle, the motor will also do the same.

Have you got the encoder working?

Seems like the kind of thing that'd be easier to do with a servo.

CrossRoads:
Seems like the kind of thing that'd be easier to do with a servo.

Well the question is "how do I make a servo", so lets answer that.

You need a control loop - something like a PID controller library is just the ticket.

Then you need to calculate an error input to the PID controller, here the
difference between desired position and current position (pot value - encoder
position value).

The PID output drives the H-bridge (absolute value -> PWM, sign -> direction),

then you just have to tune the PID loop.

I tried using this code. But nothing came out.

const int clkPinA = 2;
const int dirPinA = 4;
volatile int encoderACount = 0;
volatile boolean changeFlag = false;

void setup() {
Serial.begin(9600);
pinMode(clkPinA, INPUT);
pinMode(dirPinA, INPUT);
attachInterrupt(0, encoderIntA, RISING);
}

void loop() {
if (changeFlag) {
changeFlag = false;
Serial.println(encoderACount);
}
}

void encoderIntA() {
if (digitalRead(dirPinA) == HIGH)
encoderACount++;
else
encoderACount--;
changeFlag = true;
}

MarkT:

CrossRoads:
Seems like the kind of thing that'd be easier to do with a servo.

Well the question is "how do I make a servo", so lets answer that.

You need a control loop - something like a PID controller library is just the ticket.

Then you need to calculate an error input to the PID controller, here the
difference between desired position and current position (pot value - encoder
position value).

The PID output drives the H-bridge (absolute value -> PWM, sign -> direction),

then you just have to tune the PID loop.

What do you mean by the PID controller?

PIC controller

Please use code tags when posting code.

This is the arduino code. but its not working.

const int clkPinA = 2;
const int dirPinA = 4;
volatile int encoderACount = 0;
volatile boolean changeFlag = false;

void setup() {
  Serial.begin(9600);
  pinMode(clkPinA, INPUT);  
  pinMode(dirPinA, INPUT);  
  attachInterrupt(0, encoderIntA, RISING);
}

void loop() {
 if (changeFlag) {
    changeFlag = false;
    Serial.println(encoderACount);
  }
}

void encoderIntA() {
  if (digitalRead(dirPinA) == HIGH)
    encoderACount++;
  else
    encoderACount--;
  changeFlag = true;
}

How have you wired this up?
Is pin 4 able to generate an interrupt?
What do you mean by not work? Please explain what you see and what you expect to see.

Grumpy_Mike:
How have you wired this up?
Is pin 4 able to generate an interrupt?
What do you mean by not work? Please explain what you see and what you expect to see.

my encoder have 4 pins. supply, ground, signal A and signal B. I see nothing on the serial monitor when I rotate the encoder.

AWOL:
PIC controller

Please use code tags when posting code.

The PID controller is arduino code or is it another software?

I see nothing on the serial monitor when I rotate the encoder.

So forget about the interrupts for the moment and just write something to look at the two inputs. Make sure they are changing. Then worry about the interrupts.

You have got some gearing between the motor and the encoder have you?

jimmy12:

AWOL:
PIC controller

Please use code tags when posting code.

The PID controller is arduino code or is it another software?

P.I.D. - proportional, integral, differential. Not PIC!!

There'll be various libraries, you could even write your own. Search these forums.

[hint start with just proportional control - its one line of code]

oops, bloody auto-correct (the link is correct, BTW)

This code will make my motor turn clockwise, anti clockwise and stop only. How do i make my motor follow the direction of the pot? For example, how do i make my motor turn to 25 degree whenever my pot turn to 25 degree angle?

int potPin = 0; // analog input pin 0 for the potentiometer
int motor1Pin = 7; // H-bridge leg 1
int motor2Pin = 6; // H-bridge leg 2
int val = 0; // variable to store the value coming from the potentiometer

void setup() 
  {
    pinMode(motor1Pin, OUTPUT);
    pinMode(motor2Pin, OUTPUT);
  }

void loop() 
  {
  
    val = analogRead(potPin); // read the value from the potentiometer
    val = val/4; // convert 0-1023 range to 0-255 range
  
    if (val <= 85) 
    {
      digitalWrite(motor1Pin, HIGH); // set leg 1 of the H-bridge low
      delay(100);
      digitalWrite(motor2Pin, LOW); // set leg 2 of the H-bridge high
    }
  
  
    else if (val >=86 && val<=170)
    {
      digitalWrite(motor1Pin, LOW); // set leg 1 of the H-bridge low
      delay(100);
      digitalWrite(motor2Pin, LOW); // set leg 2 of the H-bridge high
    }
  
  
    else 
    {
      digitalWrite(motor1Pin, LOW); // set leg 1 of the H-bridge high
      delay(100);
      digitalWrite(motor2Pin, HIGH); // set leg 2 of the H-bridge low
    }
  }

You do it by answere in the questions that have already been asked of you.

Grumpy_Mike:
You do it by answere in the questions that have already been asked of you.

u mean PID?

jimmy12:
u mean PID?

No. I mean the questions you were asked and never answered:-
From reply#1

Have you got the encoder working?

From reply#8

How have you wired this up?

your reply of:-

my encoder have 4 pins. supply, ground, signal A and signal B.

Is not enough, schematic needed, link to encoders needed. Some encoders need pull up resistors some do not we need to rule out that.

From reply#11

So forget about the interrupts for the moment and just write something to look at the two inputs. Make sure they are changing.

Also from reply#11

You have got some gearing between the motor and the encoder have you?

If your using a simply DC motor, you will never exactly follow the pot.

If it has an encoder then actually you can but the coding can be a bit tricky. (that whole PID thing)

If you only have a simply DC motor, the best you can hope for is a close approximation which you would have to visually calibrate to achieve.

  1. learn how to read a analog value from a pot through code. (and how to wire if you don't know)
  2. figure out what kind of motor you have, the voltage, current rating....
  3. assuming you have a small DC motor of 12V or less, L293D motor driver is a easy one to start with, you'll need it if you want to change the direction of the motor in the simplest manner possible.
  4. learn how to use the L293D bad wiring tends to destroy most chips. before using code do a hard wire test, driving it with just +5V and ground wires on the inputs to prove it works.
  5. What most people do is have the pots resistance (voltage from arduino's perspective) directly linked to the speed of the motor. 0% = 0rpm, 50% = 10rpm, 100% = 20rpm.

To have it follow the pot as closely as possible you'd need to measure (change of pot value) /( change in time) and calibrate the output.

My advice, if you just want to see something spin with the pot in easiest manner possible.... Buy a $5 servo, and you'll be up and running in 5 min. The code is under examples in servo --> knob just make sure you connect to the pins they picked or modify to the ones you want.

Grumpy_Mike:
How have you wired this up?
Is pin 4 able to generate an interrupt?
What do you mean by not work? Please explain what you see and what you expect to see.

This is my encoder code and I've already attached the schematic.

int val; 
 int encoder0PinA = 3;
 int encoder0PinB = 4;
 int encoder0Pos = 0;
 int encoder0PinALast = LOW;
 int n = LOW;

 void setup() { 
   pinMode (encoder0PinA,INPUT);
   pinMode (encoder0PinB,INPUT);
   Serial.begin (9600);
 } 

 void loop() { 
   n = digitalRead(encoder0PinA);
   if ((encoder0PinALast == LOW) && (n == HIGH)) {
     if (digitalRead(encoder0PinB) == LOW) {
       encoder0Pos--;
     } else {
       encoder0Pos++;
     }
     Serial.print (encoder0Pos);
     Serial.println ("/");
   } 
   encoder0PinALast = n;
 }

And when i turn the encoder, i only get the negative values. How do i get positive and negative values?