Klasse in Klasse aufrufen

Hallo zusammen,

ich bin langsam ein wenig am verzweifeln..
Ich arbeite gerade an meiner Steuerung für meinen Stromverteiler und hab eben ein Software-Problem, auf dessen Lösung ich nicht komm:
Ich hab einige Sicherungen, die jeweils mit eine digital-I/O abgefragt werden und 2 mit zwei Pins. Ich hab jetzt eine Klasse für die Sicherungen geschrieben. Ebenso gibt es jeweils eine Klasse für Eingänge und für Ausgänge. Da die Ein- und Ausgänge mit Sicherungen verdrahtet sind, soll die Sicherungsklasse in der Ein- und Ausgangsklasse aufgerufen werden, aber da meckert der Compoiler immer und ich find einfach nicht warum :woozy_face:

fuse.h:

#pragma once

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

class Fuse
{
  private:
    uint8_t _pinOkay;
    uint8_t _pinNOkay;
    bool _state;
    bool _stateChanged;

    bool _secPin;
    uint8_t _debounceTime = 10;
    Bounce _pinState[2];

    bool _alarm;
    bool _alarmChanged;

  public:
    Fuse(uint8_t pinOkay, uint8_t pinNOkay = 100);
    void run();

    // Getter
    bool getState();
    bool getStateChanged();
    bool getAlarm();
    bool getAlarmChanged();
};

fuse.cpp:

#include "fuse.h"

Fuse::Fuse(uint8_t pinOkay, uint8_t pinNOkay = 100)
{
  _pinOkay = pinOkay;
  _pinNOkay = pinNOkay;

  pinMode(_pinOkay, INPUT_PULLUP);
  _pinState[0].attach(_pinOkay);
  _pinState[0].interval(_debounceTime);

  if (pinNOkay != 100)
  {
    _secPin = true;
    pinMode(_pinNOkay, INPUT_PULLUP);
    _pinState[1].attach(_pinNOkay);
    _pinState[1].interval(_debounceTime);
  }
}*/

input.h:

#pragma once

#include "Arduino.h"
#include "fuse.h"
//#include <Bounce2.h>

class Input
{
  private:
    // Members
    Fuse _lsFuse;

    bool _stateRelay;

  public:
    Input(uint8_t pinFuse, uint8_t pinRelay, uint8_t pinCheckL1, uint8_t pinCheckL2, uint8_t pinCheckL3, uint8_t countPole);
    void run();

    // Setter
    bool setRelay(bool state);
    
    // Getter
};

input.cpp:

#include "input.h"
#include "fuse.h"

Input::Input(uint8_t pinFuse, uint8_t pinRelay, uint8_t pinCheckL1, uint8_t pinCheckL2, uint8_t pinCheckL3, uint8_t countPole)
{
  _lsFuse = Fuse(pinFuse);

}

void Input::run()
{
  _lsFuse.run();
}

(Für die Übersicht hab ich alles nicht relevante weggelassen.)

Ich bekomm folgende Fehlermeldung:

steuerung/fuse.cpp:3:51: warning: default argument given for parameter 2 of 'Fuse::Fuse(uint8_t, uint8_t)' [-fpermissive]
 Fuse::Fuse(uint8_t pinOkay, uint8_t pinNOkay = 100)
                                                   ^
In file included from steuerung/fuse.cpp:1:0:
steuerung/fuse.h:22:5: note: previous specification in 'Fuse::Fuse(uint8_t, uint8_t)' here
     Fuse(uint8_t pinOkay, uint8_t pinNOkay = 100);
     ^~~~
steuerung/input.cpp: In constructor 'Input::Input(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t)':
input.cpp:4:126: error: no matching function for call to 'Fuse::Fuse()'
 Input::Input(uint8_t pinFuse, uint8_t pinRelay, uint8_t pinCheckL1, uint8_t pinCheckL2, uint8_t pinCheckL3, uint8_t countPole)
                                                                                                                              ^
In file included from steuerung/input.h:4:0,
                 from steuerung/input.cpp:1:
steuerung/fuse.h:22:5: note: candidate: Fuse::Fuse(uint8_t, uint8_t)
     Fuse(uint8_t pinOkay, uint8_t pinNOkay = 100);
     ^~~~
steuerung/fuse.h:22:5: note:   candidate expects 2 arguments, 0 provided
steuerung/fuse.h:6:7: note: candidate: constexpr Fuse::Fuse(const Fuse&)
 class Fuse
       ^~~~
