Objekt an Klasse übergeben

Moin,

bin seit neuerem in der Arduino Welt tätig, in dem ich mir ein Smarthome aufbaue, welches vorwiegend meine Beleuchtung steuert und ich nach und nach erweitere.

Derzeit stehe ich vor dem Problem, eine Reihe von LED Treibern die über ein Bus-System angesteuert werden über mehrere Instanzen einer Lichtfunktions-Library durch das immer gleiche Objekt einer Bus-Treiber Library aufzurufen.

Die LED Treiber werden über die ChainableLED Library angesteuert, von der ich im Sketch das Objekt leds erzeuge. Die ChainableLED Methode setColorRGB wird dann in der shine Methode der LightsRGB Library aufgerufen.

ChainableLED leds(clk_pin, data_pin, num_of_leds);

LightsRGB led1(0);
LightsRGB led2(1);

void setup() {
  leds.init();
}

void loop() {
  led1.shine();
  led2.shine();
}

Meine LightsRGB Library, mit der ich eine Dimmer- und Pulsier-Funktion für die LEDs ausführe...

class LightsRGB
{
  public:
    LightsRGB(int ledDriver);

    void dim(float dimTime, float dimLevel0, float dimLevel1, float dimLevel2);
    void pulse(float pulseLevel0, float pulseLevel1, float pulseLevel2, float pulseSlope, int pulseCount, float pulseRate, float pulsePause, int pulseRepeat);
    void shine();
}

In der Methode shine werden die Ausgangslevel des entsprechenden LED Treibers geändert und dann über das ChainableLED leds Objekt auf den Bus geschrieben

void Lights::shine() {
    ...

    leds.setColorRGB(_ledDriver, _ledLevel[0], _ledLevel[1], _ledLevel[2]);

    ...
}

Zuvor habe ich die LightsRGB Klasse direkt im Sketch programmiert und getestet, funktioniert tadellos.

Jetzt, nachdem ich die Klasse als Library verpackt habe bekomme ich diesen Fehler vom Compiler

...\Arduino\libraries\LightsRGB\LightsRGB.cpp: In member function 'void LightsRGB::shine()':

...Arduino\libraries\LightsRGB\LightsRGB.cpp:112:5: error: 'leds' was not declared in this scope

leds.setColorRGB(_ledDriver, _ledLevel[0], _ledLevel[1], _ledLevel[2]);

^

Die Library kennt das Objekt leds offenbar nicht, welches ich dann wohl irgendwie der LightsRGB Library, bzw. dessen Instanzen bekannt machen muss.
Mehrere Instanzen der ChainableLED Library, indem ich diese in der LightsRGB mit initiere schlägt insofern fehl, dass mehrere Instanzen den Bus nicht korrekt beschreiben. Beim Test überschrieben sich parallele Blinkvorgänge unterschiedlicher LEDs.

Ich habe durch suchen nach einer Lösung einige Ansätze versucht umzusetzen.
Da aber keine Lösung mir so Recht einleuchtete hatte ich mit keinem Ansatz Erfolg.
Daher schreibe ich die Versuche hier nicht auf, ich habe sie auch bereits alle verworfen.

Es sollte sich aber wohl in die Richtung "Zeiger auf das ChainableLED Objekt in der LightsRGB Library" bewegen, oder?

Könnt ihr mir einen Lösungsweg aufzeigen?

Danke und Gruß,
Björn

Sowohl die ChainableLED Klasse wie auch das globale Objekt leds muss deiner LightsRGB (oder Lights) bekannt sein.

Zur Not via

extern ChainableLED leds;

in deiner Library.

bjrnptrsn:
Es sollte sich aber wohl in die Richtung "Zeiger auf das ChainableLED Objekt in der LightsRGB Library" bewegen, oder?

Besser eine Referenz, da die nicht Null sein kann und nicht deferenziert werden muss. Die setzt man im Konstruktor

Ganz einfach:

class Class
{
public:
   Class(OtherClass& obj) : obj(obj)
   {
   }

private:
   OtherClass& obj;
};

Referenz ist gut, aber als Klassenelement besser einmal statisch einbauen, als in jede einzelne LightsRGB Instanz.

Wenn schon, dann würde ich die LightsRGB Klasse mit einem Array für die LEDs ausstatten, dann braucht man nur noch 1 Objekt dieser Klasse, und das kann dann ggf. auch gleich noch das ChainableLED Objekt erzeugen und als privat kapseln.

class ManyLightsRGB {
public:
  ManyLightsRGB(int clk_pin; int data_pin; int num_of_leds) : drvr(ChainableLED(clk_pin, data_pin, num_of_leds);
  void shine(int ledDriver);
private:
  ChainableLED &drvr;
//??? leds[]; //wie?
}
...
ManyLightsRGB(...) allesHierDrin;

Warnung: mein C++ ist stark angerostet!

Und auf das Dereferenzieren einer Referenz kann man nur syntaktisch verzichten, intern ist auch eine Referenz nur ein Pointer.

DrDiettrich:
Referenz ist gut, aber als Klassenelement besser einmal statisch einbauen, als in jede einzelne LightsRGB Instanz.

Dann mach es auch so. Dein Code macht was anderes. Es soll nur ein ChainableLED Objekt geben so wie ich das verstehe. Du versucht jedesmal ein neues Objekt zu erstellen.
Statische Objekte werden übrigens nicht in Konstruktoren erstellt, da sie nicht an eine Klasse gebunden sind.

Außerdem: wenn man das Objekt direkt im Konstruktor erzeugt braucht man keine Referenz. Der explizite Konstruktor Aufruf ist auch falsch

Und auf das Dereferenzieren einer Referenz kann man nur syntaktisch verzichten

Mehr soll es auch nicht sein. Ein Punkt lässt sich einfacher schreiben als ->

Ich meinte ganz was anderes als Du vermutest, mit nur 1 Objekt pro Klasse.

Eine statische Referenz außerhalb der Klasse wäre wohl die einfachste Lösung, aber wo, wie und wann soll diese Referenz erzeugt werden? Im Prinzip sollte das nicht viel komplizierter werden als der Pointer in #1, mir fällt nur kein C++ dazu ein. Dabei sollte ja auch möglichst verhindert werden, daß mehrere konkurrierende Instanzen der ChainableLED Klasse erzeugt werden - die muß hier ein Singleton bleiben. In Delphi könnte ich das alles hinschreiben, in C++ leider nicht :frowning: