Object within class

Hello,
I am trying to turn my arduino sketch into the library. But I need to use object of another library inside. I need to build my own library where I include RF24 library in it and where I will work with this object. Currently I have following code but still with problems:

FLNRF24.cpp

#include "Arduino.h"
#include "FLNRF24.h"
#include "SPI.h"
#include "nRF24L01.h"
#include "RF24.h"



FLNRF24::FLNRF24() : radio (9,10)
{ 
  radio.begin(); // NRF24L01+ 
  // 4 values to set for long range distance radio
  // Max power 
  radio.setPALevel( RF24_PA_MAX ) ; 
  // Min speed
  radio.setDataRate( RF24_250KBPS ) ;
  // 8 bits CRC
  radio.setCRCLength( RF24_CRC_8 ) ;
  // optionally, increase the delay between retries & # of retries
  radio.setRetries(15,15);
  // optionally, reduce the payload size.  seems to
  // improve reliability
  radio.setPayloadSize(32);
  
  radio.openWritingPipe(_writingPipes[0]);
  radio.openReadingPipe(1,_readingPipes[0]);
  radio.openReadingPipe(2,_readingPipes[1]);
  radio.openReadingPipe(3,_readingPipes[2]);
  radio.openReadingPipe(4,_readingPipes[3]);
  radio.openReadingPipe(5,_readingPipes[4]);
  
  
  radio.startListening();
 
}


unsigned long FLNRF24::listenRadio()
{ 
  if ( radio.available() )
  {
    // Dump the payloads until we've gotten everything
    bool done = false;
    while (!done)
    {
      // Fetch the payload, and see if this was the last one.
      done = radio.read( &PACKET, sizeof(unsigned long) );

        return PACKET;
      // Delay just a little bit to let the other unit
      // make the transition to receiver
      delay(20);
    }
  }

  
}

FLNRF24.h

#ifndef FLNRF24_h
#define FLNRF24_h


#include "Arduino.h"
#include "SPI.h"
#include "nRF24L01.h"
#include "RF24.h"


class FLNRF24
{
  public:
    FLNRF24();
    unsigned long listenRadio();
    unsigned long PACKET;
  private:
    RF24 radio;
    //Specify the reading pipes
    const uint64_t _readingPipes[5] = { 0xFFFFFF10, 0xFFFFFF11, 0xFFFFFF12, 0xFFFFFF13, 0xFFFFFF14 };
    //specify the writing pipes
    const uint64_t _writingPipes[5] = { 0xFFFFFF00, 0xFFFFFF01, 0xFFFFFF02, 0xFFFFFF03, 0xFFFFFF04 };
   
};

#endif

sketch.ino

#include <SoftwareSerial.h>

#include "FLSigfox.h"
#include "FLNRF24.h"

#include "SPI.h"
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

unsigned long PACKET;

FLNRF24 nrf;

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

}

void loop() {
  Serial.println(nrf.listenRadio());
}

I tried to remove the parts of code which are not relevant to the problem to make it more readable.

The code is still not working correctly even it compile fine. I probably work in a wrong way with the object created inside my class.

Any help will be appreciated.

FLNRF24::FLNRF24() : radio (9,10)

what is the name of the base class?

radio is an instance...

example:

class BaseClass{
  public:
    BaseClass(int val){myPin = val;};  // base class constructor
  private:
    int myPin;
};

class MyClass : public BaseClass{
  public:
    MyClass(int val) : BaseClass(val){};  // MyClass inherits from BaseClass
};

const int pin = 3;

MyClass myInstance(pin);

void setup() 
{

}

void loop() 
{

}

Name of the base class is RF24. There is created object in the FLNRF24.h file in private part by following line: RF24 radio; you can see it in the code I pasted in the first post.

By the way here is the tutorial which helped me to create it:

So I think the problem is how to handel the object within the class (to keep the object alive for whole time of the arduino sketch, or how to access this object within the FLNRF24.cpp file).

My C++ is not too good when it come to classes but I managed to create a working library from your files by doing some mods to them:

h file (added 2 variables to the library to store the pin assignment when FLNRF24(ce,cs) is initialised):

#ifndef FLNRF24_h
#define FLNRF24_h


#include "Arduino.h"
#include "SPI.h"
#include "nRF24L01.h"
#include "RF24.h"

