How do I use open-source Library (e.g. PID, TMC26,) in custom library?

I have never made my own library before, in any scenario, so bear with me.

I have the following class:

#ifndef Cooler_Control_h
#define Cooler_Control_h

#include <C:\Users\labpc1.INSTECH\Documents\Arduino\libraries\Arduino-PID-library-master\PID_v1.h>

#include "Arduino.h"

class Cooler_Control
{
	public:
             // my constructor
             Cooler_Control(double step);

             // PID constructor
             PID myPID(&Input, &Output, &Setpoint, aggKp, aggKi, aggKd, REVERSE);
        private:
             double Input, Output, Setpoint;
             double aggKp, aggKi, aggKd;
};

#endif

I don’t need want those private variables to be public, although I feel like that’s where the problem lies (how else will the PID constructor use those variables if I’m preventing it to use them? If that’s the right way of looking at it.))

Then in my Cooler_Control.cpp file, I re-included the PID_v1.h (no harm, no foul, right?) and then wrote all my custom functions.

In my main.c file, I declare my constructor as such:

Cooler_Control myCooler = Cooler_Control(3.0);

As a result of all this, after compilation, I receive the similar errors: “aggKp has not been declared”, etc.

Should those private variables be public, and declared prior to the PID construction?\

Thanks,
Anthony

I don't need want those private variables to be public, although I feel like that's where the problem lies (how else will the PID constructor use those variables if I'm preventing it to use them? If that's the right way of looking at it.))

Public members of a class can access public and private members and fields of a class.
Private members of a class can access public and private members and fields of a class.
Other class objects can only access public members and fields of a class.

Since myPID (stupid name; who else's PID would it be?) is a member of the class, it can access the private variables.

haha "myPID", ditto that.

In terms of order of initialization, does the PID construction happen before the private declarations? If so, then that makes sense, but that also means that the setup of (constructor = public, certain variables = private) might not work.

When I made the PID constructor private (which doesn't make sense to do, at all), I received the expected errors regarding all the PID library functions not being initialized (this was after the first occurrence where a PID function was called.)

Any thoughts or does none of that make a difference?

And don’t include the whole path to the library. If the library is just where it’s supposed to be just use <PID_v1.h> (Although the name is a bit mehhh).

Move the initialization of the PID object to the .cpp and just declare a PID object. That way you don’t need to include the pid.h in your .h and will a simple forward declaration do.

Unfortunately I keep running into the same scope issue.

Here’s the Cooler_Control constructor, the PID constructor (as stated in the <PID_v1.h>), and the beginCooler method:

Cooler_Control::Cooler_Control(double setp)
{
	outMax = 255;
	outMin = -125;
	setAGGKP(8.0);
	aggKi = 3.0, aggKd = 0.15;
	conKp = 1.1, conKi = 0.0, conKd = 1.2;
	Setpoint = setp;
}

PID myPID(&Input, &Output, &Setpoint, getAGGKP(), aggKi, aggKd, REVERSE);

bool Cooler_Control::coolerBegin()
{
	myPID.SetOutputLimits(outMin, outMax);
	myPID.SetMode(AUTOMATIC);
	setBoundsPID(Setpoint);
	hasStarted = true;
}

/////// aggKp setter and getter, just to see if I needed to write them, they both are private

void Cooler_Control::setAGGKP(double _aggKp)
{
	this->aggKp = _aggKp;
}

double Cooler_Control::getAGGKP()
{
	return aggKp;
}

Knowing that I declared those variables in the ‘Cooler_Control’, shouldn’t they have kept their scope?

I keep getting the error:

C:\Users\labpc1.INSTECH\Documents\Arduino\libraries\Cooler_Control\Cooler_Control.cpp:16:51: error: ‘aggKi’ was not declared in this scope

PID myPID(&Input, &Output, &Setpoint, getAGGKP(), aggKi, aggKd, REVERSE);

With an arrow point at aggKi

This also occurs with the getAGGKP() call.

If you plan to make your custom library available to others make sure to abide by the licence requirements for the Open Source libraries.

...R

Available to others via a user of the product the code is written for?

Or available for other programmers to view, change, use, etc.?

Also any thoughts on the issue I'm experiencing?

As far as I can see in that snippet aggKi is indeed never declared....

I declared those variables in my class structure, under private:

#ifndef Cooler_Control_h
#define Cooler_Control_h

#include "Arduino.h"

class Cooler_Control
{
	public:
		Cooler_Control(double setp);
		bool coolerBegin();
		void readTemperatureC();
		void setSetpoint(int num);
		double getSetpoint();
		double getInput();
	private:
		// functions
		void temperaturePID_Decision();
		void setBoundsPID(double setpoint);
		void setAGGKP(double _aggKp);
		double getAGGKP();
		// declarations
		#define COOL_INPUT 2
		#define PIN_OUTPUT 28
		bool hasStarted;
		int outMax, outMin;
		int upBoundPID, lowBoundPID;
		double Input, Output, Setpoint;
		double aggKp;
		double aggKi;
		double aggKd;
		double conKp;
		double conKi;
		double conKd;
};

#endif

But they are uninitialized...

So if myPid must be part of you library declare it as any other variable in the .h. In the .cpp like that it's just a variable in global.

I initialized the aggKp variable to 8.0, yet the myPID object still says it's not declared in the scope.

Just using the variable aggKp and the myPID constructor, how would you write this out?

Unless double aggKp = 8.0; in private: isn't initialization, how do I properly initialize these variables?

For that, post .h, .cpp and sketch/.ino here (again) in code tags. Now I just have no idea what it all looks like.

lennon-pledge:
Available to others via a user of the product the code is written for?

Or available for other programmers to view, change, use, etc.?

Both, I suspect. But you will need to study the licences.

...R

Here’s Cooler_Control.h

#ifndef Cooler_Control_h
#define Cooler_Control_h
#include "Arduino.h"

class Cooler_Control
{
	public:
		Cooler_Control(double setp);
		bool coolerBegin();
		void readTemperatureC();
		void setSetpoint(int num);
		double getSetpoint();
		double getInput();
	private:
		// functions
		void temperaturePID_Decision();
		void setBoundsPID(double setpoint);
		void setAGGKP(double _aggKp);
		double getAGGKP();
		// declarations
		#define COOL_INPUT 2
		#define PIN_OUTPUT 28
		bool hasStarted;
		int outMax, outMin;
		int upBoundPID, lowBoundPID;
		double Input, Output, Setpoint;
		double aggKp = 8.0;
		double aggKi;
		double aggKd;
		double conKp;
		double conKi;
		double conKd;
};

#endif

Here’s some of Cooler_Control.cpp:

#include "Arduino.h"
#include "Cooler_Control.h"
#include <PID_v1.h>

/******************************** public **********************************/
Cooler_Control::Cooler_Control(double setp)
{
	outMax = 255;
	outMin = -125;
	//setAGGKP(8.0);
	//aggKi = 3.0, aggKd = 0.15;
	aggKd = 0.15;
	aggKi = 3.0;
	conKp = 1.1, conKi = 0.0, conKd = 1.2;
	Setpoint = setp;
}

PID myPID(&Input, &Output, &Setpoint, getAGGKP(), aggKi, aggKd, REVERSE);

bool Cooler_Control::coolerBegin()
{
	myPID.SetOutputLimits(outMin, outMax);
	myPID.SetMode(AUTOMATIC);
	setBoundsPID(Setpoint);
	hasStarted = true;
}

void Cooler_Control::setSetpoint(int num)
{
	Setpoint = Setpoint + num;
	if (Setpoint < 3.0) Setpoint = 8.0;
	else if (Setpoint > 8.0) Setpoint = 3.0;
	setBoundsPID(Setpoint);
	// put LCD commands at end of this call, if bytes were actually passed from LV
}

// best to use only when Setpoint changes
double Cooler_Control::getSetpoint()
{
	return Setpoint;
}

Here are the errors:

C:\Users\labpc1.INSTECH\Documents\Arduino\libraries\Cooler_Control\Cooler_Control.cpp:18:51: error: 'aggKi' was not declared in this scope

 PID myPID(&Input, &Output, &Setpoint, getAGGKP(), aggKi, aggKd, REVERSE);

                                                   ^

C:\Users\labpc1.INSTECH\Documents\Arduino\libraries\Cooler_Control\Cooler_Control.cpp:18:58: error: 'aggKd' was not declared in this scope

 PID myPID(&Input, &Output, &Setpoint, getAGGKP(), aggKi, aggKd, REVERSE);

And those errors will go on for each parameter.

PID myPID(&Input, &Output, &Setpoint, getAGGKP(), aggKi, aggKd, REVERSE);

myPID (still with the stupid name, I see) is NOT a member of the class. You can NOT access class members from public objects.

As far as anyone besides myself should be concerned, the name is irrelevant...just roll with it.

Now, given what you said, how should I access my class members and pass them as parameters to the myPID public object?

Or should I just scrap this whole idea of including the PID library in my Cooler_Control library, and use it in my main.c, passing those parameters in my Cooler_Control constructor instead? Personally, I want to work with it in my custom library, so this is a last resort option.

Or should I just scrap this whole idea of including the PID library in my Cooler_Control library

You are NOT (now, anyway) including the PID library IN your library. You are (now) simply making an instance of the PID class in the same file.

The PID class needs the address of the variables; you can not tell it where the address is of variables that belong to an instance of your class, since your class doesn't know what the addresses will be when one or more instances get created.

Why did you remove the PID instantiation from your class?

Is #include <PID_v1.h> in my libraries .cpp file not correct?

In terms of the PID instantiation, I tried three different ways:

  1. create it as a public member in my public class
  2. create it as a private member in my public class
  3. create it within the body of my public class constructor (which posed 2 problems:)
  1. the myPID object was localized.
  2. in my public/private members section in the class definition, an attempt to create an
    uninstantiated PID myPID; object proved unsuccessful. In the open source
    “PID_v1” library, there’s no general constructor for such a situation. You need the 6 parameters
    for any PID object creation.

And the idea of how my instance variables cannot be found when called upon by the PID constructor make sense. But I need them for the PID construction haha, so how do I adequately provide addressable variables to the PID constructor? Thanks for putting up with this.

Is #include <PID_v1.h> in my libraries .cpp file not correct?

It is correct. It is what you do with the instance(s) of the class defined in that library that is wrong.

In terms of the PID instantiation, I tried three different ways:

  1. create it as a public member in my public class
  2. create it as a private member in my public class
  3. create it within the body of my public class constructor (which posed 2 problems:)

So, you’ve tried three wrong ways. When you are ready to do it right, let us know.

I submit, I cannot input another half-decent solution to this problem. I don't know enough about object construction (or C++) to think of something.

And just to throw this out there, adding an empty constructor to the PID library is wrong, correct?