Inglobare PID in una classe

Salve,
vorrei realizzare un controllo di temperatura regolato tramite PID, fin qui nulla di difficile, vorrei però poterlo fare in modo da poter regolare indipendentemente più zone, per fare questo ho pensato di creare una classe e di inserirci il PID con i suoi parametri, il problema è che non riesco a creare la classe correttamente, sicuramente l'errore è sotto il naso ma è un ora che non lo vedo... per cortesia aiutatemi!

Il codice:

#include <PID_v1.h>

class controlTemp {
  public:
    controlTemp(int pinANALOG, int pinPWM);
    double getTemp();
    void setTargetTemp(double val);
    void setPWM(double val);
    void setPIDTunings(double KpVal, double KiVal, double KdVal);
  
  private:
//    double analog2temp(int raw);
    int _pinANALOG;
    int _pinPWM;
    double PIDInput;
    double PIDOutput;
    double PIDSetpoint;
    double PIDKp;
    double PIDKi;
    double PIDKd;
    double PIDMinOut;
    double PIDMaxOut;
    PID pid();
};

// costruttore classe 
controlTemp::controlTemp(int pinANALOG, int pinPWM) {
  _pinANALOG = pinANALOG;
  _pinPWM = pinPWM;
  
  // setto il pinANALOG come analogIn
  pinMode(_pinANALOG, INPUT); 
  // setto il pinPWM come output e a 0
  pinMode(_pinPWM, OUTPUT); 
  analogWrite(_pinPWM, 0);

  // inizializzo i parametri del PID
  PIDInput = 0.0;
  PIDSetpoint = 0.0;
  PIDKp = 1.0;
  PIDKi = 0.0;
  PIDKd = 0.0;
  PIDMinOut = 0.0;
  PIDMaxOut = 255.0;

  // configuro il PID
  PID pid(&PIDInput, &PIDOutput, &PIDSetpoint, PIDKp, PIDKi, PIDKd, DIRECT);

  // setto il PID
  pid.SetTunings(PIDKp, PIDKi, PIDKd);
  pid.SetOutputLimits(PIDMinOut, PIDMaxOut);
  pid.SetMode(MANUAL); // spento per il momento 

}

// setto la temperatura voluta 
void controlTemp::setTargetTemp(double val) {
  PIDSetpoint = val;
}

// setto i parametri del PID 
void controlTemp::setPIDTunings(double KpVal, double KiVal, double KdVal) {
  pid.SetTunings(KpVal, KiVal, KdVal); // <--- primo errore in compilazione!
}

// calcolo il valore e setto il PWM 
void controlTemp::setPWM(double val) {
  // 
  PIDInput = val;
  if (pid.Compute()) {
      analogWrite(_pinPWM, (int) PIDOutput);
  }
  
  Serial.println("=== DEBUG setPWM ===");
  Serial.print("In= ");
  Serial.println(PIDInput);
  Serial.print("Set= ");
  Serial.println(PIDSetpoint);
  Serial.print("PWM= ");
  Serial.println(PIDOutput);
  Serial.print("P= ");
  Serial.println(pid.GetKp());
  Serial.println("=== /DEBUG setPWM ===");
}

////////////////////// Fine classe controlTemp ///////////////////////////////////


void setup() {

}

void loop() {

}

L'errore è:


Arduino:1.6.8 (Linux), Scheda:"Arduino Duemilanove or Diecimila, ATmega328"

/home/dino/Arduino-progetti/CTemp/CTemp/CTemp.ino: In member function 'void controlTemp::setPIDTunings(double, double, double)':
CTemp:63: error: '((controlTemp*)this)->controlTemp::pid' does not have class type
pid.SetTunings(KpVal, KiVal, KdVal);
^
/home/dino/Arduino-progetti/CTemp/CTemp/CTemp.ino: In member function 'void controlTemp::setPWM(double)':
CTemp:70: error: '((controlTemp*)this)->controlTemp::pid' does not have class type
if (pid.Compute()) {
^
CTemp:82: error: '((controlTemp*)this)->controlTemp::pid' does not have class type
Serial.println(pid.GetKp());
^
exit status 1
'((controlTemp*)this)->controlTemp::pid' does not have class type

Questo report potrebbe essere più ricco di informazioni con l'opzione
"Mostra un output dettagliato durante la compilazione"
abilitata in File -> Impostazioni


Ho trovato questo topic in cui si chiede aiuto per lo stesso problema, ma non ho capito la soluzione :frowning:

Devi usare la initialization list per inizializzare l'oggetto interno (pid) e le variabili da cui questo dipende:

controlTemp::controlTemp(int pinANALOG, int pinPWM):
    PIDInput (0.0),
    PIDSetpoint (0.0),
    PIDKp (1.0),
    PIDKi (0.0),
    PIDKd (0.0),
    pid (&PIDInput, &PIDOutput, &PIDSetpoint, PIDKp, PIDKi, PIDKd, DIRECT) {
 // ...
}

Grazie mille! evidentemente non ragionavo molto... :slight_smile: