Using PID and encoders to go in a straight line

Hello,

I'm making a robot that needs to go in a straight line. For that I'm using :

  • Arduino UNO
  • 2 DC motors
  • 2 encoders

I've written the code with PID but I don't know how to convert the speed into a voltage. Anyone can help me?
Here's my code :

#include <PID_v1.h>

#define encoder1 2
#define encoder2 3
#define motor1a 9
#define motor1b 6 
#define motor2a 7
#define motor2b 5

byte tension1 = 180;
byte tension2 = 180;
long newposition1;
long oldposition1;
long newposition2;
long oldposition2;
long newtime;
long oldtime;
volatile int num1 = 0;
volatile int num2 = 0;
float speed1;
float speed2;

double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
double Kp=?, Ki=?, Kd=?;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup()
{
  pinMode(encoder1,INPUT_PULLUP);
  pinMode(encoder2,INPUT_PULLUP);
  pinMode(motor1a,OUTPUT);
  pinMode(motor1b,OUTPUT);
  pinMode(motor2a,OUTPUT);
  pinMode(motor2b,OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2),count1,FALLING);
  attachInterrupt(digitalPinToInterrupt(3),count2,FALLING);
  Serial.begin(9600);
  
  SetOutputLimits(?);
  SetSampleTime(100);
  Setpoint = speed1;
  Input = speed2;

  myPID.SetMode(AUTOMATIC);
}

void loop()
{
  analogWrite(motor1a,tension1);
  analogWrite(motor2a,tension2);
  newposition1 = num1;
  newposition2 = num2;
  newtime = millis();
  speed1 = (newposition1-oldposition1)/(newtime-oldtime);
  speed2 = (newposition2-oldposition2)/(newtime-oldtime);
  Serial.print("speed1=");
  Serial.print(speed1);
  Serial.print("speed2=");
  Serial.print(speed2);
  Serial.println();
  oldposition1=newposition1;
  oldposition2=newposition2;
  oldtime=newtime;
  
  Input = speed2;
  myPID.Compute();
  speed2 = Output;


  if (speed2 < speed1) {
    tension2 = tension2 + 1;
  }
  else if (speed2 > speed1) {
    tension2 = tension2 - 1;
  }
  else {
    tension2 = tension2;
  }
}

void count1() {
  num1 = num1 + 1;
}

void count2() {
  num2 = num2 + 2;
}

What is the range of values that your variable called output can take?

And how do you want that range to be interpreted?

Separately I will be surprised if your 'bot moves in a straight line for more than a short distance without some external direction reference - such as a white line on the floor.

...R

A movement requires a speed, and that is what a PID and encoder can regulate. In your case you'll use 2 PIDs, one for each wheel, with a common speed set point.

In practice every speed difference will result in a curved instead of a straight line. This is what Robin means, and all these tiny curves can sum up to weird movements without any external references.