Wie bereits im Thread für den Fensterdrehgriffkontakt beschrieben versuche ich die Firmware so anzupassen, dass sie ebenfalls einen Temperaturfühler ausliest und übermittelt. Die aktuellen Probleme sind:
Im WeatherChannel muss ich irgendwie an dev kommen, aktuell habe ich es so gemacht aber muss es noch initialisieren, wo/wie mache ich das?
class WeatherChannel : public Channel<Hal, WeatherList1, EmptyList, List4, PEERS_PER_CHANNEL, RHSList0>, public Alarm {
WeatherEventMsg msg;
int16_t temp;
uint16_t millis;
WeatherChannel& dev;
::OneWire _oneWire;
public:
WeatherChannel() : Channel(), Alarm(5), temp(0), millis(0), _oneWire(0) {}
virtual ~WeatherChannel() {}
// here we do the measurement
void measure() {
DPRINT("Measure...\n");
_oneWire.reset();
_oneWire.write(0xCC); // Select entire BUS
_oneWire.write(0x44); // start conversion, use ds.write(0x44,1) with parasite power on at the end
for(int i = 0; i < 800; i++)
delayMicroseconds(1000);
_oneWire.reset();
_oneWire.write(0xCC); // Select entire BUS
_oneWire.write(0xBE); // Read Scratchpad
uint8_t data[9];
for (uint8_t i = 0; i < 9; i++) { // we need 9 bytes
data[i] = _oneWire.read();
}
if (OneWire::crc8(data, 8) == data[8]) {
int16_t raw = (data[1] << 8) | data[0];
if ((raw * 10) / 16 != 850) {
temp = (raw * 10) / 16;
DPRINT("T = " + String(temp) + "\n");
}
else {
DPRINT("T INVALID!\n");
}
} else {
DPRINT("DS CRC INVALID!\n");
}
}
virtual void trigger(__attribute__((unused)) AlarmClock& clock) {
uint8_t msgcnt = device().nextcount();
// reactivate for next measure
tick = delay();
clock.add(*this);
measure();
msg.init(msgcnt, temp);
if (msgcnt % 20 == 1) device().sendPeerEvent(msg, *this); else device().broadcastEvent(msg, *this);
}
uint32_t delay() {
uint16_t _txMindelay = 180;
_txMindelay = dev.getList1().Sendeintervall();
if (_txMindelay == 0) _txMindelay = 180;
return seconds2ticks(_txMindelay);
}
void init(int pin) {
_oneWire.begin(pin);
}
void setup(Device<Hal, RHSList0>* dev, uint8_t number, uint16_t addr) {
Channel::setup(dev, number, addr);
sysclock.add(*this);
}
uint8_t status() const {
return 0;
}
uint8_t flags() const {
return 0;
}
};
Vermutlich muss ich sowas ähnliches tun wie
WeatherChannel(WeatherChannel& d) : Channel(), Alarm(5), temp(0), millis(0), dev(d), _oneWire(0) {}
aber so bekomme ich
Channel.h: 410:18: error: no matching function for call to 'WeatherChannel::WeatherChannel()
VirtChannel () {}
HB-SEC-RHS-3.ino:246: note candidate WeatherChannel WeatherChannel(WeatherChannel&)
WeatherChannel(WeatherChannel& d) *: Channel(), Alarm(5), temp(0), millis(0), dev(d), _oneWire(0) {}
^~~~~~~~~~~~~~
HB-SEC-RHS-3.ino:246: note candidate expects 1 argument, 0 provided
Warum ist im configChanged der cycleInfoMsg-Teil auskommentiert?
virtual void configChanged() {
if ( /*this->getList0().cycleInfoMsg() ==*/ true) {
DPRINTLN("Activate Cycle Msg");
sysclock.cancel(cycle);
cycle.set(CYCLETIME);
sysclock.add(cycle);
}
else {
DPRINTLN("Deactivate Cycle Msg");
sysclock.cancel(cycle);
}
}
Sieht soweit doch eigentlich richtig aus und als ob das sinnvoll wäre das mit reinzunehmen? Und muss ich von dem configChanged aus noch irgendwas tun um ein eventuell geändertes Sendeintervall von meinem WeatherChannel zu übernehmen? Oder das configChanged vom RHSType dort integrieren falls sich das auf die RHSList0 bezieht?
Im RHSType ist auch ein
TSDevice::configChanged();
mit drin, sollte ich das auch mit reinnehmen als
DeviceType::configChanged();
Wieso ist eigentlich im (originalen)
DEFREGISTER(Reg1,CREG_AES_ACTIVE,CREG_MSGFORPOS,CREG_EVENTDELAYTIME,CREG_LEDONTIME)
nichts für das transmitTryMax vorgesehen? Müsste da nicht auch ein REG für sein, ähnlich wie beim Reg0, wo ein DREG_TRANSMITTRYMAX? vorhanden ist?
An das Device kommst Du einfach mit der device() Methode der Channel-Klasse - ist ja die Basis.
https://github.com/pa-pa/AskSinPP/blob/711842f791a5365f8a928596fca4ab7af4155dd8/Channel.h#L38
Der Konstruktor muss zwinged leer sein. Sonst klappt die ganze Konstruktion nicht - deshalb auch der Fehler.
Warum die Abfrage auskommentiert ist, kann ich auch nicht (mehr) sagen.
Für den DS18b20 gibt es schon ne Klasse, die auch das Temperature-Interface implementiert.
https://github.com/pa-pa/AskSinPP/blob/711842f791a5365f8a928596fca4ab7af4155dd8/sensors/Ds18b20.h#L20
Ich habe nun alles soweit am laufen, nur verstehe ich das mit den Registern für die Konfiguration noch nicht so ganz: Was macht das DEFREGISTER und warum fehlt dort beim Original-Sketch für Reg1 das CREG_TRANSMITTRYMAX?
Das DEFREGISTER Macro erzeugt ein Array mit den RegisterAddressen und eine Klasse für den Zugriff. Ein Beispiel ist hier im Code: https://github.com/pa-pa/AskSinPP/blob/711842f791a5365f8a928596fca4ab7af4155dd8/Register.h#L273
CREG_TRANSMITTRYMAX gibt es hat für das Gerät nicht. Dann wird automatisch der Default-Wert genommen:
https://github.com/pa-pa/AskSinPP/blob/711842f791a5365f8a928596fca4ab7af4155dd8/Register.h#L448