[ERLEDIGT] HM-SEN-LI-O Nachbau mit BME280 möglich?

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

Moderator: Co-Administratoren

Antworten
Allodo
Beiträge: 85
Registriert: 27.04.2018, 21:48
Hat sich bedankt: 7 Mal

[ERLEDIGT] HM-SEN-LI-O Nachbau mit BME280 möglich?

Beitrag von Allodo » 22.06.2020, 10:42

ERLEDIGT!
Nachdem ich meinen Fehler in der Configdatei zum HB-UNI-Sensor1 behoben habe, läuft dieser jetzt seit gestern ohne Problem durch. Somit hat sich das Thema in Wohlgefallen aufgelöst.

Danke an dieser Stelle noch einmal an all die fleißigen Tüftler und Helfer, welche uns das Ganze hier ermöglichen :)

Hallo,

ich wollte für draußen einen Helligkeitssensor bauen und habe alles (BH1750 und BME280) auf eine HB-UNI-SEN-BATT-Platine verlötet.
Anschließend habe ich den HB-UNI-Sensor1-Sketch aufgespielt und anfänglich funktionierte es auch, aber nach nicht einmal 24 Stunden keine Übermittlung mehr von dem Gerät.

Also habe ich testweise mal den HM-SEN-LI-O-Sketch aufgespielt und siehe da, absolut stabil das Ganze.

Nun dachte ich mir, man müsste doch einen BME280 mit in den Sketch einbauen können, oder irre ich mich da?

Habe also mal den Teil mit dem BME280 aus dem HB-UNI-Sensor1-Sketch genommen und in dem HM-SEN-LI-O-Sketch kopiert. Aber es wird im Seriellen Monitor nur der Helligkeitssensor angezeigt.

Blicke da leider nicht so durch bzgl. RF-Types usw. Gibt es eine Doku bzgl. der Sketche usw., so dass man sich ein wenig einlesen kann?
Muss noch etwas definiert werden, damit die Anzeige im WebUI vom Homematic dargestellt werden?

Hier mal mein Versuch 2 Sketche zusammen zu führen

Code: Alles auswählen

//- -----------------------------------------------------------------------------------------------------------------------
// AskSin++
// 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
//- -----------------------------------------------------------------------------------------------------------------------

// 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 <Register.h>


#include <sensors/Bh1750.h>
#include <sensors/Bme280.h>

//#include <sensors/Tsl2561.h>
//#include <sensors/Max44009.h>

//#define SENSOR_CLASS MAX44009<>
#define SENSOR_CLASS Bh1750<>
//#define SENSOR_CLASS Tsl2561<>                   // Brücke zwischen L und GND
//#define SENSOR_CLASS Tsl2561<TSL2561_ADDR_HIGH>  // Brücke zwischen H und GND
//#define SENSOR_CLASS Tsl2561<TSL2561_ADDR_FLOAT> // keine Brücke gesetzt

#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

//Korrektur von Temperatur und Luftfeuchte
//Einstellbarer OFFSET für Temperatur -> gemessene Temp +/- Offset = Angezeigte Temp.
#define OFFSETtemp 0 //z.B -50 ≙ -5°C / 50 ≙ +5°C

//Einstellbarer OFFSET für Luftfeuchte -> gemessene Luftf. +/- Offset = Angezeigte Luftf.
#define OFFSEThumi 0 //z.B -10 ≙ -10%RF / 10 ≙ +10%RF

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

//seconds between sending messages
#define MSG_INTERVAL 180

#define LUX_EVENT_CYCLIC_TIME 120 //seconds to send cyclic message
#define LUX_EVENT_CYCLIC      0x53
#define LUX_EVENT             0x54

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

// define all device properties
const struct DeviceInfo PROGMEM devinfo = {
  {0x34, 0xfd, 0x02},     // Device ID
  "MYSENS0001",           // Device Serial
//  {0x00, 0xfd},           // Device Model
  {0x00, 0x40},           // Device Model
  0x01,                   // Firmware Version
//  0x53, // Device Type
  as::DeviceType::THSensor,  // 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> BaseHal;
class Hal : public BaseHal {
  public:
    void init (const HMID& id) {
      BaseHal::init(id);
      // measure battery every 1h
      battery.init(seconds2ticks(60UL * 60), sysclock);
      battery.low(22);
      battery.critical(19);
    }

    bool runready () {
      return sysclock.runready() || BaseHal::runready();
    }
} hal;

DEFREGISTER(LiReg0, MASTERID_REGS, DREG_TRANSMITTRYMAX, DREG_CYCLICINFOMSGDIS, DREG_LOCALRESETDISABLE, DREG_INTKEY)
class LiList0 : public RegList0<LiReg0> {
  public:
    LiList0 (uint16_t addr) : RegList0<LiReg0>(addr) {}
    void defaults () {
      clear();
      transmitDevTryMax(1);
      //cyclicInfoMsgDis(0);
      // intKeyVisible(false);
      // localResetDisable(false);
    }
};

DEFREGISTER(LiReg1, CREG_AES_ACTIVE, CREG_TX_MINDELAY, CREG_TX_THRESHOLD_PERCENT)
class LiList1 : public RegList1<LiReg1> {
  public:
    LiList1 (uint16_t addr) : RegList1<LiReg1>(addr) {}
    void defaults () {
      clear();
      aesActive(false);
      txMindelay(8);
      //txThresholdPercent(0);
    }
};

class LuxEventMsg : public Message {
  public:
    void init(uint8_t msgcnt, uint32_t lux, uint8_t type) {
      Message::init(0xf, msgcnt, type, RPTEN|WKMEUP, 0x00, 0xc1);
      pload[0] = (lux >> 24)  & 0xff;
      pload[1] = (lux >> 16) & 0xff;
      pload[2] = (lux >> 8) & 0xff;
      pload[3] = (lux) & 0xff;
    }
};

template <class SENSOR>
class LuxChannel : public Channel<Hal, LiList1, EmptyList, List4, PEERS_PER_CHANNEL, LiList0>, public Alarm {

    LuxEventMsg lmsg;
    uint32_t    lux;
    uint32_t    lux_prev;
    uint16_t    millis;

    SENSOR      sens;
    uint8_t     last_flags;
    uint8_t     cyclic_cnt;
    uint8_t     cyclic_dis_cnt;

  public:
    LuxChannel () : Channel(), Alarm(5), lux(0), lux_prev(0), millis(0), last_flags(0xff), cyclic_cnt(0), cyclic_dis_cnt(0) {}
    virtual ~LuxChannel () {}

    // here we do the measurement
    void measure () {
      DPRINT("Measure... ");
      sens.measure();
      lux = sens.brightness();
      DDEC(lux);
      DPRINTLN(" lux");
    }

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

    virtual void trigger (__attribute__ ((unused)) AlarmClock& clock) {
      cyclic_cnt++;

      uint8_t txMindelay = max(8,this->getList1().txMindelay());
      //DPRINT(F("TX_MINDELAY: ")); DDECLN(txMindelay);

      // reactivate for next measure
      set(seconds2ticks(txMindelay));
      clock.add(*this);

      // measure brightness
      measure();

      // if battery low is reached, send a message immediately
      if (last_flags != flags()) {
        this->changed(true);
        last_flags = flags();
      }

      bool sendMsg = false;

      uint8_t msgType = LUX_EVENT_CYCLIC;

      // send message as LUX_EVENT, but every 3 minutes as LUX_EVENT_CYCLIC
      uint8_t cyclicInfoMsgDis = device().getList0().cyclicInfoMsgDis();
      if (cyclic_cnt * txMindelay >= LUX_EVENT_CYCLIC_TIME) {

        if (cyclicInfoMsgDis == 0 || cyclic_dis_cnt >= cyclicInfoMsgDis) {
          sendMsg = true;
          cyclic_dis_cnt = 0;
        } else {
          cyclic_dis_cnt++;
        }

        cyclic_cnt = 0;
      }

      // check if lux is above/below threshold (if configured)
      uint8_t txThresholdPercent = this->getList1().txThresholdPercent();
      DPRINT(F("thresholdPcnt pcnt: "));DDECLN(txThresholdPercent);
      if (txThresholdPercent > 0) {  // a threshold is configured
        uint8_t pcnt = (lux_prev > 0) ? min(abs(100.0 / (lux_prev) * lux - 100), 100) : 100;
        if ((lux == 0) && (lux_prev == 0)) pcnt = 0; // so pcnt is not 100 if lux and lux_prev are 0
        DPRINT(F("lux changed   pcnt: "));DDECLN(pcnt);
        if (pcnt >= txThresholdPercent) { // the calculated percentage between lux_prev and lux is greater or equal to the configured txThresholdPercent
          lux_prev = lux;                 // save the current lux in lux_prev
          sendMsg = true;
          msgType = LUX_EVENT;
        }
      }

      if (sendMsg == true) {
        lmsg.init(device().nextcount(), lux * 100, msgType);

        if (msgType == LUX_EVENT_CYCLIC) {
          device().broadcastEvent(lmsg, *this);
        } else {
          lmsg.setAck();
          device().sendPeerEvent(lmsg, *this);
        }

      }

    }

    void setup(Device<Hal, LiList0>* dev, uint8_t number, uint16_t addr) {
      Channel::setup(dev, number, addr);
      sysclock.add(*this);
      sens.init();
    }

    uint8_t status () const {
      return 0;
    }
};

//NEU
class WeatherEventMsg : public Message {
  public:
    void init(uint8_t msgcnt, int16_t temp, uint8_t humidity, bool batlow) {
      uint8_t t1 = (temp >> 8) & 0x7f;
      uint8_t t2 = temp & 0xff;
      if ( batlow == true ) {
        t1 |= 0x80; // set bat low bit
      }
      Message::init(0xc, msgcnt, 0x70, BIDI | WKMEUP, t1, t2);
      pload[0] = humidity;
    }
};

class WeatherChannel : public Channel<Hal, List1, EmptyList, List4, PEERS_PER_CHANNEL, List0>, public Alarm {

    WeatherEventMsg msg;
    int16_t         temp;
    uint8_t         humidity;

    Bme280          bme280;
    uint16_t        millis;

  public:
    WeatherChannel () : Channel(), Alarm(5), temp(0), humidity(0), millis(0) {}
    virtual ~WeatherChannel () {}


    // here we do the measurement
    void measure () {
      DPRINT("Measure...\n");
      bme280.measure();

      temp = bme280.temperature() + OFFSETtemp;
      humidity = bme280.humidity() + OFFSEThumi;

      DPRINT("T/H = " + String(temp) + "/" + String(humidity) + "\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, humidity, device().battery().low());
      if (msgcnt % 20 == 1) device().sendPeerEvent(msg, *this); else device().broadcastEvent(msg, *this);
    }

    uint32_t delay () {
      return seconds2ticks(MSG_INTERVAL);
    }
    void setup(Device<Hal, List0>* dev, uint8_t number, uint16_t addr) {
      Channel::setup(dev, number, addr);
      bme280.init();
      sysclock.add(*this);
    }

    uint8_t status () const {
      return 0;
    }

    uint8_t flags () const {
      return 0;
    }
};
//NEU_ENDE
typedef MultiChannelDevice<Hal,LuxChannel<SENSOR_CLASS>, 1, LiList0> LuxType;

LuxType sdev(devinfo, 0x20);
ConfigButton<LuxType> cfgBtn(sdev);

void setup () {
  DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER);
  sdev.init(hal);
  buttonISR(cfgBtn, CONFIG_BUTTON_PIN);
  sdev.initDone();
}

void loop() {
  bool worked = hal.runready();
  bool poll = sdev.pollRadio();
  if ( worked == false && poll == false ) {
    if ( hal.battery.critical() ) {
      hal.activity.sleepForever(hal);
    }
    hal.activity.savePower<Sleep<>>(hal);
  }
}
Zuletzt geändert von Allodo am 23.06.2020, 08:32, insgesamt 1-mal geändert.

FrankenKai
Beiträge: 179
Registriert: 04.05.2020, 21:31
System: CCU
Hat sich bedankt: 16 Mal
Danksagung erhalten: 8 Mal

Re: HM-SEN-LI-O Nachbau mit BME280 möglich?

Beitrag von FrankenKai » 22.06.2020, 11:19

Allodo hat geschrieben:
22.06.2020, 10:42
Hallo,

ich wollte für draußen einen Helligkeitssensor bauen und habe alles (BH1750 und BME280) auf eine HB-UNI-SEN-BATT-Platine verlötet.
Anschließend habe ich den HB-UNI-Sensor1-Sketch aufgespielt und anfänglich funktionierte es auch, aber nach nicht einmal 24 Stunden keine Übermittlung mehr von dem Gerät.

....
Bist du dir sicher das nit die Spannungsüberwachung zugeschlagen hat und den Sensor in dauer Sleep versetzt?

Was sagt denn die Spannungsübertragung und welche werte hast du im scetch eingetragen?

Allodo
Beiträge: 85
Registriert: 27.04.2018, 21:48
Hat sich bedankt: 7 Mal

Re: HM-SEN-LI-O Nachbau mit BME280 möglich?

Beitrag von Allodo » 22.06.2020, 11:37

Auf der Platine ist keine aktive Spannungsüberwachung vorgesehen und im Sketch habe ich dazu nix eingetragen.

Vor dem Kopfschlag, lol.

In der Configdatei war Punkt 3 aktiviert und nicht Punkt 1.

Code: Alles auswählen

//---------------------------------------------------------
// Schaltungsvariante und Pins für Batteriespannungsmessung, siehe README
//------------
// 1) Standard: tmBattery, UBatt = Betriebsspannung AVR
#define BAT_SENSOR tmBattery
//------------
// 2) für StepUp/StepDown: tmBatteryResDiv, sense pin A0, activation pin D9, Faktor = Rges/Rlow*1000, z.B. 470k/100k, Faktor 570k/100k*1000 = 5700
//#define BAT_SENSOR tmBatteryResDiv<A0, 9, 5700>
//------------
// 3) Echte Batteriespannungsmessung unter Last, siehe README und Thema "Babbling Idiot Protection"
// tmBatteryLoad: sense pin A0, activation pin D9, Faktor = Rges/Rlow*1000, z.B. 10/30 Ohm, Faktor 40/10*1000 = 4000, 200ms Belastung vor Messung
//#define BAT_SENSOR tmBatteryLoad<A0, 9, 4000, 200>
Habe ich jetzt mal auf Punkt 1 geändert und schaue mal, was so passiert :)

FrankenKai
Beiträge: 179
Registriert: 04.05.2020, 21:31
System: CCU
Hat sich bedankt: 16 Mal
Danksagung erhalten: 8 Mal

Re: HM-SEN-LI-O Nachbau mit BME280 möglich?

Beitrag von FrankenKai » 22.06.2020, 12:48

Genau die Spannungsmessung unter last ist eine der Unterschiden beim uni Sensor um den Babbling Idiot zu vermeiden.
Wenn es mit der Option 1) geht , dann sind deine Batterien schwach. Oder der Strom für die Messung zu hoch gewählt. (wenn den die Schaltung dazu bestückt ist).

Allodo
Beiträge: 85
Registriert: 27.04.2018, 21:48
Hat sich bedankt: 7 Mal

Re: HM-SEN-LI-O Nachbau mit BME280 möglich?

Beitrag von Allodo » 22.06.2020, 13:20

Nicht so ganz, denn auf der HB-UNI-Sensor-Platine ist optional die Spannungsüberwachung per Hardware bestückbar. Dies ist wiederum auf der HB-UNI-SENS-BATT-Platine wohl nicht vorgesehen. Deshalb benötigte ich Punkt 1 statt 3.

Antworten

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