"Gerätekommunikation gestört" - HM-ES-TX-WM exakt 10x langsamer

Entwicklung und Bau von Hardware aller Art, die im HM-Umfeld eingesetzt werden kann

Moderator: Co-Administratoren

Antworten
FunnyPaul
Beiträge: 25
Registriert: 16.10.2022, 16:59
System: Alternative CCU (auf Basis OCCU)
Wohnort: 38820 Halberstadt
Hat sich bedankt: 2 Mal
Danksagung erhalten: 4 Mal

"Gerätekommunikation gestört" - HM-ES-TX-WM exakt 10x langsamer

Beitrag von FunnyPaul » 24.10.2022, 10:54

Hallo Freunde des gepflegten Forums,

ich habe einen HM-ES-TX-WM-CCU auf einen 328P-PU (im DIL-Gehäuse) auf dem Steckbrett geflasht und das System scheint exakt 10x langsamer als erwartet zu funktionieren, weshalb es auch zu einem Warnhinweis "Gerätekommunikation gestört" kommt.

Das System ist nativ per ISP geflasht und hat wohl auch die richtigen Fuses für den int. 8Mhz Oszi, ohne Teiler. (l:E2, h:D2, e:FE).

Um Lebenszeit während des Testens zu sparen habe ich die Übertragungszeit auf 60 Sekunden eingestellt:

Code: Alles auswählen

// we send the counter every 3 minutes
//#define MSG_CYCLE seconds2ticks(60 * 3)
#define MSG_CYCLE seconds2ticks(60)
Das System erhält einem Funktionsgenerator exakt alle 6 sek einen feinen Impuls. In der seriellen Ausgabe auch schön zu sehen. Statt nun nach dem ca. 10. Impuls die Anzahl zu übertragen, geschieht dies erst nach dem ca. 100. Impuls, siehe Bild:
Screenshot 2022-10-24 104319.png
Anmerkung: Wenn ich auf dem so "gefusten" Chip, ein dummy-Prog laufen lasse, welches alle 1.000 ms ein Sternchen auf SERIAL1 ausgibt, dann kommt das auch alle 1 sek.

Muss ich noch irgendwo einen Teiler o.ä. ausschalten - oder was mache ich falsch? :roll:
Alle sagten: "Das geht nicht!" Dann kam einer, der wusste das nicht und hat es einfach gemacht.

papa
Beiträge: 705
Registriert: 22.05.2018, 10:23
Hat sich bedankt: 24 Mal
Danksagung erhalten: 120 Mal

Re: "Gerätekommunikation gestört" - HM-ES-TX-WM exakt 10x langsamer

Beitrag von papa » 24.10.2022, 11:10

Gibt es den ganzen Sketch irgendwo zu sehen ?
Anfragen zur AskSin++ werden nur im Forum beantwortet

FunnyPaul
Beiträge: 25
Registriert: 16.10.2022, 16:59
System: Alternative CCU (auf Basis OCCU)
Wohnort: 38820 Halberstadt
Hat sich bedankt: 2 Mal
Danksagung erhalten: 4 Mal

Re: "Gerätekommunikation gestört" - HM-ES-TX-WM exakt 10x langsamer

Beitrag von FunnyPaul » 24.10.2022, 12:53

Ja, gerne, ist direkt aus dem Beispiel / github:

Code: Alles auswählen

//- -----------------------------------------------------------------------------------------------------------------------
// AskSin++
// 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
//- -----------------------------------------------------------------------------------------------------------------------
// ci-test=yes board=328p aes=no
// 
// https://raw.githubusercontent.com/jp112sdl/Beispiel_AskSinPP/master/examples/HM-ES-TX-WM_CCU/HM-ES-TX-WM_CCU.ino
// 
// define this to read the device id, serial and device type from bootloader section
// #define USE_OTA_BOOTLOADER

#define EI_NOTEXTERNAL
#include <EnableInterrupt.h>
#include <AskSinPP.h>
#include <LowPower.h>

#include <MultiChannelDevice.h>

// we use a Pro Mini
// Arduino pin for the LED
// D4 == PIN 4 on Pro Mini
#define LED_PIN 4
// Arduino pin for the config button
// B0 == PIN 8 on Pro Mini
#define CONFIG_BUTTON_PIN 8
// Arduino pin for the counter impulse
// A0 == PIN 14 on Pro Mini
#define COUNTER1_PIN 14
// we send the counter every 3 minutes
//#define MSG_CYCLE seconds2ticks(60 * 3)
#define MSG_CYCLE seconds2ticks(60)

// number of available peers per channel
#define PEERS_PER_CHANNEL 2

// all library classes are placed in the namespace 'as'
using namespace as;

// define all device properties
const struct DeviceInfo PROGMEM devinfo = {
    {0x90,0x00,0x05},       // Device ID
    "DKS-18-Gas",           // Device Serial
    {0x00,0xde},            // Device Model
    0x10,                   // Firmware Version
    as::DeviceType::PowerMeter, // Device Type
    {0x01,0x00}             // Info Bytes
};

/**
 * Configure the used hardware
 */
typedef AvrSPI<10, 11, 12, 13> SPIType;
typedef Radio<SPIType, 2> RadioType;
typedef StatusLed<LED_PIN> LedType;
typedef AskSin<LedType, BatterySensor, RadioType> HalType;

class MeterList0Data : public List0Data {
    uint8_t LocalResetDisbale : 1;   // 0x18 - 24
    uint8_t Baudrate : 8;   // 0x23 - 35
    uint8_t SerialFormat : 8;   // 0x24 - 36
    uint8_t MeterPowerMode : 8;   // 0x25 - 37
    uint8_t MeterProtocolMode : 8;   // 0x26 - 38
    uint8_t SamplesPerCycle : 8;   // 0x27 - 39

public:
    static uint8_t getOffset(uint8_t reg) {
        switch (reg) {
        case 0x18: return sizeof(List0Data) + 0;
        case 0x23: return sizeof(List0Data) + 1;
        case 0x24: return sizeof(List0Data) + 2;
        case 0x25: return sizeof(List0Data) + 3;
        case 0x26: return sizeof(List0Data) + 4;
        case 0x27: return sizeof(List0Data) + 5;
        default:   break;
        }
        return List0Data::getOffset(reg);
    }

    static uint8_t getRegister(uint8_t offset) {
        switch (offset) {
        case sizeof(List0Data) + 0:  return 0x18;
        case sizeof(List0Data) + 1:  return 0x23;
        case sizeof(List0Data) + 2:  return 0x24;
        case sizeof(List0Data) + 3:  return 0x25;
        case sizeof(List0Data) + 4:  return 0x26;
        case sizeof(List0Data) + 5:  return 0x27;
        default: break;
        }
        return List0Data::getRegister(offset);
    }
};

class MeterList0 : public ChannelList<MeterList0Data> {
public:
    MeterList0(uint16_t a) : ChannelList(a) {}

    operator List0& () const { return *(List0*)this; }

    // from List0
    HMID masterid() { return ((List0*)this)->masterid(); }
    void masterid(const HMID& mid) { ((List0*)this)->masterid(mid); }
    bool aesActive() const { return ((List0*)this)->aesActive(); }

