Instanciating an objet in a new class [SOLVED]

Hi all,

I am here again with a question about classes.

I have a class Contact:

class Contact : public Debounce {
  public:
    Contact(byte pin, byte mode);
    virtual bool closed();
    virtual bool open();
    virtual bool rose();
    virtual bool fell();
    virtual bool isRising();
    virtual bool isFalling();
    virtual void begin();
  protected:
    byte MYpin;
    byte MYmode;
    bool MYstatus = false;
    bool MYrisingEdge;
    bool MYfallingEdge;
  private:
    bool firstPass = true;

Now, I want to create a new QuadratureEncoder, that needs two Contact objects:

class QuadratureEncoder {
  public:
    QuadratureEncoder(byte pinA, byte modeA, byte pinB, byte modeB);
    int read();
  private:
    byte MYpinA;
    byte MYpinB;
    byte MYmodeA;
    byte MYmodeB;
    Contact A(MYpinA, MYmodeA);
    Contact B(MYpinB, MYmodeB);
};

The compiler says : error: 'MYpinA' is not a type error: 'MYmodeA' is not a type error: 'MYpinB' is not a type error: 'MYmodeB' is not a type

In a sketch, writing Contact A(7, PULLUP); works perfectly.

In the new sketch that tries to use QuadratureEncoder, I write

QuadratureEncoder anEncoder(7, PULLUP, 8, PULLUP);

The instantiator does just this:

QuadratureEncoder::QuadratureEncoder(byte pinA, byte modeA, byte pinB, byte modeB) {
  MYpinA = pinA;
  MYmodeA = modeA;
  MYpinB = pinB;
  MYmodeB = modeB;
}

What am I doing wrong?

Thanks in advance for your help.

Jacques

Here is the code that uses two Contact objects to read an encoder in a sketch:

/*
 * MakeEncoder.ino
 * Author: Jacques Bellavance
 * Date : August 11, 2017
 * Released under the GNU General Public License v3.0
 * 
 * Demonstrates how to use the Contact class
 * to read a 4 step per click encoder using two Contact objects.
 * 
 * Connections: PULLUP
 * [Encoder pin A]---D7
 * [Encoder pin C]---Ground
 * [Encoder pin B]---D8
 * 
*/

#include "SwitchPack.h"
Contact A(7, PULLUP);
Contact B(8, PULLUP);

//setup=======================
void setup() {
  Serial.begin(9600);
  A.begin();
  B.begin();
}

//readEncoder=============================================
//See  http://playground.arduino.cc/Main/RotaryEncoders
//--------------------------------------------------------
int readEncoder() {
  if (A.isRising()) { 
    return (B.closed() << 1) -1;
  }
  return 0;
}//readEncoder--------------------------------------------

//loop===========================================
void loop(){
  int encoder = readEncoder();
  static int count = 0;
  count += encoder;
  if (encoder != 0) { 
    if (encoder == 1) Serial.print(' ');
    Serial.print(encoder);
    Serial.print(" : ");
    Serial.println(count);
  }
}

Jacques

I changed this :

class QuadratureEncoder {
  public:
    QuadratureEncoder(byte pinA, byte modeA, byte pinB, byte modeB);
    int read();
  private:
    byte MYpinA;
    byte MYpinB;
    byte MYmodeA;
    byte MYmodeB;
    Contact A(MYpinA, MYmodeA);
    Contact B(MYpinB, MYmodeB);
};

to this:

class QuadratureEncoder : public Contact{
  public:
    QuadratureEncoder(byte pinA, byte modeA, byte pinB, byte modeB);
    int read();
  private:
    byte MYpinA;
    byte MYpinB;
    byte MYmodeA;
    byte MYmodeB;
    Contact A;
    Contact B;
};

And this:

QuadratureEncoder::QuadratureEncoder(byte pinA, byte modeA, byte pinB, byte modeB) {
  MYpinA = pinA;
  MYmodeA = modeA;
  MYpinB = pinB;
  MYmodeB = modeB;
}

to this:

QuadratureEncoder::QuadratureEncoder(byte pinA, byte modeA, byte pinB, byte modeB) {
  MYpinA = pinA;
  MYmodeA = modeA;
  MYpinB = pinB;
    MYmodeB = modeB;
    Contact A(MYpinA, MYmodeA);
    Contact B(MYpinB, MYmodeB);
}

Now, the first error is :error: no matching function for call to 'Contact::Contact()

Jacques

Probably not your problem but you should avoid single capital letters for variable names. Many of those are defined as macros and the replacement can cause some really hard errors to figure out.

You are right.

Renamed them contactA and contactB.

Still not compiling though. :slightly_frowning_face:

Jacques

Tried this without success:

QuadratureEncoder::QuadratureEncoder(byte pinA, byte modeA, byte pinB, byte modeB) 
  : contactA = new Contact(pinA, modeA))
  : contactB = new Contact(pinB, modeB)) 
{
  MYpinA = pinA;
  MYmodeA = modeA;
  MYpinB = pinB;
  MYmodeB = modeB;
}

Jacques

Strange...

I did this in .h

class QuadratureEncoder : public Contact{
  public:
    QuadratureEncoder(Contact contactA, Contact contactB);
    int getRotation();
  private:
    Contact MYcontactA;
    Contact MYcontactB;
};

I did this in .cpp

QuadratureEncoder::QuadratureEncoder(Contact contactA, Contact contactB)  {
  MYcontactA = contactA;
  MYcontactB = contactB;
}

