using the PID LIB

This is related to a post I started but cant find anymore! Anyway this is more specific and directly addresses my problem, which is:
How do I use the PID LIB for my specific project? I know to include the library in my sketch.
#include <PID_v1.h>
The basic example is a good reference for my question so here it is

[code]
#include <PID_v1.h>

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);

void setup()
{
  //initialize the variables we're linked to
  Input = analogRead(0);
  Setpoint = 100;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
}

void loop()
{
  Input = analogRead(0);
  myPID.Compute();
  analogWrite(3,Output);
}

[/code]

I’m using a Uno and IDE 1.8.1.

I want to use the PID LIB to control a power supply (PSU). The PSU output current has a monitor signal of .1 volt /amp, max output is 30 amps, so the signal varies from 0 to 3.0 volts. I wired this to analog channel 2 (A2). The PSU output current is controlled by a 0 10 volt command, I wired this to digital pin D11 a PWM signal. analogWrite(11, (0-255), will only output 0-5v, but it is OK that I am limited to a PSU output range of 0 to 15 amps.

So I’m trying

#include <PID_v1.h>

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);

void setup()
{
  //initialize the variables we're linked to
  Input = analogRead(A2);
  Setpoint = 100;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
}

void loop()
{
  Input = analogRead(A2);
  myPID.Compute();
  analogWrite(11,Output);
}

How is the scaling of the Input and Output configured? As for Input, 15 (any small value) is a good test to observe the stability and control at the PSU
Finally,the statement PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
is how the tunings (2, 5, 1) are passed to myPID.Compute();
What am I leaving out?
Gene

You need to start by explicitly stating, in English, what your input, setpoint, and output are to represent.

PaulS,
Input to the PID function is from the PSU current monitor output.
That output is on A2. The A/D output 0 - 1023 represents 0 to 5 volts. However, the PSU current monitor signal is 0 to 3 volts = 0 to 30 amps therefore the A/D output will be 0 = 0 amps and 614 = 30 amps = 3 volts.

Setpoint
The setpoint for the PID will be an integer variable between 0 and 30 where 0 is set to turn the PSU off and 30 is set for the full 30 amps.

Output
I will be sending a current command signal to the PSU via analogWrite(11, xxx)
The PSU current command signal requires a 0 to 10 volt signal where 0v = 0 amp command and 10v = 30 amp command. For now this will only be 0- 15 because the Uno analogWrite() only outputs 5 volts but I will convert the arduino's 0 to 5 to a 0 to 10 volt signal at some point so I can command the full 30 amps.

I just dont see where or how I code these parameters using the PID lib.

Skipping all the verbage about what the numbers mean, and what you might do in the future, the input is the current being output by the device now, the setpoint is the desired current level, and the output is the PWM level needed to achieve that current level.

You have defined that the PID process is to be concerned about three variables, named Input, Setpoint, and Output.

   Input = analogRead(theCurrentPin);
   Setpoint = howManyAmps;

   myPID.Compute();

   analogWrite(somePin, Output);

...The PSU output current is controlled by a 0 10 volt command, I wired this to digital pin D11 a PWM signal. analogWrite(11, (0-255), will only output 0-5v, but it is OK that I am limited to a PSU output range of 0 to 15 amps.

D11 will only output 0 or 5 volts 2.8 volts will never be an output of a digital pin. PWM is a trick to adjust the duty cycle of the 0 or 5V output of the digital pin to give you a way to produce a variable output. additional components or circuitry is required to get a different voltage than 0 or 5V.

Z

Thanks Z, I know what you are saying, I used an RC filter to convert the PWM to analog, but the PSU somhow detected the 5 volt level of the pwm duity cycle anyway. So I fed D11 to an LTC2644 (8 bit) see attached if interrested, it workes great so that problem is solved (or side steped?)
@PaulS
I do get too wordy :confused:
So I must process D11, the OUTPUT, to be the proper signal to command the PSU to the SETPOINT in amps
Likewise must read A2 and process it such that it is also in amps, as the INPUT.
That makes more sense now. I’m beginning to see the light (I hope).
Gene

LTC2644 10 bit PWM to analog converter.pdf (407 KB)

Let me rephrase that:
I state the target, say 5 amps
SETPOINT = 5.

then I read A2 and process the data so that it is in amps such as:

sum = 0;
analogRead (A2);
delayMicroseconds (100);
for (int i = 0; i < 5; i++) {
sum += analogRead(A2);
delayMicroseconds(100);
}
sum = (sum / 5); // avg 5 readings
stackI = (sum * 5.0 / 1024.0) * 10; // conversion, counts to volts, 3v = 30 amps! MAX Current
// the math can be reduced

then I call,
MyPID.Compute() // which calculates OUTPUT, which I pass to the proper pin
analogWrite(11, OUTPUT);

and that is how I use the PID lib right?

and that is how I use the PID lib right?

Assuming that the results of the analogRead() readings and averaging gives a value that seems reasonable, you'd need to print the value of Output to see if using it directly to drive the PWM pin was reasonable. If so, then, yes. You may need to scale Output up or down.

@PaulS
I do the A/D avg to get a consistant reading. Do you have any recomendations to get repeatable / accurate data? I do a lot of data acquisition and find that the data jumps around a bit or two even with a very steady input. I think the Mux adds a bit of noise too.
Gene