class FLNRF24
{
  public:
    FLNRF24(uint8_t ce, uint8_t cs);
    unsigned long listenRadio();
    unsigned long PACKET;
  private:
    static uint8_t cepin;
    static uint8_t cspin;
    //Specify the reading pipes
    const uint64_t _readingPipes[5] = { 0xFFFFFF10, 0xFFFFFF11, 0xFFFFFF12, 0xFFFFFF13, 0xFFFFFF14 };
    //specify the writing pipes
    const uint64_t _writingPipes[5] = { 0xFFFFFF00, 0xFFFFFF01, 0xFFFFFF02, 0xFFFFFF03, 0xFFFFFF04 };
};

#endif

CPP file (now 'radio' is declared locally in each function):

#include "FLNRF24.h"


uint8_t FLNRF24::cepin=0;
uint8_t FLNRF24::cspin=0;

FLNRF24::FLNRF24(uint8_t ce, uint8_t cs)
{  
  cepin = ce;
  cspin = cs;

  RF24 radio(cepin, cspin);
  
  radio.begin(); // NRF24L01+ 
  // 4 values to set for long range distance radio
  // Max power 
  radio.setPALevel( RF24_PA_MAX ) ; 
  // Min speed
  radio.setDataRate( RF24_250KBPS ) ;
  // 8 bits CRC
  radio.setCRCLength( RF24_CRC_8 ) ;
  // optionally, increase the delay between retries & # of retries
  radio.setRetries(15,15);
  // optionally, reduce the payload size.  seems to
  // improve reliability
  radio.setPayloadSize(32);
  
  radio.openWritingPipe(_writingPipes[0]);
  radio.openReadingPipe(1,_readingPipes[0]);
  radio.openReadingPipe(2,_readingPipes[1]);
  radio.openReadingPipe(3,_readingPipes[2]);
  radio.openReadingPipe(4,_readingPipes[3]);
  radio.openReadingPipe(5,_readingPipes[4]);
  
  
  radio.startListening();
 
}


unsigned long FLNRF24::listenRadio()
{ 
  RF24 radio(cepin, cspin);
  
  if ( radio.available() )
  {
    // Dump the payloads until we've gotten everything
    bool done = false;
    while (!done)
    {
      // Fetch the payload, and see if this was the last one.
      done = radio.read( &PACKET, sizeof(unsigned long) );

        return PACKET;
      // Delay just a little bit to let the other unit
      // make the transition to receiver
      delay(20);
    }
  }

  
}

example skech:

#include <SoftwareSerial.h>

#include "FLSigfox.h"
#include "FLNRF24.h"

#include "SPI.h"
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

unsigned long PACKET;

FLNRF24 nrf(9,10); //now specifying the pins to use here instread on in the library

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

}

void loop() {
  Serial.println(nrf.listenRadio());
}

sherzaad:
My C++ is not too good when it come to classes...

agreed.

I'm thinking you can't call the constructor like that. It looks like you want your class to contain a member that's an object of type RH24 rather than inheriting the RH24 class. I'd use a pointer. I can't compile / test this because I don't have the library / hardware. But, something like this:

.h file:

#ifndef FLNRF24_h
#define FLNRF24_h

#include "Arduino.h"
#include "SPI.h"
#include "nRF24L01.h"
#include "RF24.h"

class FLNRF24
{
  public:
    FLNRF24();
    unsigned long listenRadio();
    unsigned long PACKET;
  private:
    RF24 *radio;
    //Specify the reading pipes
    const uint64_t _readingPipes[5] = { 0xFFFFFF10, 0xFFFFFF11, 0xFFFFFF12, 0xFFFFFF13, 0xFFFFFF14 };
    //specify the writing pipes    const uint64_t _writingPipes[5] = { 0xFFFFFF00, 0xFFFFFF01, 0xFFFFFF02, 0xFFFFFF03, 0xFFFFFF04 };
   
};
#endif

.cpp file:

#include "Arduino.h"
#include "FLNRF24.h"
#include "SPI.h"
#include "nRF24L01.h"
#include "RF24.h"

FLNRF24::FLNRF24() : radio (9,10)
{ 
  radio = new RF24(9,10);
  radio->begin(); // NRF24L01+ 
  // 4 values to set for long range distance radio
  // Max power 
  radio->setPALevel( RF24_PA_MAX ) ; 
  // Min speed
  radio->setDataRate( RF24_250KBPS ) ;
  // 8 bits CRC
  radio->setCRCLength( RF24_CRC_8 ) ;
  // optionally, increase the delay between retries & # of retries
  radio->setRetries(15,15);
  // optionally, reduce the payload size.  seems to
  // improve reliability
  radio->setPayloadSize(32);
  
  radio->openWritingPipe(_writingPipes[0]);
  radio->openReadingPipe(1,_readingPipes[0]);
  radio->openReadingPipe(2,_readingPipes[1]);
  radio->openReadingPipe(3,_readingPipes[2]);
  radio->openReadingPipe(4,_readingPipes[3]);
  radio->openReadingPipe(5,_readingPipes[4]);  
  
  radio->startListening();
 
}

