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? 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.
    – Majenko
    Aug 6, 2017 at 0:29
  • I did just that and I get a compilation error: collect2.exe: error: ld returned 5 exit status. 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.
    – Majenko
    Aug 6, 2017 at 0:48
  • I did copy it, fixed the typos (MFRC522 instead of MRFC22/MRFC622) but the error appears anyway. 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? 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.
    – Nick Gammon
    Aug 5, 2017 at 6:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.