[SOLVED] Creating instance of another class inside a class

Dear everyone

I’ve been building small Arduino projects as a hobby for a few years now. The devices are getting more complicated and I’ve ran into a situation, where my sketches get long with a bunch of variables and functions. Thus, it starts to make sense to create classes to make projects more manageable and also expandable (I might want to add a second or third led, maybe have an additional temperature sensor and so on).

As for background, there are some great tutorials (e.g. Arduino - LibraryTutorial) for creating Arduino libraries/classes and the basics seem to be working fine. But there’s one thing, I cannot wrap my mind around and I’ve also been unable to find a clear answer on the Internet/here.

Previously I would write like this (example for controlling a heatpump with Arduino).

//Ino without class
#include <MideaHeatpumpIR.h>

IRSenderPWM irSender(9);
HeatpumpIR *heatpumpIR = new MideaHeatpumpIR();

void setup(){
 heatpumpIR->send(irSender, POWER_ON, MODE_HEAT, FAN_2, 17, VDIR_UP, HDIR_AUTO);
 delay(5000);
 heatpumpIR->send(irSender, POWER_OFF, MODE_HEAT, FAN_2, 17, VDIR_UP, HDIR_AUTO);
 delay(5000);
}
void loop(){
}

when I transfer this bit of code into a class in my ino file, I declare the variables at the beginning (to make them available to my methods) and then create an instance in the constructor. For MideaHeatPumpIR I can create a new object. But what do with IRSender? I’ve tried creating a pointer (I think that’s what it’s called and using ->) among other things but I can’t seem to get it work.

Here’s the ino file

//Ino with class
#include <MideaHeatpumpIR.h>

class HeatPump{
  private:
  IRSenderPWM irSender(uint8_t);
  MideaHeatpumpIR *heatpumpIR; 
  
  public:
  uint8_t temperature;
  uint8_t IRpin;
  
  HeatPump(uint8_t ir, uint8_t temp) { 
    IRpin = ir;
    temperature = temp;
    IRSenderPWM irSender(ir);
    heatpumpIR = new MideaHeatpumpIR();
  }
  
  void start() {
    heatpumpIR->send(irSender, POWER_ON, MODE_HEAT, FAN_2, temperature, VDIR_UP, HDIR_AUTO);
  }
  
  void stop() {
    heatpumpIR->send(irSender, POWER_OFF, MODE_HEAT, FAN_2, temperature, VDIR_UP, HDIR_AUTO);
  }
};


void setup() {
  HeatPump garagePump(3, 20);
  garagePump.start();
  delay(5000);
  garagePump.stop();
  delay(5000);
}

void loop() {
}

And here’s the error:

Arduino: 1.8.7 (Windows 10), Board: “Arduino/Genuino Uno”

C:\Users\Ari\Documents\Arduino\sketch_feb04a\sketch_feb04a.ino: In member function ‘void HeatPump::start()’:

sketch_feb04a:21:91: error: invalid use of non-static member function

heatpumpIR->send(irSender, POWER_ON, MODE_HEAT, FAN_2, temperature, VDIR_UP, HDIR_AUTO);

^

C:\Users\Ari\Documents\Arduino\sketch_feb04a\sketch_feb04a.ino: In member function ‘void HeatPump::stop()’:

sketch_feb04a:25:92: error: invalid use of non-static member function

heatpumpIR->send(irSender, POWER_OFF, MODE_HEAT, FAN_2, temperature, VDIR_UP, HDIR_AUTO);

^

exit status 1
invalid use of non-static member function

This report would have more information with
“Show verbose output during compilation”
option enabled in File → Preferences.

Any help is greatly appreciated. Even if someone could point me to a resource that would explain the use of classes inside classes (I think that’s the case here) in rather simple terms for a hobbyist would be great. I guess, once I understand why the above isn’t working, I’ll be able to implement my classes correctly in the future.

First, I don’t see any compelling reason to use dynamic allocation to create the instance of MideaHeatpumpIR. So, I’d just do it statically.

I don’t have those libraries installed, so I can’t try to compile this. But, try something like this:

#include <MideaHeatpumpIR.h>

class HeatPump {
  private:
    IRSenderPWM irSender;
    MideaHeatpumpIR heatpumpIR;

  public:
    HeatPump(uint8_t ir, uint8_t temp) : irSender(ir), temperature(temp) {
    }

    void start() {
      heatpumpIR.send(irSender, POWER_ON, MODE_HEAT, FAN_2, temperature, VDIR_UP, HDIR_AUTO);
    }

    void stop() {
      heatpumpIR.send(irSender, POWER_OFF, MODE_HEAT, FAN_2, temperature, VDIR_UP, HDIR_AUTO);
    }

    uint8_t temperature;
};

void setup() {
}

void loop() {
}

PS - Google “c++ initializer list”

Thanks heaps!

It does actually compile and a quick Google search for initializer lists gave good results. I’ll post two links below, in case someone is strugling with the same issue.

https://www.learncpp.com/cpp-tutorial/8-5a-constructor-member-initializer-lists/