2

I'm having trouble explaining my issue. What I'm doing is creating a library to work easily with the RFID reader/writer RC522 module. I need to create an object of the library MFRC522 in my .cpp file to be able to communticate with the module itself. I want my constructor end up like this:UltimateRFID rfid(53, 5);, the parameters being the slave select and the reset pins, respectively. The problem is that I don't know how to make my constructor so that it is within the scope of the functions that require the MFRC522 object to be called. Below's my code.

#include "Arduino.h"
#include "UltimateRFID.h"
#include <MFRC522.h>


MFRC522::MIFARE_Key key;


UltimateRFID::UltimateRFID(int ss, int rst)
{
   MFRC522 mfrc522(ss, rst); //this would be ideal, but how can my functions access the instance?
}


void UltimateRFID::initialize() //sample of a function that uses the MFRC522 object
{
  //digitalWrite(49, HIGH);
  digitalWrite(2, LOW);
  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }     
  mfrc522.PCD_Init();
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;          
  }

}

Now comes my header file, although I'm not sure it matters much.

#ifndef UltimateRFID_h
#define UltimateRFID_h

#include "Arduino.h"
#include <MFRC522.h>

class UltimateRFID
{
  public:
    UltimateRFID(int ss, int rst);
    void initialize();
  private:
    MFRC522::MIFARE_Key key;
};

#endif

Please be patient, it's my first library.

3 Answers 3

3

Why not have your class just extend the MFRC522 class?

#include <MFRC522.h>

class UltimateRFID : public MFRC522 {
    private:
        MIFARE_Key key;

    public: 
        UltimateRFID(uint8_t ss, uint8_t rst) : MFRC522(ss, rst) {}
        // your other methods
        void initialize();
};

void UltimateRFID::initialize() {
    //digitalWrite(49, HIGH);
    digitalWrite(2, LOW);
    for (byte i = 0; i < 6; i++) {
        key.keyByte[i] = 0xFF;
    }     
    PCD_Init();
    if ( ! PICC_IsNewCardPresent()) {
        return;
    }
    if ( ! PICC_ReadCardSerial()) {
        return;          
    }
}

UltimateRFID rfid(53, 5);

void setup() {
    rfid.initialize();
}

void loop() {}

Your class then becomes a "flavour" of MFRC522 with additional functionality. It can access all the public functions of the MFRC522 class, since they are now a part of your class.

Anything you can do with an MFRC522 object you can now do with your object. As well as your extra functions.

8
  • And I don't need a constructor in my source file? Only in the header? Commented Aug 6, 2017 at 0:27
  • You can have a constructor if you want. There is an empty one in the header at the moment (the {}). No content is needed since the initialisation list calls the parent constructor for you. Commented Aug 6, 2017 at 0:29
  • I did just that and I get a compilation error: collect2.exe: error: ld returned 5 exit status. Commented Aug 6, 2017 at 0:40
  • Did you copy and paste my code? I just noticed a typo in the initialisation list. I am not at my computer at the moment (1:48am here) so cannot test it right now. Commented Aug 6, 2017 at 0:48
  • I did copy it, fixed the typos (MFRC522 instead of MRFC22/MRFC622) but the error appears anyway. Commented Aug 6, 2017 at 2:17
2

While @Majenko's answer is probably best (I +1'd it), for completeness, here's how to construct a member variable with parameters:

class UltimateRFID {
    public:
    UltimateRFID(int ss, int rst) : mfrc522(ss, rst) {}

    protected:
    MFRC522 mfrc522;
};

"placement new" is another option:

class UltimateRFID {
    public:
    UltimateRFID(int ss, int rst) {
        new (&mfrc522) MFRC522(ss, rst)
    }

    protected:
    MFRC522 mfrc522;
};

However, this method calls the default ctor - which may or may not be an issue. This is usually reserved for re-initializing an existing object.

There's also assignment:

class UltimateRFID {
    public:
    UltimateRFID(int ss, int rst) {
        mfrc522 = MFRC522(ss, rst)
    }

    protected:
    MFRC522 mfrc522;
};

This also calls the default ctor and works best if the class provides operator=.

1
UltimateRFID::UltimateRFID(int ss, int rst)
{
   MFRC522 mfrc522(ss, rst); //this would be ideal, but how can my functions access the instance?
}

As you note, that instance would go out of scope immediately. The simplest thing would be to put a pointer to the other class in your class definition. Then in your init function do a new to create the instance of the class, passing the appropriate parameters.

2
  • In init and in all other functions that use MFRC522 objects? Commented Aug 5, 2017 at 6:30
  • No, you only do a new once (for a particular instance). Read up on new/delete in C++ tutorials. Commented Aug 5, 2017 at 6:49

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.