Interne Spannung AVcc wird nicht ausgewertet, Batteriestatus immer OK trotz Unterspannung
Moderator: Co-Administratoren
-
- 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
Interne Spannung AVcc wird nicht ausgewertet, Batteriestatus immer OK trotz Unterspannung
Hallo liebe Freunde,
leider habe ich noch ein Problem mit dem Nachbau des HM-ES-TX-WM (bzw. auch dem Einstiegsprojekt HM-RC-P1). Der Sketch ist Out of the Box von Github und funktioniert soweit nun auch prima. Das System befindet sich an einem Labornetzteil und wird derzeit mit 2.00 Volt aus einem Labornetzteil bettrieben. Beim Start kann man im seriellen Monitor auch schön sehen, dass der Wert auch so vom Prozessor gemessen wird:
Dann passiert aber nichts mehr und in der CCU scheint die Welt in Ordnung zu sein: Ich habe schon allerhand mit verschiedenen typedef's etc. experimentiert, aber ohne Erfolg. Sicherlich ein systematischer Fehler - aber welcher?
leider habe ich noch ein Problem mit dem Nachbau des HM-ES-TX-WM (bzw. auch dem Einstiegsprojekt HM-RC-P1). Der Sketch ist Out of the Box von Github und funktioniert soweit nun auch prima. Das System befindet sich an einem Labornetzteil und wird derzeit mit 2.00 Volt aus einem Labornetzteil bettrieben. Beim Start kann man im seriellen Monitor auch schön sehen, dass der Wert auch so vom Prozessor gemessen wird:
Dann passiert aber nichts mehr und in der CCU scheint die Welt in Ordnung zu sein: Ich habe schon allerhand mit verschiedenen typedef's etc. experimentiert, aber ohne Erfolg. Sicherlich ein systematischer Fehler - aber welcher?
Alle sagten: "Das geht nicht!" Dann kam einer, der wusste das nicht und hat es einfach gemacht.
-
- Beiträge: 12108
- Registriert: 20.11.2016, 20:01
- Hat sich bedankt: 848 Mal
- Danksagung erhalten: 2148 Mal
- Kontaktdaten:
Re: Interne Spannung AVcc wird nicht ausgewertet, Batteriestatus immer OK trotz Unterspannung
Auch nicht nach einer Stunde?
-
- 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: Interne Spannung AVcc wird nicht ausgewertet, Batteriestatus immer OK trotz Unterspannung
nein leider auch nicht nach jetzt 3 StundenAuch nicht nach einer Stunde?
Alle sagten: "Das geht nicht!" Dann kam einer, der wusste das nicht und hat es einfach gemacht.
-
- 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: Interne Spannung AVcc wird nicht ausgewertet, Batteriestatus immer OK trotz Unterspannung
nein leider auch nicht nach jetzt 3 Stunden
Alle sagten: "Das geht nicht!" Dann kam einer, der wusste das nicht und hat es einfach gemacht.
-
- Beiträge: 5427
- Registriert: 30.05.2019, 11:37
- System: Alternative CCU (auf Basis OCCU)
- Wohnort: Chemnitz
- Hat sich bedankt: 114 Mal
- Danksagung erhalten: 734 Mal
Re: Interne Spannung AVcc wird nicht ausgewertet, Batteriestatus immer OK trotz Unterspannung
Was steht denn in der Konfiguration der Batteriewarnschwelle wirklich drin? Vielleicht nicht mehr die 2,2 V Standard?
-
- 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: Interne Spannung AVcc wird nicht ausgewertet, Batteriestatus immer OK trotz Unterspannung
Siehe mein Bildchen oben, bzw. gerne hier nochmal:
Code: Alles auswählen
// 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);
Alle sagten: "Das geht nicht!" Dann kam einer, der wusste das nicht und hat es einfach gemacht.
-
- Beiträge: 12108
- Registriert: 20.11.2016, 20:01
- Hat sich bedankt: 848 Mal
- Danksagung erhalten: 2148 Mal
- Kontaktdaten:
Re: Interne Spannung AVcc wird nicht ausgewertet, Batteriestatus immer OK trotz Unterspannung
Welchen Sketch hast du genommen? Hast du was daran verändert?
Bitte mit Link oder wenn verändert, dann hier in Code-Tags posten
Bitte mit Link oder wenn verändert, dann hier in Code-Tags posten
-
- Beiträge: 5427
- Registriert: 30.05.2019, 11:37
- System: Alternative CCU (auf Basis OCCU)
- Wohnort: Chemnitz
- Hat sich bedankt: 114 Mal
- Danksagung erhalten: 734 Mal
Re: Interne Spannung AVcc wird nicht ausgewertet, Batteriestatus immer OK trotz Unterspannung
Ich kenne den Sketch nicht, aber meist steht die Batterieschwelle doch in den Konfigurationsdaten im EEPROM und das, was im Code als Initialwert drin steht, ist später unerheblich. Deshalb meine Frage, was WIRKLICH drin steht, nicht, womit ehemals initiiert wurde.
Läßt sich die Schwelle bei diesem Gerät denn in der CCU konfigurieren?
Läßt sich die Schwelle bei diesem Gerät denn in der CCU konfigurieren?
Zuletzt geändert von Matsch am 25.10.2022, 14:11, insgesamt 1-mal geändert.
-
- 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: Interne Spannung AVcc wird nicht ausgewertet, Batteriestatus immer OK trotz Unterspannung
Gerne:
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.
-
- 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: Interne Spannung AVcc wird nicht ausgewertet, Batteriestatus immer OK trotz Unterspannung
Wie soll das in den EEPROM kommen?
In der CCU kann ich nur den Sensor-Typ (Gas) und die Zählerkonstante (0,010) m³/ Impuls einstellen. - Oder gibt es da noch eine andere Stelle?
Alle sagten: "Das geht nicht!" Dann kam einer, der wusste das nicht und hat es einfach gemacht.