    bool localResetDisable() const { return isBitSet(sizeof(List0Data) + 0, 0x01); }
    bool localResetDisable(bool value) const { return setBit(sizeof(List0Data) + 0, 0x01, value); }
    uint8_t baudrate() const { return getByte(sizeof(List0Data) + 1); }
    bool baudrate(uint8_t value) const { return setByte(sizeof(List0Data) + 1, value); }
    uint8_t serialFormat() const { return getByte(sizeof(List0Data) + 2); }
    bool serialFormat(uint8_t value) const { return setByte(sizeof(List0Data) + 2, value); }
    uint8_t powerMode() const { return getByte(sizeof(List0Data) + 3); }
    bool powerMode(uint8_t value) const { return setByte(sizeof(List0Data) + 3, value); }
    uint8_t protocolMode() const { return getByte(sizeof(List0Data) + 4); }
    bool protocolMode(uint8_t value) const { return setByte(sizeof(List0Data) + 4, value); }
    uint8_t samplesPerCycle() const { return getByte(sizeof(List0Data) + 5); }
    bool samplesPerCycle(uint8_t value) const { return setByte(sizeof(List0Data) + 5, value); }

    uint8_t transmitDevTryMax() const { return 6; }
    uint8_t ledMode() const { return 1; }

    void defaults() {
        ((List0*)this)->defaults();
    }
};

class MeterList1Data {
public:
    uint8_t  AesActive : 1;   // 0x08, s:0, e:1
    uint8_t  MeterType : 8;   // 0x95
    uint8_t  MeterSensibilityIR : 8;   // 0x9c
    uint32_t TxThresholdPower : 24;  // 0x7C - 0x7E
    uint8_t  PowerString[16];         // 0x36 - 0x46 : 06 - 21
    uint8_t  EnergyCounterString[16]; // 0x47 - 0x57 : 22 - 37
    uint16_t MeterConstantIR : 16;  // 0x96 - 0x97 : 38 - 39
    uint16_t MeterConstantGas : 16;  // 0x98 - 0x99 : 40 - 41
    uint16_t MeterConstantLed : 16;  // 0x9a - 0x9b : 42 - 43

    static uint8_t getOffset(uint8_t reg) {
        switch (reg) {
        case 0x08: return 0;
        case 0x95: return 1;
        case 0x9c: return 2;
        case 0x7c: return 3;
        case 0x7d: return 4;
        case 0x7e: return 5;
        default: break;
        }
        if (reg >= 0x36 && reg <= 0x57) {
            return reg - 0x36 + 6;
        }
        if (reg >= 0x96 && reg <= 0x9b) {
            return reg - 0x96 + 38;
        }
        return 0xff;
    }

    static uint8_t getRegister(uint8_t offset) {
        switch (offset) {
        case 0:  return 0x08;
        case 1:  return 0x95;
        case 2:  return 0x9c;
        case 3:  return 0x7c;
        case 4:  return 0x7d;
        case 5:  return 0x7e;
        default: break;
        }
        if (offset >= 6 && offset <= 37) {
            return offset - 6 + 0x36;
        }
        if (offset >= 38 && offset <= 43) {
            return offset - 38 + 0x96;
        }
        return 0xff;
    }
};

class MeterList1 : public ChannelList<MeterList1Data> {
public:
    MeterList1(uint16_t a) : ChannelList(a) {}

    bool aesActive() const { return isBitSet(0, 0x01); }
    bool aesActive(bool s) const { return setBit(0, 0x01, s); }
    uint8_t meterType() const { return getByte(1); }
    bool meterType(uint8_t value) const { return setByte(1, value); }
    uint8_t meterSensibilty() const { return getByte(2); }
    bool meterSensibilty(uint8_t value) const { return setByte(2, value); }
    uint32_t thresholdPower() const { return ((uint32_t)getByte(3) << 16) + ((uint16_t)getByte(4) << 8) + getByte(5); }
    bool thresholdPower(uint32_t value) const { return setByte(3, (value >> 16) & 0xff) && setByte(4, (value >> 8) & 0xff) && setByte(5, value & 0xff); }

    uint16_t constantIR() const { return ((uint16_t)getByte(38) << 8) + getByte(39); }
    bool constantIR(uint16_t value) const { return setByte(38, (value >> 8) & 0xff) && setByte(39, value & 0xff); }
    uint16_t constantGas() const { return ((uint16_t)getByte(40) << 8) + getByte(41); }
    bool constantGas(uint16_t value) const { return setByte(40, (value >> 8) & 0xff) && setByte(41, value & 0xff); }
    uint16_t constantLed() const { return ((uint16_t)getByte(42) << 8) + getByte(43); }
    bool constantLed(uint16_t value) const { return setByte(42, (value >> 8) & 0xff) && setByte(43, value & 0xff); }