steuerung/fuse.h:6:7: note:   candidate expects 1 argument, 0 provided
steuerung/fuse.h:6:7: note: candidate: constexpr Fuse::Fuse(Fuse&&)
steuerung/fuse.h:6:7: note:   candidate expects 1 argument, 0 provided
Bibliothek Bounce2 in Version 2.71 im Ordner: /home/*/Arduino/libraries/Bounce2  wird verwendet
exit status 1
no matching function for call to 'Fuse::Fuse()'

Wieso kann man Arduino nich einfach mit Python programmieren.. :roll_eyes:

Ich hoffe, dass ihr mir weiter helfen könnt.

Vielen Dank im voraus und
liebe Grüße

Fipschen

Hier fehlt der (default) Konstruktor ohne Parameter.

Ich würde im Konstruktor garkeine Parameter erwarten und die Pins über eine Fuse::begin(...) Methode nachreichen.

Oder mit Delphi :frowning:

Der Python Interpreter dürfte nur auf den richtig großen Arduinos laufen.

Ich hatte bei nem andrem Projekt von mir rein geschaut, da war es auch so, hat aber funktioniert.. :thinking: des war ja des, was mich gewundert hat.. :face_with_monocle:

So läuft's jez... danke dir

Delphi kenn ich nich, ich komm von PHP und MySQL und hab mit Pyhton auf'm Raspi bissl was gemacht.. die Typensicherheit und Pointer krieg ich nich in Kopf rein...
Ich hab bisher eig. eh immer nur mit dem Mega gearbeitet, weil ich immer auch einige I/Os brauch.. :sweat_smile:

Danke dir und
liebe Grüße

Fipschen

Delphi, genauer die freie Alternative Lazarus geht.

Gruß Tommy

Danke für den Hinweis :slight_smile:

Wenn du nicht zwingend an den Arduino gebunden bist, gibt es durchaus andere Microcontroller die mit Python programmiert werden können bzw in CircuitPython.

Oder Micropython.
Aber nicht vergessen: Python ist ein Interpreter. C(++) wird compiliert.

Gruß Tommy

Ich glaub "gebunden" is relativ. Ich hab schon ein paar Sachen damit realisiert und für die nächsten zwei Projekte schon die Hardware auf Arduino bassierend.
Bei ein paar Projekten hab ich ist der Arduino auch nur eine I/O-Erweiterung für'n Raspberry über USB/Serial.

Danke, werd ich mir beides mal anschauen.

Ja, das ist mir bewusst, danke.

Liebe Grüße

Fipschen

du hättest in der input.cpp die Instanz der Fuse mit einem Parameter anlegen müssen. Das Funktioniert in einer Intialisierungsliste.

Input::Input(uint8_t pinFuse, uint8_t pinRelay, uint8_t pinCheckL1, uint8_t pinCheckL2, uint8_t pinCheckL3, uint8_t countPole) : _lsFuse(pinFuse) {}

was mir generell auffällt:

  • du kannst die Parameter in der Initialisierungsliste übernehmen (nicht erst im Body des Konstruktors)
  • alles was Hardware-Zugriffe machen kann sollte nicht im Body sein, mach dafür eigene .begin() member functions und rufe diese separat in setup() auf (z.B. pinMode...)

Ja, das Problem hab ich ja jetzt hinbekommen. Ich hatte da irgend n Logikdreher im Kopf, frag mich nich mehr, welchen.. :sweat_smile: :sweat_smile:

Bei ersterem Punkt bin ich mir jetzt nicht ganz sicher, wie du das meinst...
...zweiteren hab ich schon umgebastelt, das ist jetzt alles in begin() drin, danke.

Liebe Grüße

Fipschen

Das eine Parameterübergabe bei der Objektanlage mit einer Initialisierungsliste gemacht werden kann.

Constructors and member initializer lists - cppreference.com

Initialisierungsliste /= Parameterübergabe im Konstruktor-Body.

Der mitlesende OOP-Anfänger würde sich darüber freuen, Deine Lösung auch sehen zu können. Das Prinzip eines öffentlichen Forums basiert auf Nehmen und Geben.

Wenn Du die Lösung dann noch als solche kennzeichnest, sieht man gleich in der Übersicht, das der Fragesteller eine zufriedenstellende Antwort gefunden hat :slightly_smiling_face:

ich würde das Umschreiben des Programms auf das Parameterinitialisieren in einer .begin() member function nicht als Lösung bezeichnen. Eher als Workaround.

ich bleib dabei, --> Initialisierungsliste

// https://forum.arduino.cc/t/klasse-in-klasse-aufrufen/1155361/8

//#include <Bounce2.h>
class Fuse {
  private:
    uint8_t _pinOkay;
    uint8_t _pinNOkay;
    bool _state;
    bool _stateChanged;

    bool _secPin = true;  // initialisieren geht auch hier
    uint8_t _debounceTime = 10;
    //Bounce _pinState[2];

    bool _alarm;
    bool _alarmChanged;

  public:
    Fuse(uint8_t pinOkay, uint8_t pinNOkay = 100) :
      _pinOkay(pinOkay), _pinNOkay(pinNOkay)
    {}

    void begin()    {
      pinMode(_pinNOkay, INPUT_PULLUP);
      //_pinState[1].attach(_pinNOkay);
      //_pinState[1].interval(_debounceTime);
    }

    void run() {}

    // Getter
    bool getState() {}
    bool getStateChanged() {}
    bool getAlarm() {}
    bool getAlarmChanged() {}
};


class Input {
  private:
    // Members
    Fuse _lsFuse;

    bool _stateRelay;    // bleibt uninitialisiert?!?
    uint8_t pinRelay;    // fehlte mir 
    uint8_t pinCheckL1;  // fehlte mir 
    uint8_t pinCheckL2;  // fehlte mir 
    uint8_t pinCheckL3;  // fehlte mir 
    uint8_t countPole;   // fehlte mir 

  public:
    Input(uint8_t pinFuse, uint8_t pinRelay, uint8_t pinCheckL1, uint8_t pinCheckL2, uint8_t pinCheckL3, uint8_t countPole) :
      _lsFuse(pinFuse),
      pinRelay(pinRelay), pinCheckL1(pinCheckL1), pinCheckL2(pinCheckL2), pinCheckL3(pinCheckL3), countPole(countPole) {}
    void run() {}

    void begin() {
      _lsFuse.begin();
    }

    // Setter
    bool setRelay(bool state) {}

    // Getter
};

Input input (1, 2, 3, 4, 5, 6);

void setup() {
  // put your setup code here, to run once:
  input.begin();
}

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

}

(ungetestet)

Hab mir gerade noch ein paar andere Seiten dazu angeschaut.. ich versteh die Syntax und den Sinn der Initialisierungslisten nicht wirklich.. :sweat_smile: würde aber auch behaupten, dass das für mich gerade nicht ganz so wichtig ist :sweat_smile:

Entschuldige, da hast du natürlich vollkommen recht! Ich hatte das zwischen Tür und Angel geantwortet, deshalb ging das dann unter bei mir.

fuse.h:

#pragma once

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

class Fuse
{
  private:
    uint8_t _pinOkay;
    uint8_t _pinNOkay;
    bool _state;
    bool _stateChanged;

    bool _secPin;
    uint8_t _debounceTime = 10;
    Bounce _pinState[2];

  public:
    Fuse();
    void begin(uint8_t pinOkay, uint8_t pinNOkay = 100);
    void run();

    // Getter
    bool getState();
};

fuse.cpp:

#include "fuse.h"

Fuse::Fuse()
{
  
}

void Fuse::begin(uint8_t pinOkay, uint8_t pinNOkay = 100)
{
  _pinOkay = pinOkay;
  _pinNOkay = pinNOkay;

  pinMode(_pinOkay, INPUT_PULLUP);
  _pinState[0].attach(_pinOkay);
  _pinState[0].interval(_debounceTime);

  if (pinNOkay != 100)
  {
    _secPin = true;
    pinMode(_pinNOkay, INPUT_PULLUP);
    _pinState[1].attach(_pinNOkay);
    _pinState[1].interval(_debounceTime);
  }
}

input.h:

#pragma once

#include "Arduino.h"
#include "fuse.h"
//#include <Bounce2.h>

class Input
{
  private:
    // Members
    Fuse _lsFuse = Fuse();
    uint8_t _pinRelay;

    const static uint8_t _countInputPins = 3;
    const uint8_t _debounceTime = 10;
    Bounce _pinState[_countInputPins];

    bool _stateRelay;

  public:
    Input(uint8_t pinFuse, uint8_t pinRelay, uint8_t pinCheckL1, uint8_t pinCheckL2, uint8_t pinCheckL3);
    void run();

    // Setter
    bool setRelay(bool state);
    
    // Getter
};

input.cpp:

#include "input.h"
#include "fuse.h"

Input::Input(uint8_t pinFuse, uint8_t pinRelay, uint8_t pinCheckL1, uint8_t pinCheckL2, uint8_t pinCheckL3)
{
  _lsFuse.begin(pinFuse);
  _pinRelay = pinRelay;

  pinMode(_pinRelay, OUTPUT);

  //_pinState[0].attach(_pinCheckL1);
  //_pinState[0].interval(_debounceTime);
}

void Input::run()
{

}

Der Übersicht halber hab ich das unnötige wieder raus geschmissen.

Vielen Dank und
liebe Grüße

Fipschen

Man freut sich so über die Lösung, daß man das Forum vergißt, ganz normal.

Danke, jetzt habe ich was zum Lesen :smiley:

und zum ausbessern, weil kompilieren wird das nicht ... ist wieder verstümmelt :wink:

der gesamte Code kompiliert ohne Probleme. Soll ich vllt. doch den ganzen Code posten, auch wenn's unübersichtlicher wird?

Liebe Grüße

Fipschen

nö, mach deine 4 gekürzten Dateien lauffähig. pack es in ein separates projekt probier es aus, poste die korrigierten dann.

Okay, ja, es war jetzt nur wegen dem kürzen ein paar Variablen-Probleme, die aber richtig rausgestrichen, funktioniert auch das gekürzte. Ich korrigier das im oberen Post noch. Da der Code so allein stehend eh nicht viel Sinn ergibt, hatte ich da jetzt nicht wirklich drauf geachtet, mir ging's nur um die Klasseneinbindung.
Danke dir

Liebe Grüße

Fipschen

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.