unsigned long FLNRF24::listenRadio()
{ 
  if ( radio->available() )
  {
    // Dump the payloads until we've gotten everything
    bool done = false;
    while (!done)
    {
      // Fetch the payload, and see if this was the last one.
      done = radio->read( &PACKET, sizeof(unsigned long) );

        return PACKET;
      // Delay just a little bit to let the other unit
      // make the transition to receiver
      delay(20);
    }
  }
}

gfvalvo:

FLNRF24::FLNRF24() : radio (9,10)

{
  radio = new RF24(9,10);

??

not sure what you meant there...

BulldogLowell:
??
not sure what you meant there...

Means I forgot to delete that part:

FLNRF24::FLNRF24()
{ 
  radio = new RF24(9,10);

Thinking about it some more, I'd take everything out of the constructor and put it in a .begin() method for the OP's new FLNRF24 class.

gfvalvo:
Means I forgot to delete that part:

FLNRF24::FLNRF24()

{
  radio = new RF24(9,10);




Thinking about it some more, I'd take everything out of the constructor and put it in a .begin() method for the OP's new FLNRF24 class.

Perhaps, but I think I'd go with inheritance... it seems like he's making a simple wrapper.

Thanks all of you for your suggestions. I hope I will have some time to test it soon to write here the results. Thanks a lot for your help guys.

I tried your suggested code. It compile without problems but not doing what is expected. It event do not reach the setup part in the sketch file. :o( It is caused by the FLNRF24 class as when I remove it from the arduino sketch it works ok.

boylucky:
I tried your suggested code. It compile without problems but not doing what is expected. It event do not reach the setup part in the sketch file. :o( It is caused by the FLNRF24 class as when I remove it from the arduino sketch it works ok.

I guess the question is “what do you want to do?”

Are you wanting to inherit from RF24 and add some methods, or are you trying to do something else?

Yes, I would like for now to inherit from RF24 and add some methods.

boylucky:
Yes, I would like for now to inherit from RF24 and add some methods.

then just define a derived class; a tutorial here.

ok, thanks. I am checking the page if I succeed.

Is there also a way that I would not want to add some other functions to existing class, but I would just use that class within my own class? I mean I would define object of RF24 class within my own class where I want to use it and do same operations as in the normal sketch? To be able to manipulate with this object normaly as it would be in the sketch.

For example I want to do SoftwareSerial in my new class. I would like to do it the way that I create object from SoftwareSerial inside the new class and will use it in some functions within my new class.

boylucky:
ok, thanks. I am checking the page if I succeed.

Is there also a way that I would not want to add some other functions to existing class, but I would just use that class within my own class? I mean I would define object of RF24 class within my own class where I want to use it and do same operations as in the normal sketch? To be able to manipulate with this object normaly as it would be in the sketch.

Is your own class functionally a radio object or does it do something else? If you plan to use any methods of the base class in addition to the methods of your own class, then use inheritance instead. It will be more straightforward in the long run.

Think in terms of an "is a" relationship. If your created class "is a" kind of Software serial, then use inheritance. If it's a "something that uses" Software serial, then no.

In this case it is something that only use software serial. I just want to print with SoftwareSerial inside my class. For example function which send commands to SoftwareSerial:

void FLSigfox::sleep()
{
mySerial.print('\r');
mySerial.print("AT$P=1");
mySerial.print('\r');
_sigfoxUp=false;
}

But I need to somehow create object within my FLSigfox class.

boylucky:
But I need to somehow create object within my FLSigfox class.

What somehow? Just create it. Just declare one like you would declare any object.

boylucky:
ok, thanks. I am checking the page if I succeed.

Is there also a way that I would not want to add some other functions to existing class, but I would just use that class within my own class? I mean I would define object of RF24 class within my own class where I want to use it and do same operations as in the normal sketch? To be able to manipulate with this object normaly as it would be in the sketch.

of course a class can contain classes as members:

class Aclass{
  public:
    doSomething(){Serial.println(F("test"));}
  private:
    doSomethingElse(){Serial.println(F("test2"));}
    
};

class Bclass{
  public:
    giddyUp(){a.doSomething();}
    // doPrivate(){a.doSomethingElse();} // int Aclass::doSomethingElse()' is private
  private:
    Aclass a;
};

Bclass b;

void setup() 
{
  Serial.begin(9600);
  b.giddyUp();
}

void loop() 
{
  
}