    void defaults() {
        aesActive(false);
        meterType(0xff);
        meterSensibilty(0);
        thresholdPower(100 * 100);
        constantIR(100);
        constantGas(10);
        constantLed(10000);
    }
};

class GasPowerEventMsg : public Message {
public:
    void init(uint8_t msgcnt, bool boot, const uint64_t& counter, const uint32_t& power) {
        uint8_t cnt1 = (counter >> 24) & 0x7f;
        if (boot == true) {
            cnt1 |= 0x80;
        }
        Message::init(0x10, msgcnt, 0x54, BIDI | WKMEUP, cnt1, (counter >> 16) & 0xff);
        pload[0] = (counter >> 8) & 0xff;
        pload[1] = counter & 0xff;
        pload[2] = (power >> 16) & 0xff;
        pload[3] = (power >> 8) & 0xff;
        pload[4] = power & 0xff;
    }
};

class GasPowerEventCycleMsg : public GasPowerEventMsg {
public:
    void init(uint8_t msgcnt, bool boot, const uint64_t& counter, const uint32_t& power) {
        GasPowerEventMsg::init(msgcnt, boot, counter, power);
        typ = 0x53;
    }
};

class PowerEventMsg : public Message {
public:
    void init(uint8_t msgcnt, bool boot, const uint64_t& counter, const uint32_t& power) {
        uint8_t cnt1 = (counter >> 16) & 0x7f;
        if (boot == true) {
            cnt1 |= 0x80;
        }
        Message::init(0x0f, msgcnt, 0x5f, BIDI | WKMEUP, cnt1, (counter >> 8) & 0xff);
        pload[0] = counter & 0xff;
        pload[1] = (power >> 16) & 0xff;
        pload[2] = (power >> 8) & 0xff;
        pload[3] = power & 0xff;
    }
};

class PowerEventCycleMsg : public PowerEventMsg {
public:
    void init(uint8_t msgcnt, bool boot, const uint64_t& counter, const uint32_t& power) {
        PowerEventMsg::init(msgcnt, boot, counter, power);
        typ = 0x5e;
    }
};

class IECEventMsg : public Message {
public:
    void init(uint8_t msgcnt, uint8_t channel, const uint64_t& counter, const uint32_t& power, bool lowbat) {
        uint8_t cnt1 = channel & 0x3f;
        if (lowbat == true) {
            cnt1 |= 0x40;
        }
        Message::init(0x15, msgcnt, 0x61, BIDI | WKMEUP, cnt1, 0x00);
        pload[0] = (counter >> 32) & 0xff;
        pload[1] = (counter >> 24) & 0xff;
        pload[2] = (counter >> 16) & 0xff;
        pload[3] = (counter >> 8) & 0xff;
        pload[4] = counter & 0xff;
        pload[5] = 0x00; //
        pload[6] = (power >> 24) & 0xff;
        pload[7] = (power >> 16) & 0xff;
        pload[8] = (power >> 8) & 0xff;
        pload[9] = power & 0xff;
    }
};

class IECEventCycleMsg : public IECEventMsg {
public:
    void init(uint8_t msgcnt, uint8_t channel, const uint64_t& counter, const uint32_t& power, bool lowbat) {
        IECEventMsg::init(msgcnt, channel, counter, power, lowbat);
        typ = 0x60;
    }
};

class MeterChannel : public Channel<HalType, MeterList1, EmptyList, List4, PEERS_PER_CHANNEL, MeterList0>, public Alarm {

