Anpassen der Fensterdrehgriffkontakt-Firmware

Begonnen von Flole, 11 August 2021, 22:22:46

Vorheriges Thema - Nächstes Thema

Flole

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?

papa

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.
BananaPi + CUL868 + CUL433 + HM-UART + 1Wire

papa

BananaPi + CUL868 + CUL433 + HM-UART + 1Wire

Flole

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?

papa

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
BananaPi + CUL868 + CUL433 + HM-UART + 1Wire