PID controller direction programming question

Hi!

I'm trying to build a PID controller, with an arduino. I have an uno R3 and a motor shield with the l298p chipset. The idea is to control a valve based on temperature.

The idea is that through the analog inputs (sensor value in this case a ntc (10k) with 5v reference proces value) and the second input a pot-meter (10k) (setpoint). Error = SP - PV

So the code:

#include <arduino.h>
#include <PID_v1.h>

#define PIN_INPUT 0 //setpoint
#define PIN_INPUT 1 //input
#define PIN_OUTPUT 3 //pwm output
#define PIN_OUTPUT 8 // enable motor
#define PIN_OUTPUT 12 // direction

//Define Variables
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
double Kp=2, Ki=5, Kd=1;

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup()

{
//initialize the variables we're linked to

Input = analogRead(1) /4;
// value divide by 4 (1024 / 4 = 256 for pwm output

Setpoint = analogRead(0) /4;
digitalWrite(8, HIGH);

//turn the PID on

myPID.SetMode(AUTOMATIC);

}

void loop()

{
Input = analogRead(0) /4;
Setpoint = analogRead(1) /4;
myPID.Compute();
If (analogRead(0) / 4 =< analogRead(1) /4) {
digitalWrite(12, HIGH);
analogWrite(3, output)
}
Else if (analogRead(0) / 4 => analogRead(1) /4) {
digitalWrite(12, LOW);
analogWrite(3, OUTPUT)
}
Else
{
// do nothing
}
Delay(1000)
}

So the problem is the motor turns only one direction and if the input is almost at the setpoint both output light up (on the shield + en - led). I was thinking i should set the output limits because the arduino has a default of 0 》255

Thanks in advance

sp. "if", "delay", "else" etc

Shouldn't you be using the values you just read?

Also, pins default to input, so your digitalWrite is just turning on the pullup resistor.

Please remember to use code tags when posting code

There are a LOT of basic mistakes in your code. Here it is with the mistakes edited out:

#include <PID_v1.h>

const byte SetpointAIPin = A0;
const byte InputAIPin = A1;
const byte MotorEnablePin = 8;
const byte MotorDirectionPin = 12;
const byte MotorPWMPin = 3;

//Define Variables
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
double Kp = 2, Ki = 5, Kd = 1;

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup()
{
  pinMode(MotorPWMPin, OUTPUT);
  pinMode(MotorEnablePin, OUTPUT);
  pinMode(MotorDirectionPin, OUTPUT);

  digitalWrite(MotorEnablePin, HIGH);

  //turn the PID on
  myPID.SetOutputLimits(-255, 255);
  myPID.SetMode(AUTOMATIC);
}

void loop()
{
  Input = analogRead(InputAIPin);
  Setpoint = analogRead(SetpointAIPin);

  myPID.Compute();

  if (Output >= 0)
  {
    digitalWrite(MotorDirectionPin, HIGH);
    analogWrite(3, Output);
  }
  else
  {
    digitalWrite(MotorDirectionPin, LOW);
    analogWrite(3, -Output);
  }

  delay(1000);
}

Many thanks! It works flawless. It was indeed a mess.. I changed the code a little to suit my project better. I will try it later if it works

#include <PID_v1.h>

const byte SetpointAIPin = A0;
const byte InputAIPin = A1;
const byte MotorEnablePin = 8;
const byte MotorDirectionPin = 12;
const byte MotorPWMPin = 3;
const byte MotorUpperDIPin = 4; // switch at the end of the shaft upper limit
const byte MotorLowerDIPin = 7; // switch at the end of the shaft lower limit

//Define Variables
double Setpoint, Input, Output;
int MotorMax, MotorMin; // HIGH / LOW

//Specify the links and initial tuning parameters
double Kp = 1, Ki = 2, Kd = 1;

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup()
{
pinMode(MotorPWMPin, OUTPUT);
pinMode(MotorEnablePin, OUTPUT);
pinMode(MotorUpperDIPin, INPUT);
pinMode(MotorLowerDIPin, INPUT);

digitalWrite(MotorEnablePin, HIGH);

//turn the PID on
myPID.SetOutputLimits(-100, 100);
myPID.SetMode(AUTOMATIC);
}

void loop()
{
Input = analogRead(InputAIPin);
Setpoint = analogRead(SetpointAIPin);
MotorMax = digitalRead(MotorUpperDIPin);
MotorMin = digitalRead(MotorLowerDIPin);

myPID.Compute();

if (Output >= 0 || MotorMax != HIGH) // upper switch
{
digitalWrite(MotorDirectionPin, HIGH);
analogWrite(3, Output);
}
else if (MotorMin != HIGH) // lower switch
{
digitalWrite(MotorDirectionPin, LOW);
analogWrite(3, -Output);
}
else
{
}
delay(100);
}

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