Most of my background is in Python and I am trying to re-learn C++ as it applies to micro-controller boards like Arduino.
I have created a standalone C++ class named DigitalGPIOPin
. I also have another class named DigitalRGBPin
that will need to instantiate 3 objects of the DigitalGPIOPin
class in the constructor and share access to the objects with its member functions. Is this possible with C++?
I am attaching my attempt at this problem thus far with a simplified case, but I get the error shown below the code, which indicates that the member function initialize_rgb_pin()
can not access the objects.
// GPIOPin.hpp file
class DigitalGPIOPin
{
public:
int id; // Pin identifier
int io // INPUT or OUTPUT
DigitalGPIOPin(int identifier, int io_type);
void initialize_pin();
};
// -----------------------------------------------------------------
class DigitalRGBPin
{
public:
int red_id, green_id, blue_id
DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier);
void initialize_rgb_pin();
};
// =================================================================
// =================================================================
// GPIOPin.cpp file
DigitalGPIOPin::DigitalGPIOPin(int identifier, int io_type)
{
id = identifier;
io = io_type;
}
void
DigitalGPIOPin::initialize_pin()
{
if (io == OUTPUT || io == INPUT || io == INPUT_PULLUP) {
pinMode(id, io);
}
else {
Serial.println("Pin mode not recognized");
}
}
// -----------------------------------------------------------------
DigitalRGBPin::DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier)
{
red_id = red_identifier;
green_id = green_identifier;
blue_id = blue_identifier;
DigitalGPIOPin red_pin(red_identifier, OUTPUT);
DigitalGPIOPin green_pin(green_identifier, OUTPUT);
DigitalGPIOPin blue_pin(blue_identifier, OUTPUT);
}
// -----------------------------------------------------------------
void
DigitalRGBPin::initialize_rgb_pin()
{
red_pin.initialize_pin();
/* Commented out lines below to focus on problem.
The compiler does not recognize red_pin, because it
was not defined as a public variable. So how can I
define this without having to re-write the entire
DigitalGPIOPin class as a nested class within DigitalRGBPin.
This would effectively put me in a position where I have to define
the class twice, since I still need it as a standalone class.
*/
// green_pin.initialize_pin();
// blue_pin.initialize_pin();
}
This yields the following error:
error: red_pin was not declared in this scope
You have declared red_pin
, green_pin
, and blue_pin
as local variables inside of your DigitalRGBPin()
constructor. As such, the compiler error is correct - they are not in scope for initialize_rgb_pin()
(or any other method of DigitalRGBPin
) to access.
You need to make them be members of the DigitalRGBPin
class (just as you did for id
and io
in the DigitalGPIOPin
class, and red_id
, green_id
, blue_id
in the DigitalRGBPin
class).
However, you will have to use the DigitalRGBPin()
constructor's member initialization list to initialize them 1, since DigitalGPIOPin
doesn't have a default constructor defined.
1: you should get in the habit of using the member initialization list for all of your classes when it is feasible to do so.
Try this:
GPIOPin.hpp
class DigitalGPIOPin
{
public:
int id; // Pin identifier
int io; // INPUT or OUTPUT
DigitalGPIOPin(int identifier, int io_type);
void initialize_pin();
};
// -----------------------------------------------------------------
class DigitalRGBPin
{
public:
int red_id, green_id, blue_id;
DigitalGPIOPin red_pin, green_pin, blue_pin;
DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier);
void initialize_rgb_pin();
};
// =================================================================
// =================================================================
GPIOPin.cpp
DigitalGPIOPin::DigitalGPIOPin(int identifier, int io_type) :
id(identifier),
io(io_type)
{
}
void DigitalGPIOPin::initialize_pin()
{
if (io == OUTPUT || io == INPUT || io == INPUT_PULLUP) {
pinMode(id, io);
}
else {
Serial.println("Pin mode not recognized");
}
}
// -----------------------------------------------------------------
DigitalRGBPin::DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier) :
red_id(red_identifier),
green_id(green_identifier),
blue_id(blue_identifier),
red_pin(red_identifier, OUTPUT),
green_pin(green_identifier, OUTPUT),
blue_pin(blue_identifier, OUTPUT)
{
}
// -----------------------------------------------------------------
void DigitalRGBPin::initialize_rgb_pin()
{
red_pin.initialize_pin();
green_pin.initialize_pin();
blue_pin.initialize_pin();
}
On a side note, the red_id
, green_id
, and blue_id
members of the DigitalRGBPin
class are redundant, and thus can (and should) be removed in favor of using red_pin.id
, green_pin.id
, and blue_pin.id
when needed, eg:
GPIOPin.hpp
class DigitalGPIOPin
{
public:
int id; // Pin identifier
int io; // INPUT or OUTPUT
DigitalGPIOPin(int identifier, int io_type);
void initialize_pin();
};
// -----------------------------------------------------------------
class DigitalRGBPin
{
public:
DigitalGPIOPin red_pin, green_pin, blue_pin;
DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier);
void initialize_rgb_pin();
};
// =================================================================
// =================================================================
GPIOPin.cpp
DigitalGPIOPin::DigitalGPIOPin(int identifier, int io_type) :
id(identifier),
io(io_type)
{
}
void DigitalGPIOPin::initialize_pin()
{
if (io == OUTPUT || io == INPUT || io == INPUT_PULLUP) {
pinMode(id, io);
}
else {
Serial.println("Pin mode not recognized");
}
}
// -----------------------------------------------------------------
DigitalRGBPin::DigitalRGBPin(int red_identifier, int green_identifier, int blue_identifier) :
red_pin(red_identifier, OUTPUT),
green_pin(green_identifier, OUTPUT),
blue_pin(blue_identifier, OUTPUT)
{
}
// -----------------------------------------------------------------
void DigitalRGBPin::initialize_rgb_pin()
{
red_pin.initialize_pin();
green_pin.initialize_pin();
blue_pin.initialize_pin();
}