Utilizando clases dentro de otras clases

Buenas,

estoy haciendo un controlador de temperatura al estilo de un termostato para controlar la temperatura de unas ollas, con algunas funcionalidades añadidas, como el cálculo del volumen de liquido que contiene la olla mediante un sensor ultrasonidos.

La cuestión es que he creado una clase "Tanque" en la que, dentro de la misma, necesito instanciar un objeto de la clase "NewPing" que me permite operar con el sensor ultrasonidos. Si lo hago de forma "fija" por llamarlo de alguna manera, funciona perfectamente, es decir, si en el archivo de clase .cpp fuera de cualquier método de la clase "Tanque" instancio un objeto "sonar" de la clase "NewPing" y directamente le paso numéricamente los parametros necesarios para el constructor de la clase "NewPing" funciona perfectamente.

El problema viene cuando no quiero fijar numericamente dentro de la clase "Tanque" los parámetros que le quiero pasar al constructor de "NewPing", sino que se los quiero pasar por código mediante el constructor de la clase "Tanque" para que con esos parámetros dentro del constructor "Tanque" me instancie la clase "NewPing", en este caso cuando quiero utilizar algún método de la clase "NewPing" dentro de una función de la clase "Tanque" me da un error que me dice que no se ha definido el método que quiero utilizar.

Se que es bastante lioso y me he intentado explicar lo mejor posible. Dejo el archivo .cpp de la clase tanque explicando en comentarios lo que me funciona y lo que me gustaría que funcionara.

A mi me da que debería añadir algún modificador o algo así para que el objeto "sonar" fuera público y accesible para cualquier método de la clase, pero es sólo lo que a mi me da... jajaja

A ver si alguien sabio me echa una manita.

Saludos

Tanque.cpp (7.26 KB)

Hola,

Nos foltaria la clase NewPing, pero bueno, una idea seria tener un constructor por defecto o sin parametros y luego un metodo donde reciba los parametros y los inicialice.

Otra forma creo podia ser reservar memoria con un puntero y luego inicializando algo asi.

NewPing * sonar; // Reservo memoria para un objeto de la clase NewPing

Tanque::Tanque(int _pinEntrada, int _pinSalida, int _pinTrigger, int _pinEcho)
{
    pinMode(_pinEntrada, INPUT);
    pinMode(_pinSalida, OUTPUT);

// resto del código

    //Esto es lo que me gustaría que funcionara

    //se instancia un elemento de la clase NewPing
    sonar=new NewPing(pinTrigger,pinEcho,distanciaMaxima); // Creo el objeto en la zona resevada
.
.
.
}

Creo que eso tambien funciono pero no estoy muy seguro, yo tambien soy nuevo en C++

Creo que buscas invocar al constructor de NewPing con parámetros en el constructor de Tanque. Para ello se ha de invocar el constructor de sonar antes de las llaves de la definición del constructor de Tanque. Has de poner dos puntos (:slight_smile: después de los paréntesis que definen los parámetros del constructor de Tanque y poner la llamada al constructor de sonar antes de la primera llave ({) que define el cuerpo de la función. El constructor de Tanque quedaría algo tal que así:

Tanque::Tanque(int _pinEntrada, int _pinSalida, int _pinTrigger, int _pinEcho, int _distanciaMaxima) : sonar(_pinTrigger, _pinEcho, _distanciaMaxima)
{
    pinMode(_pinEntrada, INPUT);
    pinMode(_pinSalida, OUTPUT);

    pinEntrada=_pinEntrada;
    pinSalida=_pinSalida;
    //parametros sonda predefinidos
    B=3553;     //parametro de la sonda
    R_25=10.25;     //resistencia a 25ºC en [KOhm]
    R_fija=10;     //resistenacia colocada a tensión en [KOhm]

    //parametros de procesos predefinidos
    tolerancia=0.5;
    nEscalones=1;
    modo=0;

    //temperaturas
    TaConsigna=30;

    //volumen
    pinTrigger=_pinTrigger;
    pinEcho=_pinEcho;

    //volumenes predefinidos
    distanciaMaxima=200;
    distanciaCero=70;
    volMin=5;
    volMax=50;
    vol_cm=1;
    volumenLimite=60;
}

Incluso puedes inicializar el resto de variables miembro de la clase de la misma manera, separándolos por comas y pasando el valor o valores entre paréntesis. Ejemplo:

Tanque::Tanque(int _pinEntrada, int _pinSalida, int _pinTrigger, int _pinEcho, int _distanciaMaxima)
    : sonar(_pinTrigger, _pinEcho, _distanciaMaxima),
    //parametros sonda predefinidos
    B(3553),     //parametro de la sonda
    R_25(10.25),     //resistencia a 25ºC en [KOhm]
    R_fija(10),     //resistenacia colocada a tensión en [KOhm]

    //parametros de procesos predefinidos
    tolerancia(0.5),
    nEscalones(1),
    modo(0),

    //temperaturas
    TaConsigna(30),

    //volumen
    pinTrigger(_pinTrigger),
    pinEcho(_pinEcho),

    //volumenes predefinidos
    distanciaMaxima(200),
    distanciaCero(70),
    volMin(5),
    volMax(50),
    vol_cm(1),
    volumenLimite(60)

// Aquí empieza el cuerpo del constuctor (fíjese que la primera llave del contructor está a continuación)
{
    // Ya están inicializadas todas las variables anteriores
    pinMode(pinEntrada, INPUT); // <- pinEntrada ya se ha inicializado con el valor de _pinEntrada
    pinMode(pinSalida, OUTPUT); // <- pinSalida ya se ha inicializado con el valor de _pinSalida
}

Nota: algunos compiladores dan un warning si no se ponen las variables miembro el el mismo orden en que se han puesto en la declaración de la clase.

Recuerda que has de poner en la declaración de la clase Tanque la variable NewPing sonar como la primera de todas ellas, ya que la he puesto la primera en el constructor. O cambia la posición en la que la he puesto según la posición en que la declares en la clase. Ten cuidado con los dos puntos (:slight_smile: no lo muevas de su sitio.

He añadido el parámetro _distanciaMaxima al constructor de Tanque, así que acuérdate de añadirlo también a la declaración del constructor y a la declaración del objeto Tanque.

Espero que sea esto lo que estabas buscando.

¿Puedes poner el archivo Tanque.h?
Lo ideal es que pusieras todo: el .h, el .cpp y un archivo.ino sencillo que haga uso de ellos.
Así podemos ver si compila y con qué cambios.

Buenas,

sigo trabajando en el asunto. De momento he probado las dos opciones que me habeis dado pero:

1- La de @rodripelto no me da error al instanciar la clase, pero sigo teniendo el mismo error que antes. Es decir, soy capaz de crear un objeto "sonar" de la clase "NewPing" en el constructor de la clase "Tanque", pero cuando quiero usar un método del objeto "sonar" en la función "getVolumen()" de la clase "Tanque" me da el error de " 'sonar' was no declared in this scope" por lo que el problema sigue siendo el mismo.

2- La solución de @IgnoranteAbsoluto tiene buena pinta, y posiblemente no me funcione porque no entiendo del todo lo que estoy haciendo. La cosa es que sólo con el código que has pasado no veo cómo "el programa" puede saber que sónar es un objeto de la clase "NewPing". Pero seguire probando por ahi también.

Continuaré investigando el código de alguna clase que necesite la típica función "begin()" para funcionar porque puede que la clave vaya por ahi.

Igualmente siento no haber subido desde el principio todos los codigos, obviamente es error de novato pero lo había hecho por no sobrecargar. Adjunto todo ahora.

Adjunto las librerias y el sketch. Funcionando correctamente debe sacar por serial cada segundo el valor del volumen de la olla en función de la distancia a la lamina de agua. Mas o menos, para una distancia de 20 cm da 40L y disminuye 1L por cada cm que se aleje.

librerias.zip (18 KB)

librerias.zip (18 KB)

amolina31:
La cosa es que sólo con el código que has pasado no veo cómo "el programa" puede saber que sónar es un objeto de la clase "NewPing". Pero seguire probando por ahi también.

Pues lo ha de saber de la misma manera que sabe de qué tipo son las otras variables miembro de la clase como, por ejemplo, R_25. Dónde has declarado el tipo y nombre de R_25 declaras también el tipo y nombre de sonar, en la declaración de la clase.

Nota: creo que has puesto dos veces la librería y no has puesto tu código.

Estoy dandole vueltas pero no entiendo muy bien a lo que te refieres. Creo que a parte del código que has dejado necesito incluir alguna línea en el Tanque.h pero no se el qué exactamente, por que a lo que yo me refería con que el programa no sabe de que tipo es sonar es a que en tu codigo no aparece en ningun momento que sonar sea un objeto de la clase NewPing. Alomejor es una tontería y no me doy cuenta pero no consigo dar con ello.

Nota: el documento librerias.zip adjunto incluye la libreria Tanque, la llibreria NewPing y el sketch.

¡¡Voy avanzando!!

He estado investigando para comprender lo que me contaba @IgnoranteAbsoluto y he encontrado un post en Stack Overflow que soluciona justo eso y ya no me da el error " 'sonar' was no declared in this scope", lo que es buena señal.

El problema ahora es que el método sonar.ping_cm() no funciona si lo uso a traves del método "getVolumen()" de la clase tanque pero sí si lo uso en un sketch básico. No se que puede estar pasando ahora.

Dejo el enlace al post que me ha servido para complementar lo comentado por @IgnoranteAbsoluto.

En el foro no se pueden poner comentarios de más de 9000 caracteres, así que me veo obligado a dividir en tras partes mi propuesta.

No habia podido ver el contenido del zip y como lo vi duplicado pensé que tal vez te faltó algo por subir.

He tratado de compilar lo que tienes en el zip y me ha dado unos cuantos warning así que los he corregido para poder hacer los cambios y verificar que compila bien. Aunque hay algo que no he corregido porque no sé que es lo que se pretende hacer, y lo he dejado indicado. No he mirado cómo funciona la clase ni lo que hace, únicamente me he preocupado de incluir un objeto NewPing en la clase Tanque y de su inicialización en el constructor de esta clase, así como de corregir los warning que daba el compilador.

El fichero Tanque.h me ha quedado asi:

#ifndef Tanque_h
#define Tanque_h

#include <Arduino.h> //Permite utilizar los comandos de Arduino
#include "NewPing.h" // <-- Necesitamos incluir esto porque lo vamos a usar para definir sonar en la clase Tanque
 
class Tanque //Definicion de la clase
{
    public:
//clase Termostato----------------------------------------------------------------------------------------
    //Constructor de la clase
        Tanque(int _pinEntrada, int _pinSalida, int _pinTrigger, int _pinEchos, int _distanciaMaxima); // <-- Se le ha añadido el parámetro _distanciaMaxima

    //metodos

    void ejecutar();    //Hace las tres funciones siguientes seguidas
    void temp();   //Obtiene la temperatura de la sonda y la almacena en la variable TaReal
    void mantenerTemp();   //Activa el pin de Salida en caso de ser necesario
    void cambioTemp();     //Cambia a una nueva temperatura objetivo

    void setSonda(float _B, float _R_25, float _R_fija);        //actualiza los parametros de la sonda
    void setTermostato(float _TaConsigna, bool _modo);    //selecciona los parámetros del termostato
    void setEscalones(int _nEscalones, float _tEsc[], float _TaEsc[]);    //0 -> calor ; 1 -> frio

    //activacion y desactivacion del termostato
    void on();
    void off();

    //variables
    float TaReal;
    float TaConsigna;			//temperatura a la que se realiza el mash in
    int fase = 1;

//Clase Tanque--------------------------------------------------------------------------------------------
    //métodos de la clase tanque
    void getVolumen();          //calcula el volumen del tanque y lo coloca en la variable volumen
    void setTanque(int _distanciaCero, int _volMin, int _volMax, float _vol_cm);           //define los parametros de volMax, volMin, vol_cm;

    //variables de control del volumen
    int distanciaMaxima;  //maxima distancia en cm para el ping del ultrasonido
    int distanciaCero;        //distancia en cm a la que se encuentra el sensor de la cota 0
    float vol_cm;               //incremento de volumen en litros por cada cm aumentado
    int volMin;                 //mínimo volumen al que se puede encontrar el tanque
    int volMax;                 //máximo volumen al que se puede encontrar el tanque
    float volumen;                //volumen instantaneo del depósito
    int volumenLimite;          //volumen maximo para el cual una medida se considera errónea

private:

        bool intervalo(unsigned long t);    // <-- En lugar de long es mejor declarar t como unsigned long

        NewPing sonar;              // <-- Declaramos el objeto como miembro de la clase

        //Definicion de pines de salida y entrada y volumen
        int pinEntrada;
        int pinSalida;
        int pinTrigger;
        int pinEcho;

        //Definicion de parametros de la sonda
        float B;                     //parametro B de la sonda NTC en [K]
        float R_25;                //Resistencia de la sonda a 25 ºC en K_Ohm
        float R_fija;				//Resistencia colocada en serie con el termistor NTC

        //variables de temperatura
        float TaObjetivo;
        float tolerancia;

        //escalones de temperatura
        int nEscalones;
        float TaEsc[10];
        float tEsc[10];
        int escalonActual;

        //variables de procesos
        bool modo;
        bool calentando = false;     //Activa o desactiva el relé
        bool activado = true;       //indica si el termostato está encendido o apagado

        //variables funcion temp()
        float Ta_prom[100];   //inicializamos el array para hacer el promedio
        float Ta_NTC=0;      //inicializamos temperatura
        unsigned long t_anterior=0;  //inicializamos tiempo // <-- En lugar de float es mejor declarar tInicio como unsigned long
        int cont_Ta=0;       //contador del numero de muestras
        double A_NTC;       //entrada analogica de tension en la sonda
        double V_NTC;       //tension 0-5V de la sonda
        double R_NTC;       //resistencia de la sonda

        //variables funcion cambioTemp()
        unsigned long t_ini_esc=millis();   // <-- En lugar de float es mejor declarar tInicio como unsigned long

        //variables funcion intervalo
        unsigned long tInicio=0;   //se inicializa la variable que registra el tiempo anterior // <-- En lugar de float es mejor declarar tInicio como unsigned long

        //variables de la funcion getVolumen
        //t_anterior se comparte con temp()
        int contVol=0;      //contador del numero de muestras de volumen que se obtienen.
        float instVol;        //almacena el volumen instantaneo
        float volPromedio;  //almacena el valor provisional del volumen
};
 
#endif

Las líneas cambiadas o añadidos son:

Como indica el comentario, es necesario el #include para poder definir un objeto del tipo NewPing.h dentro de la clase Tanque.

#include "NewPing.h" // <-- Necesitamos incluir esto porque lo vamos a usar para definir sonar en la clase Tanque

Añado un parámetro más al constructor de Tanque para poder pasarle la distancia máxima con la que va ha trabajar sonar.

        Tanque(int _pinEntrada, int _pinSalida, int _pinTrigger, int _pinEchos, int _distanciaMaxima); // <-- Se le ha añadido el parámetro _distanciaMaxima

Para trabajar con millis() sin problemas se han de usar variables enteras sin signos, es por eso por lo que ha de declararse como unsigned long. Este es el motivo del cambio en todas las líneas siguientes:

        bool intervalo(unsigned long t);    // <-- En lugar de long es mejor declarar t como unsigned long
        unsigned long t_anterior=0;  //inicializamos tiempo // <-- En lugar de float es mejor declarar tInicio como unsigned long
        unsigned long t_ini_esc=millis();   // <-- En lugar de float es mejor declarar tInicio como unsigned long
        unsigned long tInicio=0;   //se inicializa la variable que registra el tiempo anterior // <-- En lugar de float es mejor declarar tInicio como unsigned long

Aquí es donde declaramos que sonar es una variable miembro de la clase. Indicando únicamente el tipo que ha de tener, sin especificar ningún valor de inicialización. Sólo se está indicando que esa variable pertenece a la clase, ya se le indicará los parámetros con que se ha de invocar a su constructor.

        NewPing sonar;              // <-- Declaramos el objeto como miembro de la clase

El fichero Tanque.cpp me ha quedado asi:

#include "Arduino.h"
//#include "WProgram.h"
#include "Tanque.h"
#include "NewPing.h"

//Este es el código que me funciona perfectamente.
//De esta forma puedo utilizar los métodos de la clase "NewPing" mediante el objeto Sonar en cualquier método del código

//NewPing * sonar;
//NewPing sonar(12,11,200);


Tanque::Tanque(int _pinEntrada, int _pinSalida, int _pinTrigger, int _pinEcho, int _distanciaMaxima) : sonar(_pinTrigger, _pinEcho, _distanciaMaxima) // <-- Invocamos el constructor de sonar con los parámetros y valores (se ha añadido el parámetro _distanciaMaxima
{
    pinMode(_pinEntrada, INPUT);
    pinMode(_pinSalida, OUTPUT);

    pinEntrada=_pinEntrada;
    pinSalida=_pinSalida;
    //parametros sonda predefinidos
    B=3553;     //parametro de la sonda
    R_25=10.25;     //resistencia a 25ºC en [KOhm]
    R_fija=10;     //resistenacia colocada a tensión en [KOhm]

    //parametros de procesos predefinidos
    tolerancia=0.5;
    nEscalones=1;
    modo=0;

    //temperaturas
    TaConsigna=30;

    //volumen
    pinTrigger=_pinTrigger;
    pinEcho=_pinEcho;

    //volumenes predefinidos
    distanciaMaxima=_distanciaMaxima;       // <-- Se pasa como último parámetro al definir el objeto Tanque
    distanciaCero=70;
    volMin=5;
    volMax=50;
    vol_cm=1;
    volumenLimite=60;

    //.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //Esto es lo que me gustaría que funcionara

    //se instancia un elemento de la clase NewPing
    // NewPing sonar(pinTrigger,pinEcho,distanciaMaxima);   // <-- Esto no hace falta
    //sonar = new NewPing(pinTrigger,pinEcho,distanciaMaxima);
}

void Tanque::ejecutar()
{
    temp();
    mantenerTemp();
    cambioTemp();
}


//Funcion que devuelve la temperatura registrada por la sonda NTC
//------------------------------------------------------------------------------------------------------------------
void Tanque::temp()
{
  if ((millis()-t_anterior)>=30){
  //Se registra la tensión en la sonda
     A_NTC=analogRead(pinEntrada);
  //Se mapea entre valores de tension 0-5 V
     V_NTC=A_NTC/1023*5;
  //pasamos la tensión de entrada a resistencia en k_Ohm
      R_NTC=(R_fija*V_NTC)/(5-V_NTC);
  //pasamos la resistencia a temperatura
     Ta_prom[cont_Ta]=B/(log(R_NTC/R_25)+B/298)-273;
  //registramos la temperatura y la sumamos
      if(cont_Ta==0){
        Ta_NTC=Ta_prom[cont_Ta];
      }
      else{
      Ta_NTC=Ta_prom[cont_Ta]+Ta_NTC;
      }
      //registramos el tiempo y sumamos uno al contador
      t_anterior=millis();
      cont_Ta=cont_Ta+1;
  }

  if (cont_Ta>99){
  //hacemos la media y ponemos contador y temperatura a 0
     TaReal=Ta_NTC/100;
     cont_Ta=0;
  }
}



//Funcion de control de temperatura (Termostato)
//---------------------------------------------------------------------------------------------------
void Tanque::mantenerTemp(){
    if(activado==true)
    {
    //solo mantener temperatura si el proceso esta en macerado
    //modo calor
        if(modo==0)     // <-- Tenía puesto if(modo=0) haciendo que modo pase a valer 0 y nunca se cumpla la condición
        {
            if((fase==1)||(fase==2)){
            //activar calentamiento si se baja del nivel de tolerancia
                if (TaReal<(TaObjetivo-tolerancia)){
                  digitalWrite(pinSalida, HIGH);
                  calentando=true;
                }
            //seguir calentando si calentamiento esta activado
                if(calentando){
                   digitalWrite(pinSalida, HIGH);
                }
            //detener calentamiento cuando se recupere la temperatura
                if((calentando) && (TaReal>TaObjetivo)){
                   digitalWrite(pinSalida, LOW);
                   calentando=false;
                }
            }
        }
     //modo frio
        if(modo==1)     // <-- Tenía puesto if(modo=1) haciendo que modo pasara a valer 1 y siempre se cumpla la condición
        {
            if((fase==1)||(fase==2)){
            //activar enfriamiento si se supera del nivel de tolerancia
                if (TaReal>(TaObjetivo+tolerancia)){
                  digitalWrite(pinSalida, HIGH);
                  calentando=true;
                }
            //seguir enfriando si enfriamiento esta activado
                if(calentando){
                   digitalWrite(pinSalida, HIGH);
                }
            //detener enfriamiento cuando se recupere la temperatura
                if((calentando) && (TaReal<TaObjetivo)){
                   digitalWrite(pinSalida, LOW);
                   calentando=false;
                }
            }
        }


    //no hacer nada si el proceso ha terminado
        if (fase==5){
          digitalWrite(pinSalida, LOW);
        }
    }
    if(activado==false)
    {
        calentando=false;
    }
}



//Funcion de cambio de temperatura objetivo por cambio de escalon
//-------------------------------------------------------------------------------------------------------------
void Tanque::cambioTemp(){

//definicion de Ta objetivo la Ta de mash-in
    if(fase==1)
    {
      TaObjetivo=TaConsigna;
    }
//definicion de Ta objetivo para macerado
    if(fase==2)
    {
        TaObjetivo=TaEsc[escalonActual];
        if((millis()-t_ini_esc)>(tEsc[escalonActual]*60*1000))     //comprobamos si ha pasado el tiempo del escalon
        {
            escalonActual++;              //Se incrementa un escalon

            if(escalonActual>nEscalones){       //se comprueba que no hay mas escalones
              fase=3;
            }
            else{
                t_ini_esc=millis();         //se regista el tiempo de inicio del nuevo escalon
                TaObjetivo=TaEsc[escalonActual];  //se registra la nueva temperatura objetivo
            }
        }
    }
}


void Tanque::setSonda(float _B, float _R_25, float _R_fija)
{
    B=_B;
    R_25=_R_25;
    R_fija=_R_fija;
}

void Tanque::setEscalones(int _nEscalones, float _tEsc[], float _TaEsc[])
{
    nEscalones=_nEscalones;
    for (int i = 0; i < 10; i++)
    {
      tEsc[i]=_tEsc[i];
    }
    for (int i = 0; i < 10; i++)
    {
      TaEsc[i]=_TaEsc[i];
    }
}


void Tanque::setTermostato(float _TaConsigna, bool _modo)
{
    TaConsigna=_TaConsigna;
    modo=_modo;

}


//funcion que permite activar el termostato
//-------------------------------------------------------------------
void Tanque::on()
{
    activado=true;
}

//funcion que permite desactivar el termostato
//-------------------------------------------------------------------
void Tanque::off()
{
    activado=false;
}



//Métodos de la clase Tanque
//-------------------------------------------------------------------

void Tanque::getVolumen()
{
//se instancia el objeto sonar de la clase NewPing---------------------------------------


    if ((millis()-t_anterior)>=30)
    {
    //Se obtiene el volumen instantáneo del tanque
        instVol=(distanciaCero-sonar.ping_cm())*vol_cm;    // <-- sonar ya no es un puntero, así que sustituimos -> por .
        //prevencion para lecturas erroneas, solo se opera si el volumen es menor que el establecido como error de lectura
        if(0<=instVol<=volumenLimite) // <-- ¡Cuidado con esto! está mál. No se pueden poner comparaciones así.
        {
            if(contVol==0){
              volPromedio=instVol;
            }
            else{
            volPromedio=volPromedio+instVol;
            }
            //registramos el tiempo y sumamos uno al contador
            t_anterior=millis();
            contVol=contVol+1;
        }
    }

    if (contVol>99){
    //hacemos la media y ponemos contador y temperatura a 0
       volumen=volPromedio/100;
       contVol=0;
    }
}

void Tanque::setTanque(int _distanciaCero, int _volMin, int _volMax, float _vol_cm)
{
   distanciaCero=_distanciaCero;
   volMin=_volMin;
   volMax=_volMax;
   vol_cm=_vol_cm;
}

//funcion que permite medir el tiempo transcurrido
//--------------------------------------------------------------------
bool Tanque::intervalo(unsigned long t){    // <-- En lugar de long es mejor declarar t como unsigned long
    if((millis()-tInicio) > t){
        tInicio=millis();
        return true;
    }else{
        return false;
    }
}

Las líneas cambiadas o añadidas al fichero Tanque.cpp son:

Esto es lo que te puse en mi primera propuesta porque era el único fragmento de código que habías puesto inicialmente. Aquí es donde se invoca al constructor de NewPing con los parámetros que recibimos del constructor de Tanque. Se ponen dos puntos y luego el objeto/variable con los parámetros del constructor entre paréntesis. Justo antes de la llave que define el cuerpo de la función.

Tanque::Tanque(int _pinEntrada, int _pinSalida, int _pinTrigger, int _pinEcho, int _distanciaMaxima) : sonar(_pinTrigger, _pinEcho, _distanciaMaxima) // <-- Invocamos el constructor de sonar con los parámetros y valores (se ha añadido el parámetro _distanciaMaxima

No sé si realmente necesitas guardar este valor pero, como lo guardabas, lo guardo.

    distanciaMaxima=_distanciaMaxima;       // <-- Se pasa como último parámetro al definir el objeto Tanque

Esto ya no se necesita para nada.

    // NewPing sonar(pinTrigger,pinEcho,distanciaMaxima);   // <-- Esto no hace falta

Estas dos líneas son ejemplo del típico despiste de poner un igual en lugar de dos a la hora de comparar. Lo que estaba haciendose es una asignación.

        if(modo==0)     // <-- Tenía puesto if(modo=0) haciendo que modo pase a valer 0 y nunca se cumpla la condición
        if(modo==1)     // <-- Tenía puesto if(modo=1) haciendo que modo pasara a valer 1 y siempre se cumpla la condición

Como sonar es ahora un miembro de la clase y no un puntero, se cambia "la flecha" por un "punto".

        instVol=(distanciaCero-sonar.ping_cm())*vol_cm;    // <-- sonar ya no es un puntero, así que sustituimos -> por .

Compilar, compila, pero también es verdad que el compilador suele dar un warning y no va a funcionar como tú quieres. Como no tengo claro qué es lo que quieres hacer no lo he tocado, pero que sepas que está mal. Tal vez la condición correcta seriá ((0 <= instVol) && (instVol <= =volumenLimite)).

        if(0<=instVol<=volumenLimite) // <-- ¡Cuidado con esto! está mál. No se pueden poner comparaciones así.

Lo dicho, para trabajar con millis() sin problemas se han de usar variables enteras sin signos, es por eso por lo que ha de declararse como unsigned long.

bool Tanque::intervalo(unsigned long t){    // <-- En lugar de long es mejor declarar t como unsigned long

El fichero prueba1.ino me ha quedado asi:

#include <Tanque.h>

Tanque olla(0,13,12,11,200);    // <-- Se le ha añadido el parámetro _distanciaMaxima

void setup() {
  Serial.begin(9600);

}

void loop() {
  olla.getVolumen();
  if(intervalo(1000))
  {
      Serial.println(olla.volumen);
  }

}


//funcion que permite medir el tiempo transcurrido
//--------------------------------------------------------------------
unsigned long tInicio = 0;
bool intervalo(unsigned long t){    // <-- En lugar de long es mejor declarar t como unsigned long
    if((millis()-tInicio) > t){
        tInicio=millis();
        return true;
    }else{
        return false;
    }
}

Las líneas cambiadas o añadidas al fichero Tanque.cpp son:

Ya lo dice el comentario, he añadido el 200 como parámetro para inicializar sonar en el constructor de Tanque.

Tanque olla(0,13,12,11,200);    // <-- Se le ha añadido el parámetro _distanciaMaxima

Lo dicho, para trabajar con millis() sin problemas se han de usar variables enteras sin signos, es por eso por lo que ha de declararse como unsigned long.

bool intervalo(unsigned long t){    // <-- En lugar de long es mejor declarar t como unsigned long

Y esto es todo. Espero que esta vez sí que te sirva y que llegues a entender los cambios.