Trying to create and store an instance of a class

Hi all,

I'm having trouble creating and storing an instance of the NewSoftSerial class inside my own Relay class.

I'm experienced in Java and PHP, but haven't really done a lot in C++. I think I've just about grasped pointers, but there must be something quite fundamental I'm missing here?

I have tried 2 methods, I will post the code for both...

Method 1:

--- Relay.h ---

#ifndef ATmegaNET_Relay
#define ATmegaNET_Relay

#include "WConstants.h"
#include "Module.h"
#include <NewSoftSerial.h>

class Relay : public Module{
      public:
            Relay(int dpin_tx,int dpin_rx,int timeout);
            void loop();
            void poll();
      private:
            int _timeout;
            NewSoftSerial _ss;
};

#endif

--- Relay.cpp ---

#include "WProgram.h"
#include "Relay.h"
#include <NewSoftSerial.h>

Relay::Relay(int dpin_rx,int dpin_tx,int timeout) : Module("relay"){
  _timeout=timeout;
  _ss=new NewSoftSerial(dpin_rx,dpin_tx);
  _ss.begin(9600);
}

void Relay::loop(){

}

void Relay::poll(){
  _ss.println("p");
  int timeout=millis()+_timeout;
  while(millis()<timeout){
    if(_ss.available()>0){
      char c=_ss.read();
      if(c=='#'){
        return;
      }
      Serial.print(c);
    }
  }
  Serial.println("!relay timeout");
}

This failes to compile with the following error:

/home/bob/arduino/arduino-0018/libraries/ATmegaNET/Relay.cpp: In constructor 'Relay::Relay(int, int, int)':
/home/bob/arduino/arduino-0018/libraries/ATmegaNET/Relay.cpp:5: error: no matching function for call to 'NewSoftSerial::NewSoftSerial()'
/home/bob/arduino/arduino-0018/libraries/NewSoftSerial/NewSoftSerial.h:82: note: candidates are: NewSoftSerial::NewSoftSerial(uint8_t, uint8_t, bool)
/home/bob/arduino/arduino-0018/libraries/NewSoftSerial/NewSoftSerial.h:45: note: NewSoftSerial::NewSoftSerial(const NewSoftSerial&)
/home/bob/arduino/arduino-0018/libraries/ATmegaNET/Relay.cpp:7: error: no match for 'operator=' in '((Relay*)this)->Relay::_ss = (((NewSoftSerial*)operator new(18u)), (->NewSoftSerial::NewSoftSerial(((uint8_t)dpin_rx), ((uint8_t)dpin_tx), false), ))'
/home/bob/arduino/arduino-0018/libraries/NewSoftSerial/NewSoftSerial.h:45: note: candidates are: NewSoftSerial& NewSoftSerial::operator=(const NewSoftSerial&)

It looks like its trying to call the NewSoftSerial constructor without passing in the args, is this because I've defined it in the .h and it gets instantiated at the same time Relay is? How would I go about declaring this property correctly?

Method 2:

I have also tried using a pointer as this compiles but seems to crash the Arduino and cause it to print out some junk and reset.

--- Relay.h ---

#ifndef ATmegaNET_Relay
#define ATmegaNET_Relay

#include "WConstants.h"
#include "Module.h"
#include <NewSoftSerial.h>

class Relay : public Module{
      public:
            Relay(int dpin_tx,int dpin_rx,int timeout);
            void loop();
            void poll();
      private:
            int _timeout;
            NewSoftSerial *_ss;
};

#endif

--- Relay.cpp ---

#include "WProgram.h"
#include "Relay.h"
#include <NewSoftSerial.h>

Relay::Relay(int dpin_rx,int dpin_tx,int timeout) : Module("relay"){
  _timeout=timeout;
  NewSoftSerial ss(dpin_rx,dpin_tx);
  _ss=&ss;
  _ss->begin(9600);
}

void Relay::loop(){

}

void Relay::poll(){
  _ss->println("p");
  int timeout=millis()+_timeout;
  while(millis()<timeout){
    if(_ss->available()>0){
      char c=_ss->read();
      if(c=='#'){
        return;
      }
      Serial.print(c);
    }
  }
  Serial.println("!relay timeout");
}

I guess the instance I created gets destroyed after the constructor exits leaving the pointer pointing at an invalid object?

As I say, theres something, probably quite simple I'm missing here... could someone point me in the right direction please?

I have tried searching but I cant seem to find a good combination of keywords!

Many thanks in advance :slight_smile:

There is an issue with the Arduino IDE in that the order of constructor calls is not defined or guaranteed.

You need to quit trying to construct other things in your constructor.

You need to add a begin method to your class, similar to Serial.begin(), for instance, where you put the code that you would like to have in your constructor.

The new operator is not defined for use by classes, so you can't use pointer notation.

Hi,

Thanks for the quick reply!

I have moved my constructor code to a begin function as suggested, but I am still getting the same compile error as before. Even if I completely comment out all the the code inside all the functions of Relay.cpp!

It seems to be this line in the Relay.h file that's causing the problems...

NewSoftSerial _ss;

as I think its trying to instantiate the NewSoftSerial object on construction of the Relay object, rather than waiting until I call begin() to pass it its parameters and construct it there.

In other languages I would set it to NULL in the deceleration, but this causes an error:

NewSoftSerial _ss=NULL;

error: ISO C++ forbids initialization of member '_ss'

Do I have to use a pointer here, or can I store the actual object?

The other thing that's confusing me a bit now is how would I create the object in the begin function? Especially if i cant use the new operator?

Would I have to say:

NewSoftSerial ss(dpin_rx,dpin_tx);
_ss=ss;

or can I just do a:

NewSoftSerial _ss(dpin_rx,dpin_tx);

Or am I barking up the wrong tree?

Some example code or a link to some relevant tutorials would be very helpful :slight_smile:

Cheers

Do not use pointers, and change constructor to be:

Relay::Relay(int dpin_rx,int dpin_tx,int timeout) : Module("relay"), _ss(dpin_rx,dpin_tx)

:slight_smile:

That's it! :smiley: That's the missing link! Thanks AlphaBeta :slight_smile: I knew there must be something simple I was overlooking.