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
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.
-
And I don't need a constructor in my source file? Only in the header?Alex Vilchis– Alex Vilchis2017年08月06日 00:27:21 +00:00Commented 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– Majenko2017年08月06日 00:29:14 +00:00Commented Aug 6, 2017 at 0:29 -
I did just that and I get a compilation error: collect2.exe: error: ld returned 5 exit status.Alex Vilchis– Alex Vilchis2017年08月06日 00:40:04 +00:00Commented 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– Majenko2017年08月06日 00:48:58 +00:00Commented Aug 6, 2017 at 0:48
-
I did copy it, fixed the typos (MFRC522 instead of MRFC22/MRFC622) but the error appears anyway.Alex Vilchis– Alex Vilchis2017年08月06日 02:17:43 +00:00Commented Aug 6, 2017 at 2:17
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=
.
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.
-
In init and in all other functions that use MFRC522 objects?Alex Vilchis– Alex Vilchis2017年08月05日 06:30:04 +00:00Commented 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.2017年08月05日 06:49:46 +00:00Commented Aug 5, 2017 at 6:49