    const uint32_t    maxVal = 838860700;
    uint64_t          counterSum;
    volatile uint32_t counter; // declare as volatile because of usage withing interrupt
    Message           msg;
    uint8_t           msgcnt;
    bool              boot;

private:

public:
    MeterChannel() : Channel(), Alarm(MSG_CYCLE), counterSum(0), counter(0), msgcnt(0), boot(true) {}
    virtual ~MeterChannel() {}

    void firstinit() {
        Channel<HalType, MeterList1, EmptyList, List4, PEERS_PER_CHANNEL, MeterList0>::firstinit();
        getList1().meterType(number() == 1 ? 1 : 8);  // Channel 1 default Gas / Channel 2 default IEC
    }

    uint8_t status() const {
        return 0;
    }

    uint8_t flags() const {
        return device().battery().low() ? 0x80 : 0x00;
    }

    void next() {
        // only count rotations/flashes and calculate real value when sending, to prevent inaccuracy
        counter++;

        device().led().ledOn(millis2ticks(300));

#ifndef NDEBUG
        DHEXLN(counter);
#endif
    }

    virtual void trigger(AlarmClock& clock) {
        tick = MSG_CYCLE;
        clock.add(*this);

        uint32_t consumptionSum;
        uint32_t actualConsumption = 0;

        MeterList1 l1 = getList1();
        uint8_t metertype = l1.meterType(); // cache metertype to reduce eeprom access
        if (metertype == 0) {
            return;
        }

        // copy value, to be consistent during calculation (counter may change when an interrupt is triggered)
        uint32_t c;
        ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
        {
            c = counter;
            counter = 0;
        }
        counterSum += c;

        uint16_t sigs = 1;
        switch (metertype) {
        case 1: sigs = l1.constantGas(); break;
        case 2: sigs = l1.constantIR(); break;
        case 4: sigs = l1.constantLed(); break;
        default: break;
        }

        switch (metertype) {
        case 1:
            consumptionSum = counterSum * sigs;
            actualConsumption = (c * sigs * 10) / (MSG_CYCLE / seconds2ticks(60));

            // TODO handle overflow

            ((GasPowerEventCycleMsg&)msg).init(msgcnt++, boot, consumptionSum, actualConsumption);
            break;
        case 2:
        case 4:
            // calculate sum
            consumptionSum = (10000 * counterSum / sigs);
            // TODO handle overflow

            // calculate consumption whithin the last MSG_CYCLE period
            actualConsumption = (60 * 100000 * c) / (sigs * (MSG_CYCLE / seconds2ticks(60)));
            ((PowerEventCycleMsg&)msg).init(msgcnt++, boot, consumptionSum, actualConsumption);
            break;
        case 8:
            ((IECEventCycleMsg&)msg).init(msgcnt++, number(), counterSum, actualConsumption, device().battery().low());
            break;
        default:
            DPRINTLN("Unknown meter type");
            return;
            break;
        }

        device().sendPeerEvent(msg, *this);
        boot = false;
    }
};

typedef MultiChannelDevice<HalType, MeterChannel, 1, MeterList0> MeterType;

HalType hal;
MeterType sdev(devinfo, 0x20);

template <uint8_t pin, void (*isr)(), uint16_t millis>
class ISRWrapper : public Alarm {
    uint8_t curstate;
public:
    ISRWrapper() : Alarm(0), curstate(HIGH) {
        pinMode(pin, INPUT_PULLUP);
    }
    virtual ~ISRWrapper() {}

    bool checkstate() {
        uint8_t oldstate = curstate;
        curstate = digitalRead(pin);
        return curstate != oldstate;
    }

    uint8_t state() const {
        return curstate;
    }

    void attach() {
        if (digitalPinToInterrupt(pin) == NOT_AN_INTERRUPT)
            enableInterrupt(pin, isr, CHANGE);
        else
            attachInterrupt(digitalPinToInterrupt(pin), isr, CHANGE);
    }

    void detach() {
        if (digitalPinToInterrupt(pin) == NOT_AN_INTERRUPT)
            disableInterrupt(pin);
        else
            detachInterrupt(digitalPinToInterrupt(pin));
    }

