2 PID´s connected in series!!

hello I am trying to make a control algorithm that takes the output of a PID makes a few calculations and them introduces that value as a Input of another PID. The problem is that the second PID outputs a NAN value.

Is there a way to solve this problem? Is it even possible to do what I want whith the PID library?

thanks!

NAN ?

Pedro_Teixeira: hello I am trying to make a control algorithm that takes the output of a PID makes a few calculations and them introduces that value as a Input of another PID. The problem is that the second PID outputs a NAN value.

Is there a way to solve this problem? Is it even possible to do what I want whith the PID library?

thanks!

I assume that NAN means Not A Number. Post your code for comment and help as it is impossible without it and we cannot for instance see how the 2 PIDs are defined and used.

As to the general principle, a PID doesn't care about the source of its data as long as it is the correct type. It is, after all, just a computer program. What is it that requires 2 PIDs in series ?

Can't help you with your problem other then what others suggested to make sure you are passing a proper float variable as the input to the second PID.

In the process control world, having two PID controllers in series is not all that unusual, it is called a 'cascade loop'.

here it is the complete code, I have degug it and havent nothing wrong!

#include <SPI.h> // biblioteca para a saida SPI
#include <PID_v1.h> // biblioteca para o PI
#include <stdio.h>
#include <stdint.h>
#include <math.h>

double delta, Vref, Vold, P, Pold, i, ToPI; //IpvOld
double Setpoint, Input, Input2, Output, dP, dV, Setpoint2;
double Vpv, Ipv, IL1, IL2, ILdcRef, ILdc, Vgrid, aux, Ipv1, Ipv2;
float Kp=0.2, Kp2=0.2367;
float Ki=0.002, Ki2=0.237/4293;
float Kd=0, Kd2=0;
int ROW=0, LABEL=1;

word outputValue=0;
byte data=0;

double enviaDAC=0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
PID PID2(&Input2, &enviaDAC, &Setpoint2, Kp2, Ki2, Kd2, DIRECT);// DIRECT OU REVERSE???

void setup()
{
SPI.setBitOrder(MSBFIRST);
pinMode(10, OUTPUT); // sera que isto é preciso?
SPI.begin();
Serial.begin(9600);

Serial.println(“CLEARDATA”);
Serial.println(“LABEL,Time, Vpainel,Ipainel,Ildc,Vgrid,Vref,PID1,PID2”) ; // apos LABEL separar as variaveis a imprimir por virgulas

delta=0.5;
Vref=0;
P=0;
Ipv=0;
Vold=0;

////// inicialização PI///
//Input = Vpv-ToPI;
Setpoint = 0;
Setpoint2 = 0;
PID2.SetOutputLimits(0,4096); /// segundo PID
myPID.SetOutputLimits(0, 4096);
//turn the PID on
myPID.SetMode(AUTOMATIC);
PID2.SetMode(AUTOMATIC);
/////////////// fim da inicialização ////////////
PID2.SetSampleTime(50);
}

void loop()
{
ROW++;

Vpv= analogRead(0); //verde
Ipv1=analogRead(1); //castanho
Ipv2=analogRead(2); //castanho
IL1=analogRead(3); //vermelho
IL2=analogRead(4); //vermelho
Vgrid=analogRead(5);
ILdc=(IL1-IL2);
Ipv=Ipv1-Ipv2;

Vpv=Vpv5/102410;
Ipv=Ipv5/10241/0.01;
ILdc=ILdc5/1024;
Vgrid=((Vgrid
5/1024)*162.5)-325;

P=Ipv*Vpv;

//P=pv(2);
dP=P-Pold;
dV=Vref-Vold;

if (abs(dP/P)<0.005)
delta=0.1;
else
delta=0.5;

if (dP>0)
{
//Serial.println(“a potencia aumentou”);
if (dV>0)
{
//Serial.println(“a tensao aumentou”);
Vold=Vref;
Pold=P;
Vref=Vold+delta;
}
if (dV<0)
{
//Serial.println(“a tensao diminuiu”);
Vold=Vref;
Pold=P;
Vref=Vold-delta;
}
}

if (dP<0)
{
//Serial.println(“a potencia diminuiu”);
if (dV>0)
{
//Serial.println(“a tensao aumentou”);
Vold=Vref;
Pold=P;
Vref=Vold-delta;
}
if (dV<0)
{
//Serial.println(“a tensao diminuiu”);
Vold=Vref;
Pold=P;
Vref=Vold+delta;
}
}

if(abs(Vref-Vpv)>4)
Vref=Vpv;

/////////////// fim do MPPT //////////

/////////////// codigo para a segunda malha de controlo antes do segundo PI /////////////////////////////
aux= Vgrid/(Vgrid/sqrt(Vgrid));
ILdcRef=abs(aux)((IpvVpv)/(Vgrid/sqrt(Vgrid)));

/////////////////////// codigo PI ////////////7
Input=Vpv-Vref;
myPID.Compute();
Input2=(ILdcRef*Output)-ILdc;
PID2.Compute(); // Segundo PID

///////////// done //////////////////// COMUNICAÇao com o excell aqui em baixo

Serial.print(“DATA,TIME,”);
Serial.print(Vpv);
Serial.print(",");
Serial.print(Ipv);
Serial.print(",");
Serial.print(ILdc);
Serial.print(",");
Serial.print(Vgrid);
Serial.print(",");
Serial.print(Vref);
Serial.print(",");
Serial.print(Output);
Serial.print(",");
Serial.println(enviaDAC);

///////////// comunicação para DAC ///////////

// poem o pin ss a 0 para iniciar a transferencia de nformaçao para o DAC
digitalWrite(10, LOW);// o 10 é do pin 10 do arduino
outputValue = enviaDAC;
outputValue = outputValue >> 4;
//Serial.println(“saida do PID”);
//Serial.println(enviaDAC);

// send high byte
//Serial.println(“tamanho da informação a saida do PID”);
//Serial.println(sizeof(enviaDAC));

data = highByte(outputValue); //guarda em data o primeiro byte a enviar (highbyte)
data = 0b00001111 & data; // LIMPA OS BITS DE “controlo”
data = 0b00110000 | data; // 0=DACA, 0=buffered, 1=1x, 1=output enabled + informaçao
SPI.transfer(data);
//Serial.println(“byte 1”);
//Serial.println(data);

// send low byte
data = lowByte(outputValue);
SPI.transfer(data); // envia o segundo byte
//Serial.println(“byte 2”);
//Serial.println(data);
// Poem o pin ss a 1 para assinalar o fim da transferencia de dados.
digitalWrite(10, HIGH);

//delay(1000);

//Serial.println(millis());
if(ROW>500)
{
ROW=0;
Serial.println(“ROW,SET,2”);
}

}

NEEEEEEEED HEEEEEEEELP PLS

Do serial print off all values to debug.

Input Input2 ILdcRef Output ILdc