Um das Problem zu lösen, habe ich versucht SimpleTimer nach diesem Beispiel umzubauen:
#include <iostream>
using namespace std;
// Callback-Klasse für Memberfunktionen ohne Argumente und Rückgabewert
// (Die Signatur der Memberfunktion kann je nach bedarf geändert werden)
// Basisklasse (wird im Aufrufer des Callbacks benutzt)
class CallbackBase {
public:
virtual void operator()() = 0;
};
// abgeleitete Klasse (von dieser Klasse werden die Callback-Objekte
// instanziiert)
template <class C>
class Callback: public CallbackBase {
public:
Callback(C &obj, void (C::*method)()):
m_obj(obj), m_method(method) {}
virtual void operator()() { (m_obj.*m_method)(); }
private:
C &m_obj; // Objekt, dessen Memberfunktion aufgerufen werden soll
void (C::*m_method)(); // Zeiger auf die Memberfunktion
};
// Nun kommt ein Anwendungsbeispiel:
class Timer {
public:
Timer(): m_pcb(NULL) {}
void registerCallback(CallbackBase &cb) { m_pcb = &cb; }
void useCallback() { if(m_pcb) (*m_pcb)(); }
private:
CallbackBase *m_pcb;
};
// Zwei Beispielklassen, von denen eine Memberfunktion aufgerufen werden soll
// Beide Klassen sind der Timer-Klasse unbekannt.
class Test1 {
public:
Test1(int val): m_val(val) {}
void show() { cout << "Test1: " << m_val << endl; }
private:
int m_val;
};
class Test2 {
public:
Test2(int val): m_val(val) {}
void show() { cout << "Test2: " << m_val << endl; }
private:
int m_val;
};
int main() {
Timer timer;
// Je zwei Instanzen der beiden Beispielklassen
Test1 t11(111), t12(222);
Test2 t21(111), t22(222);
// Für jedes Beispielobjekt ein Callback-Objekt auf die memberfunktion 'show'
Callback<Test1> cb11(t11, &Test1::show), cb12(t12, &Test1::show);
Callback<Test2> cb21(t21, &Test2::show), cb22(t22, &Test2::show);
// Registrieren der vier Callback-Objekte und schauen, was passiert
timer.registerCallback(cb11);
timer.useCallback();
timer.registerCallback(cb12);
timer.useCallback();
timer.registerCallback(cb21);
timer.useCallback();
timer.registerCallback(cb22);
timer.useCallback();
return 0;
}
https://www.mikrocontroller.net/topic/155049
Eigentlich funktioniert das auch, aber wenn ich versuche eine Memberfunktion später als Timer Festzulegen, stürzt der arduino ab und beginnt von vorne.
Ein Beispiel dazu:
#include <MySimpleTimer.h>
MySimpleTimer timer;
class Bsp{
private:
MySimpleTimer& timer;
public:
Bsp(MySimpleTimer& timer) : timer(timer){
}
void init(){
Callback<Bsp> oEins(*this,&Bsp::eins);
timer.setTimer(1000, oEins, 5);
Callback<Bsp> oZwei(*this, &Bsp::zwei);
timer.setInterval(1000, oZwei);
Callback<Bsp> oDrei(*this, &Bsp::drei);
timer.setTimeout(10000, oDrei);
}
void eins(){
Serial.println("5 Mal und dann nie wieder");
Serial.flush();
}
void zwei(){
Serial.println("Immer");
Serial.flush();
}
void drei(){
Serial.println("Jetzt kommt der Fehler");
Callback<Bsp> oTest(*this, &Bsp::ichBinPutt);
int t = timer.setInterval(1000, oTest);
//timer.disable(t);
}
void ichBinPutt(){
Serial.println("Ich sollte erscheinen");
Serial.flush();
}
};
Bsp bsp(timer);
void setup() {
Serial.begin(9600);
bsp.init();
}
void loop() {
timer.run();
}
"ichBinPutt" wird zwar als Timer hinzugefügt, aber nie ausgeführt und ich hab keine Ahnung warum.
MySimpleTimer.zip (4.27 KB)