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);
}
}