Probleme mit verwendung von Bibliotheken in eigener Klasse

Hallo
Ich probiere mich gerade an einem RFID Projekt und möchte die MFRC522.h in einer eigenen Klasse verwenden. Hier die relevanten Codestellen:
.ino

#include <SPI.h>
//#include <MFRC522.h>
#include "My_mfrc522.h"
#define RST_PIN         9           // Configurable, see typical pin layout above
#define SS_PIN          10          // Configurable, see typical pin layout above


My_mfrc522 testRFID(SS_PIN,RST_PIN);

void setup() {
  Serial.begin(9600);                                           // Initialize serial communications with the PC
  SPI.begin();                                                  // Init SPI bus
  // Init MFRC522 card
  Serial.println(F("Read personal data on a MIFARE PICC:"));    //shows in serial that it is ready to read
  testRFID.init();

void loop() {

Serial.println(testRFID.checkRfidTag());

  delay(1000);
  //-------------------------------------------
}
}

.h

#ifndef My_mfrc522_h
#define My_mfrc522_h
#include "Arduino.h"
#include <MFRC522.h>
class My_mfrc522
{
  private:
    bool _last_IsNewCardPresent = false;
    byte _ss_pin;
    byte _rst_pin;
    MFRC522* mfrc522;
  public:
    My_mfrc522(byte SS_PIN,byte RST_PIN);
    bool init();
    bool checkRfidTag();
    void getTagId(byte *_uid);
};
#endif

.cpp

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


My_mfrc522::My_mfrc522(byte SS_PIN, byte RST_PIN): mfrc522(new MFRC522(_ss_pin, _rst_pin))
{
  _ss_pin = SS_PIN;
  _rst_pin = RST_PIN;
  //mfrc522 = new MFRC522(_ss_pin,_rst_pin);
}

bool My_mfrc522::init()
{
  mfrc522.PCD_Init();
  return true;
}

bool My_mfrc522::checkRfidTag()
{
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;

  if (mfrc522.PICC_IsNewCardPresent()) {
    _last_IsNewCardPresent = true;
    return true;
  }
  else if (_last_IsNewCardPresent) {
    _last_IsNewCardPresent = false;
    return true;
  }
  else {
    return false;
  }
}