made this sketch

#include "SwitchPack.h"
Contact contactA(7, PULLUP);
Contact contactB(8, PULLUP);
QuadratureEncoder enc(contactA, contactB);

//setup=======================
void setup() {
  Serial.begin(9600);
  contactA.begin();
  contactB.begin();
}

//loop===========================================
void loop(){
  int encoder = enc.getRotation();
  Serial.print(encoder);
}

Got just the same errors (including not finding Contact::Contact() Here is the whole error list

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp: In constructor 'QuadratureEncoder::QuadratureEncoder(Contact, Contact)':

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:328:72: error: no matching function for call to 'Contact::Contact()'

 QuadratureEncoder::QuadratureEncoder(Contact contactA, Contact contactB)  {

                                                                        ^

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:328:72: note: candidates are:

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:53:1: note: Contact::Contact(byte, byte)

 Contact::Contact(byte pin, byte mode) {

 ^

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:53:1: note:   candidate expects 2 arguments, 0 provided

In file included from C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:2:0:

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note: constexpr Contact::Contact(const Contact&)

 class Contact : public Debounce {

       ^

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note:   candidate expects 1 argument, 0 provided

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note: constexpr Contact::Contact(Contact&&)

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note:   candidate expects 1 argument, 0 provided

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:328:72: error: no matching function for call to 'Contact::Contact()'

 QuadratureEncoder::QuadratureEncoder(Contact contactA, Contact contactB)  {

                                                                        ^

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:328:72: note: candidates are:

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:53:1: note: Contact::Contact(byte, byte)

 Contact::Contact(byte pin, byte mode) {

 ^

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:53:1: note:   candidate expects 2 arguments, 0 provided

In file included from C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:2:0:

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note: constexpr Contact::Contact(const Contact&)

 class Contact : public Debounce {

       ^

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note:   candidate expects 1 argument, 0 provided

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note: constexpr Contact::Contact(Contact&&)

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note:   candidate expects 1 argument, 0 provided

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:328:72: error: no matching function for call to 'Contact::Contact()'

 QuadratureEncoder::QuadratureEncoder(Contact contactA, Contact contactB)  {

                                                                        ^

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:328:72: note: candidates are:

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:53:1: note: Contact::Contact(byte, byte)

 Contact::Contact(byte pin, byte mode) {

 ^

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:53:1: note:   candidate expects 2 arguments, 0 provided

In file included from C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.cpp:2:0:

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note: constexpr Contact::Contact(const Contact&)

 class Contact : public Debounce {

       ^

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note:   candidate expects 1 argument, 0 provided

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note: constexpr Contact::Contact(Contact&&)

C:\Users\Jacques\Documents\Arduino\libraries\SwitchPack\SwitchPack.h:30:7: note:   candidate expects 1 argument, 0 provided

exit status 1
Erreur de compilation pour la carte Arduino Nano

I don't understand why you want the encoder class to inherit from contact. The methods in contact class don't have anything to do with encoders. Seems like the encoder class might USE a couple of contact objects but I don't understand why you want it to inherit the class.

I mean what would calling open or closed or rose or fell tell me about the encoder? Seems like those would be useful to get information that the encoder class needs to be able to tell which way the encoder is turning. But an encoder itself can't be open or closed or falling.

Actually, it is the contact that is open(), closed(),...

You are right, I only want to use two Contacts in this class. There is no inheritance whatsoever.

That is what I tried in my last post: Create the Contacts in the sketch itself. (that is not what I want, of course, I think the class should be able to use any object on it's own).

Jacques

But in your latest post you still have:

class QuadratureEncoder : public Contact{

the QuadratureEncoder class inheriting the Contact class.

I know. I was trying anything and everything.

What is on the first post is closer to what I want.

Jacques

Wouldn't the easiest thing be to give Contact a no argument constructor? Every good class should have one.

Then you could:

class QuadratureEncoder{
  public:
    QuadratureEncoder(byte pinA, byte modeA, byte pinB, byte modeB);
    int getRotation();
  private:
    Contact MYcontactA;
    Contact MYcontactB;
};



QuadratureEncoder::QuadratureEncoder(byte pinA, byte modeA, byte pinB, byte modeB)  {

  MYcontactA = Contact(pinA, modeA);
  MycontactB = Contact(pinB, modeB);
  
}

Right?

jbellavance: That is what I tried in my last post: Create the Contacts in the sketch itself. (that is not what I want, of course, I think the class should be able to use any object on it's own).

the class objects in the Parent class just need to be defined before the Parent Class definition...

(amongst other ways) you can do this like this:

class Contact 
{
  public: 
    Contact(int _pin, int _mode){pin = _pin; pinMode(pin, _mode);};
  private:
    int pin;
};

class QuadratureEncoder{
  public:
    void begin(int pinA, int modeA, int pinB, int modeB){
      sensorA = new Contact(pinA, modeA);
      sensorB = new Contact(pinB, modeB);
    };
  private:
    Contact* sensorA;
    Contact* sensorB;
};

QuadratureEncoder myQuadratureEncoder;

void setup() 
{
  myQuadratureEncoder.begin(2, INPUT_PULLUP, 3, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:

}

Thanks I'll try that and get back

Jacques

Yes, it works.

Making a no argument constructor and making a .set(pin, mode) method just saved the day.

I have been on this for 8 hours now.

Thanks for you help.

Jacques