    void debounce() {
        detach();
        tick = millis2ticks(millis);
        sysclock.add(*this);
    }

    virtual void trigger(__attribute__((unused)) AlarmClock& clock) {
        checkstate();
        attach();
    }
};
void counter1ISR();
ISRWrapper<COUNTER1_PIN, counter1ISR, 200> c1ISR;
void counter1ISR() {
    c1ISR.debounce();
    if (c1ISR.checkstate()) {
        if (c1ISR.state() == LOW) {
            sdev.channel(1).next();
        }
    }
}


ConfigButton<MeterType> cfgBtn(sdev);

void setup() {
    DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER);
    sdev.init(hal);

    buttonISR(cfgBtn, CONFIG_BUTTON_PIN);

    // measure battery every 1h
    hal.battery.init(seconds2ticks(60UL * 60), sysclock);
    // set low voltage to 2.2V
    hal.battery.low(22);
    hal.battery.critical(19);

    c1ISR.attach();
    // add channel 1 to timer to send event
    sysclock.add(sdev.channel(1));
    sdev.initDone();
}

void loop() {

    bool worked = hal.runready();
    bool poll = sdev.pollRadio();
    if (worked == false && poll == false) {
        hal.activity.savePower<Sleep<> >(hal);
    }

}
Alle sagten: "Das geht nicht!" Dann kam einer, der wusste das nicht und hat es einfach gemacht.

papa
Beiträge: 705
Registriert: 22.05.2018, 10:23
Hat sich bedankt: 24 Mal
Danksagung erhalten: 120 Mal

Re: "Gerätekommunikation gestört" - HM-ES-TX-WM exakt 10x langsamer

Beitrag von papa » 24.10.2022, 15:25

Und wo kommen die anderen Ausgaben her ?
Kann ich im Sketch nicht sehen.
Anfragen zur AskSin++ werden nur im Forum beantwortet

FunnyPaul
Beiträge: 25
Registriert: 16.10.2022, 16:59
System: Alternative CCU (auf Basis OCCU)
Wohnort: 38820 Halberstadt
Hat sich bedankt: 2 Mal
Danksagung erhalten: 4 Mal

Re: "Gerätekommunikation gestört" - HM-ES-TX-WM exakt 10x langsamer

Beitrag von FunnyPaul » 24.10.2022, 16:31

Die Ausgaben zum Counter, kommen die nicht hiervon (Zeile 316 ff)?:
#ifndef NDEBUG
DHEXLN(counter);
#endif
Alle sagten: "Das geht nicht!" Dann kam einer, der wusste das nicht und hat es einfach gemacht.

FunnyPaul
Beiträge: 25
Registriert: 16.10.2022, 16:59
System: Alternative CCU (auf Basis OCCU)
Wohnort: 38820 Halberstadt
Hat sich bedankt: 2 Mal
Danksagung erhalten: 4 Mal

Re: "Gerätekommunikation gestört" - HM-ES-TX-WM exakt 10x langsamer

Beitrag von FunnyPaul » 24.10.2022, 20:52

... komisch, nach einem neuen Anlernen - ohne etwas am Sketch oder Aufbau zu ändern, geht es plötzlich :shock:
Alle sagten: "Das geht nicht!" Dann kam einer, der wusste das nicht und hat es einfach gemacht.

papa
Beiträge: 705
Registriert: 22.05.2018, 10:23
Hat sich bedankt: 24 Mal
Danksagung erhalten: 120 Mal

Re: "Gerätekommunikation gestört" - HM-ES-TX-WM exakt 10x langsamer

Beitrag von papa » 24.10.2022, 21:45

Hm - na dann ist doch gut :-)
Anfragen zur AskSin++ werden nur im Forum beantwortet

Antworten

Zurück zu „Hardwareentwicklung und Selbstbau von Aktoren und Sensoren“