void My_mfrc522::getTagId(byte *_uid)
{
  if (mfrc522.PICC_ReadCardSerial()) {
    _uid[0] = mfrc522.uid.uidByte[0];
    _uid[1] = mfrc522.uid.uidByte[1];
    _uid[2] = mfrc522.uid.uidByte[2];
    _uid[3] = mfrc522.uid.uidByte[3];
    mfrc522.PCD_StopCrypto1();
  }

beim Übersetzen bekomme ich folgende Fehlermeldung:

Arduino: 1.8.9 (Windows Store 1.8.21.0) (Windows 10), Board: "Arduino/Genuino Uno"

sketch\My_mfrc522.cpp: In member function 'bool My_mfrc522::init()':

My_mfrc522.cpp:15:15: error: request for member 'PCD_Init' in '((My_mfrc522*)this)->My_mfrc522::mfrc522', which is of pointer type 'MFRC522*' (maybe you meant to use '->' ?)

       mfrc522.PCD_Init();

               ^

sketch\My_mfrc522.cpp: In member function 'bool My_mfrc522::checkRfidTag()':

My_mfrc522.cpp:24:19: error: request for member 'PICC_IsNewCardPresent' in '((My_mfrc522*)this)->My_mfrc522::mfrc522', which is of pointer type 'MFRC522*' (maybe you meant to use '->' ?)

       if (mfrc522.PICC_IsNewCardPresent()) {

                   ^

sketch\My_mfrc522.cpp: In member function 'void My_mfrc522::getTagId(byte*)':

My_mfrc522.cpp:39:19: error: request for member 'PICC_ReadCardSerial' in '((My_mfrc522*)this)->My_mfrc522::mfrc522', which is of pointer type 'MFRC522*' (maybe you meant to use '->' ?)

       if (mfrc522.PICC_ReadCardSerial()) {

                   ^

My_mfrc522.cpp:40:27: error: request for member 'uid' in '((My_mfrc522*)this)->My_mfrc522::mfrc522', which is of pointer type 'MFRC522*' (maybe you meant to use '->' ?)

         _uid[0] = mfrc522.uid.uidByte[0];

                           ^

My_mfrc522.cpp:41:27: error: request for member 'uid' in '((My_mfrc522*)this)->My_mfrc522::mfrc522', which is of pointer type 'MFRC522*' (maybe you meant to use '->' ?)

         _uid[1] = mfrc522.uid.uidByte[1];

                           ^

My_mfrc522.cpp:42:27: error: request for member 'uid' in '((My_mfrc522*)this)->My_mfrc522::mfrc522', which is of pointer type 'MFRC522*' (maybe you meant to use '->' ?)

         _uid[2] = mfrc522.uid.uidByte[2];

                           ^

My_mfrc522.cpp:43:27: error: request for member 'uid' in '((My_mfrc522*)this)->My_mfrc522::mfrc522', which is of pointer type 'MFRC522*' (maybe you meant to use '->' ?)

         _uid[3] = mfrc522.uid.uidByte[3];

                           ^

My_mfrc522.cpp:44:17: error: request for member 'PCD_StopCrypto1' in '((My_mfrc522*)this)->My_mfrc522::mfrc522', which is of pointer type 'MFRC522*' (maybe you meant to use '->' ?)

         mfrc522.PCD_StopCrypto1();

                 ^

My_mfrc522.cpp:45:5: error: expected '}' at end of input

     }

     ^

exit status 1
request for member 'PCD_Init' in '((My_mfrc522*)this)->My_mfrc522::mfrc522', which is of pointer type 'MFRC522*' (maybe you meant to use '->' ?)

Ich vermute dass das Problem darin liegt dass mfrc522 ein Zeiger ist, steht ja auch so da, weiß aber nicht wie ich das lösen kann :confused: . Ich habe mir als Vorbild das Beispielprojekt “rfid_write_personal_data.ino” genommen. Könnt ihr mir bitte helfen?

knautschkissen:
Ich vermute dass das Problem darin liegt dass mfrc522 ein Zeiger ist, steht ja auch so da, weiß aber nicht wie ich das lösen kann :confused: .

Steht doch auch in der Fehlermeldung:

(maybe you meant to use '->' ?)

also:

mfrc522->PCD_Init();

Was willst du hier mit dynamischem Speicher?

Einfach so anlegen:

private:
   MFRC522 mfrc522;

Und dann den Konstruktor so:

My_mfrc522::My_mfrc522(byte ss_pin, byte rst_pin) : _ss_pin(ss_pin), _rst_pin(rst_pin), mfrc522(ss_pin, rst_pin)
{
}

Großbuchstaben sind für Konstanten. Außerdem wäre es auch kein Problem den Parameter und die Variablen gleich zu benennen. Der Compiler kann das Unterscheiden

Generell daran denken dass es der Sinn einer Initialisierungsliste ist den Code vor dem Konstruktor auszuführen. Du kannst darin also nicht auf Dinge zugreifen du erst im Konstruktor-Körper selbst zuweist (die Initialisierung ist da schon gesehen!)

Und die Fehlermeldung auch mal wirklich lesen!

(maybe you meant to use '->' ?)

Das sagt doch deutlich was falsch ist. Bei Zeigern musst du auf die Elemente mit -> zugreifen

Vielen dank
ich bin nicht auf die idee gekommen dem '.' durch '->' zu ersetzen. Wusste mit dem nichts anzufangen... So funktioniert es.

Mit dem Zeiger musste ich machen weil ich sonst eine andere Felermeldung bekommen habe. Die Lösung mit dem Zeiger habe ich hier auf arduino.cc gefunden.

weil ich sonst eine andere Felermeldung bekommen habe

Das kommt aber nicht wenn man es richtig macht. Es geht auch ohne

Hab deine Codezeilen mal ausprobiert, jetzt kommt folgende Fehlermeldung

Arduino: 1.8.9 (Windows Store 1.8.21.0) (Windows 10), Board: "Arduino/Genuino Uno"

In function 'global constructors keyed to 65535_0_My_mfrc522.cpp.o':

lto1.exe: internal compiler error: Segmentation fault

Please submit a full bug report,

with preprocessed source if appropriate.

See <http://gcc.gnu.org/bugs.html> for instructions.

lto-wrapper.exe: fatal error: C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt\hardware\tools\avr/bin/avr-gcc returned 1 exit status

compilation terminated.

c:/program files/windowsapps/arduinollc.arduinoide_1.8.21.0_x86__mdqgnx93n4wtt/hardware/tools/avr/bin/../lib/gcc/avr/5.4.0/../../../../avr/bin/ld.exe: error: lto-wrapper failed

collect2.exe: error: ld returned 1 exit status

exit status 1
Fehler beim Kompilieren für das Board Arduino/Genuino Uno.

Hier nochmal die .h

#ifndef My_mfrc522_h
#define My_mfrc522_h
#include "Arduino.h"
#include <MFRC522.h>
class My_mfrc522
{
  private:
    MFRC522 mfrc522;
    bool _last_IsNewCardPresent = false;
    byte _ss_pin;
    byte _rst_pin;
    
  public:
    My_mfrc522(byte SS_PIN, byte RST_PIN);
    bool init();
    bool checkRfidTag();
    void getTagId(byte *_uid);
};
#endif

und die cpp

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


My_mfrc522::My_mfrc522(byte ss_pin, byte rst_pin) : _ss_pin(ss_pin), _rst_pin(rst_pin), mfrc522(ss_pin, rst_pin)
{
}

bool My_mfrc522::init()
{
  mfrc522.PCD_Init();
  Serial.println("init");
  return true;
}

bool My_mfrc522::checkRfidTag()
{
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
  MFRC522::StatusCode status;

  if (mfrc522.PICC_IsNewCardPresent()) {
    _last_IsNewCardPresent = true;
    Serial.println("true 1");
    return true;
  }
  else if (_last_IsNewCardPresent) {
    _last_IsNewCardPresent = false;
    Serial.println("true2");
    return true;
  }
  else {
    Serial.println("false");
    return false;
  }
}

void My_mfrc522::getTagId(byte *_uid)
{
  if (mfrc522.PICC_ReadCardSerial()) {
    _uid[0] = mfrc522.uid.uidByte[0];
    _uid[1] = mfrc522.uid.uidByte[1];
    _uid[2] = mfrc522.uid.uidByte[2];
    _uid[3] = mfrc522.uid.uidByte[3];
    mfrc522.PCD_StopCrypto1();
  }
}

Wenn ich es mit dem Zeiger probiere, kompiliert er zwar ohne fehlermeldung, aber

mfrc522->PICC_IsNewCardPresent()

erkennt nicht, dass ein RFID TAG in reichweite ist. Bevor ich versucht habe alles in eine class auszulagern hats so funktioniert, dass mfrc522.PICC_IsNewCardPresent() ein true zurückliefert wenn eine karte in reichweite ist und wenn ich die UID auslese dann immer zwischen true und false hin und her wechselt, was soweit ich verstanden habe mit der antikollisionsprüfung zusammen hängt. jetzt bekomm ich nur ein false, egal ob eine karte da ist oder nicht. lade ich die alte version ohne klasse rein, funktionierts.

lto1.exe: internal compiler error: Segmentation fault

ToolChain defekt

Es ist kein Problem mit deinem Programm.

Die Reihenfolge in der Initialisierungsliste muss die gleiche sein wie im Header. Statt einfach den Stern zu entfernen hast du das Objekt jetzt als erstes

Wobei ich eigentlich nicht sehe wieso du die Pin-Nummern überhaupt in deiner eigenen Klasse abspeicherst. Das kann man sich sparen. Das reicht:

My_mfrc522::My_mfrc522(byte ss_pin, byte rst_pin) : mfrc522(ss_pin, rst_pin)
{
}

Und dann die zwei Variablen entfernen. Wenn man so doch irgendwie abspeichern muss sollten sie const sein

Ah perfekt vielen dank.

wisst ihr woran das mit der fehlermeldung lag? war die falsche reihenfolge die Uhrsache?

wisst ihr woran das mit der fehlermeldung lag?

Welche?

Hallo,

Problem: Segmentation fault, tritt immer nur sporadisch auf, wenn man das Problem hat, muss man manuell auf die neuere Toolchain wechseln. Gehe in der IDE in die Boardverwaltung und installiere die Erweiterung "Arduino AVR Boards v1.8.2", dann haste eine neuere Toolchain mit avr-gcc 7.3. Hätte dir combie auch gleich sagen können. :smiling_imp:

Hätte dir combie auch gleich sagen können. :smiling_imp:

Google: "arduino segmentation fault" Ungefähr 138.000 Ergebnisse
Dieses Forum: "segmentation fault" Ungefähr 312 Ergebnisse

Hallo,

ich verstehe dich manchmal wirklich nicht mit dem was du bezweckst.
Wir beide haben in der Hinsicht verschiedene Einstellungen.
Warum zur Hölle soll ich jemanden im Nebel stochern lassen der ein "Segmention Fault" hat?
Demjenigen kann ich auf Grund eigener Erfahrung mit dem Problem gleich kurz und schmerzlos sagen wie er die Toolchain aktualisiert und das Problem ist zu 99,99999999% behoben. Muss bei dir wirklich jeder das Rad neu erfinden?

Auf der einen Seite schreibst du FAQ Threads und Tipp & Tricks und auf der anderen Seite schreibst du Kurzantworten mit denen fast niemand etwas anfangen kann. Da du die Lösung selbst kennst, aktualisiere bitte deinen Link [Arduino IDE] Feinheiten und Tricks - Deutsch - Arduino Forum oder schreibe es direkt in deinen Thread.
Dann musste nur noch einen Link zu deinen Thread setzen. Das wäre eine ausreichende Kurzinformation. Wenn die FAQ Threads in den tiefen des Internets verschwinden war der Aufwand umsonst. Dann würde ich mich fragen warum dann erst die Arbeit machen wenn man es niemanden Neuen zukommen lässt. Momentan wissen das nur die alten Hasen. Leider nur die.

Wünsche noch einen guten Start ins Jahr 2020. :wink:

Leider kann ich deinen Anordnungen keine Folge leisten.

Ich sitze auf meiner Insel, habe einen begrenzten Horizont, und unvollständiges Wissen.
Bin nicht perfekt.

Du sitzt auf deiner Insel, hast einen begrenzten Horizont, und unvollständiges Wissen.
Bist nicht perfekt.

Manchmal überschneiden sich unsere Inseln ein wenig.
Dann verstehen wir uns, und arbeiten erfolgreich zusammen.
So es schon mehrfach geschehen ist.

Kollisionen gibt es erst, wenn du an meinem Inselchen rüttelst.
Wenn du meinst mir sagen zu müssen, was ich hier im Forum sagen soll, oder verschweigen sollte.

Von mir aus darfst du auf deinem Inselchen machen was du willst!
Du darfst hier gerne sagen, was du willst, egal ob mir die Art und Weise passt.
Aber wenn du erwartest, deine Spielregeln auf meiner Insel einzuführen zu dürfen .....

Niemals werde ich deine art zu helfen hier im Forum kritisieren. Zumindest gebe ich mir gesteigerte Mühe in die Richtung. Nicht nur bei dir, bei jedem.
Klarer: Ich rede jetzt und hier nicht von fachlicher Kritik!

Oder anders rum: (gilt auch für alle anderen)
Meine art zu helfen mag nicht jedem schmecken (z.B. dir) .....
Dazu kann ich nur sagen: Nimm aus meinen Hilfeversuchen, was dir sinnvoll erscheint.
Den Rest lass liegen.

Ist ein bisschen wie im Supermarkt....
Man muss nicht alles nehmen.
Nimm meine Gedanken wie sie sind, andere gibts von mir nicht.
Oder lass sie im Regal liegen.

Ich gönne dir deine Insel, lass mir bitte meine.
Ist es nicht gerade auch die Vielfalt der Persönlichkeiten, die es hier interessant macht.

Meinetwegen, habe verstanden. Pflege jeder seine Insel. Ferngläser besitzen wir beide. :wink:

Yes!

Auch im kommenden Jahr werden wir unsere konstruktiven Momente haben.
So ich hoffe!