Skip to content

Commit

Permalink
Update readmes and pics for battery measurement
Browse files Browse the repository at this point in the history
  • Loading branch information
TomMajor committed Aug 31, 2018
1 parent 63e7f4e commit e7e559a
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 22 deletions.
4 changes: 2 additions & 2 deletions HB-SEC-WDS-2/HB-SEC-WDS-2.ino
Expand Up @@ -20,7 +20,7 @@
#include <LowPower.h>
#include <Register.h>
#include <ThreeState.h>
#include "Sensors/Sensor_Battery.h"
#include "Sensors/BatterySensorLoad.h"

//----------------------------------------------
// Pin definitions
Expand Down Expand Up @@ -139,7 +139,7 @@ public:
typedef AvrSPI<10,11,12,13> SPIType;
typedef Radio<SPIType,2> RadioType;
typedef StatusLed<LED_PIN> LedType;
typedef Sensor_Battery<BAT_SENS_PIN,BAT_ACT_PIN> BatSensorType;
typedef BatterySensorLoad<BAT_SENS_PIN,BAT_ACT_PIN> BatSensorType;
typedef AskSin<LedType,BatSensorType,RadioType> HalType;

DEFREGISTER(Reg0,DREG_CYCLICINFOMSG,MASTERID_REGS,DREG_TRANSMITTRYMAX)
Expand Down
10 changes: 3 additions & 7 deletions HB-SEC-WDS-2/README.md
Expand Up @@ -43,10 +43,6 @@ Ausgangsspannung DC

## Option 2: Echte Batteriezustandsmessung unter Last, um frühzeit leere Batterien zu erkennen und zu tauschen.

Dazu wird eine neue Batterieklasse nach Vorbild von papas Batterieklassen erstellt. Sie heißt hier Sensor_Battery und befindet sich unter Sensors/Sensor_Battery.h <br>
Mit dieser Klasse wird die Batterie oder der Akku für 200ms mit 75mA belastet. Momentan geschieht das 2 mal am Tag.<br>
Der Belastungsstrom lässt sich durch die Widerstände R5/R6 ändern, das Interval für die Messung in dieser Zeile:
`hal.battery.init(seconds2ticks(60UL*60*12), sysclock, 2000);
// 2x Batt.messung täglich, Spannungsteiler 1:2`

![pic](Images/Class_Sensor_Battery.jpg)
siehe
[HB-UNI-Sensor1](https://github.com/TomMajor/AskSinPP_Examples/tree/master/HB-UNI-Sensor1)
Abschnitt "Option3: Echte Batteriespannungsmessung unter Last"
Expand Up @@ -8,18 +8,18 @@
namespace as {

template <uint8_t SENSPIN, uint8_t ACTIVATIONPIN>
class Sensor_Battery : public Alarm {
class BatterySensorLoad : public Alarm {

uint8_t m_SensePin, m_ActivationPin;
uint16_t m_LastValue, m_Low, m_Critical, m_Factor;
uint32_t m_Period;

public:
Sensor_Battery () : Alarm(0), m_LastValue(0), m_Period(0), m_Low(0), m_Critical(0), m_Factor(2000), m_SensePin(SENSPIN), m_ActivationPin(ACTIVATIONPIN) {}
virtual ~Sensor_Battery() {}
BatterySensorLoad () : Alarm(0), m_LastValue(0), m_Period(0), m_Low(0), m_Critical(0), m_Factor(2000), m_SensePin(SENSPIN), m_ActivationPin(ACTIVATIONPIN) {}
virtual ~BatterySensorLoad() {}

virtual void trigger (AlarmClock& clock) {
DPRINTLN(F("Battery trigger"));
DPRINTLN(F("BattLoad trigger"));
tick = m_Period;
clock.add(*this);
m_LastValue = voltage();
Expand All @@ -35,7 +35,7 @@ class Sensor_Battery : public Alarm {

void critical (uint16_t value) {
m_Critical = value;
DPRINT(F("Battery set crit: ")); DDECLN(m_Critical);
DPRINT(F("BattLoad set crit: ")); DDECLN(m_Critical);
}

bool low () const {
Expand All @@ -44,7 +44,7 @@ class Sensor_Battery : public Alarm {

void low (uint16_t value) {
m_Low = value;
DPRINT(F("Battery set low: ")); DDECLN(m_Low);
DPRINT(F("BattLoad set low: ")); DDECLN(m_Low);
}

void init(uint32_t period, AlarmClock& clock, uint16_t factor = 2000) {
Expand Down Expand Up @@ -84,7 +84,7 @@ class Sensor_Battery : public Alarm {
digitalWrite(m_ActivationPin, LOW); // N-Channel Mosfet off

adc = 11UL * m_Factor * (ADC & 0x3FF) / 1024 / 10;
DPRINT(F("Battery voltage: ")); DDECLN(adc);
DPRINT(F("BattLoad voltage: ")); DDECLN(adc);
return (uint16_t)adc;
}
};
Expand Down
Binary file added HB-UNI-Sensor1/Images/Batteriemessung.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified HB-UNI-Sensor1/Images/Schaltung.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions HB-UNI-Sensor1/README.md
Expand Up @@ -16,6 +16,7 @@ Beispiel:<br>
- Ich empfehle den MAX44009 Helligkeitssensor anstatt dem TSL2561, siehe<br>
[SensorTest_Lux](https://github.com/TomMajor/AskSinPP_Examples/tree/master/Info/SensorTest_Lux)


# Benötige Libraries

[AskSinPP Library](https://github.com/pa-pa/AskSinPP)</br>
Expand All @@ -42,20 +43,58 @@ Für einen SHT10 Sensor (Feuchte):</br>
# Schaltung
![pic](Images/Schaltung.png)


# Messung der Batteriespannung

![pic](Images/Batteriemessung.png)

- Option1: Batteriespannungsmessung Standard (UBatt = Betriebsspannung AVR)<br>
keine zusätzliche Hardware notwendig<br>
`typedef AskSin<LedType, BatterySensor, RadioType> BaseHal;`<br>

- Option2: Batteriespannungsmessung für Step-Up<br>
2 zusätzliche Widerstände notwendig, Verwendung der Batterieklasse BatterySensorUni<br>
`BatterySensorUni<17,7,3000>`<br>
`// sense pin = A1 = 15, activation pin = D7 = 7, Vcc nominal 3,0V`

- Option3: Echte Batteriespannungsmessung unter Last<br>
Sie dient u.a. dem Schutz vor einem "Babbling Idiot, siehe
[Babbling Idiot Protection](https://github.com/TomMajor/AskSinPP_Examples/tree/master/Info/Babbling%20Idiot%20Protection)
<br><br>
Aus meiner Sicht würde es sehr helfen, eine echte Messung des Batteriezustands unter Last zu haben, um frühzeitig leere Batterien zu erkennen und zu tauschen. Bekanntermaßen sagt eine Spannungsmessung an unbelasteter Batterie, je nach Batterie- bzw. Akkutyp, nicht viel über den Ladezustand aus.
<br><br>
Die Schaltung belastet die Batterie bzw. den Akku für einige Hundert Millisekunden und misst dabei die Spannung.
Dies führt meiner Meinung nach zu realistischeren Werten über den Batteriezustand als eine asynchrone und unbelastete Messung.
<br><br>
Dazu wurde eine neue Batterieklasse nach Vorbild von papas Batterieklassen erstellt. Sie heißt hier BatterySensorLoad und befindet sich unter Sensors/BatterySensorLoad.h <br>
Mit dieser Klasse und der Schaltung wird der 1,2V Akku mit ca. 75mA für die kurze Zeit der Messung belastet. Anpassungen an andere Spannungen und Ströme sind natürlich leicht über die Widerstände R5/R6 möglich. Momentan geschieht das 2 mal am Tag:
<br>
`TODO: code für Dekl. von BatterySensorLoad`<br>
`hal.battery.init(seconds2ticks(60UL*60*12), sysclock, 2000);`<br>
`// 2x Batt.messung täglich, Spannungsteiler 1:2`
<br><br>
Das Bild zeigt den Einbruch der Batteriespannung wenn für 200ms mit 75mA belastet wird. Die Spannung bricht um 142mV ein und wird am Ende der 200ms gemessen.
<br>
![pic](Images/BatterySensorLoad.png)


# Prototyp
![pic](Images/Prototyp_HB-UNI-Sensor1.jpg)


# CCU2/RaspberryMatic Installation
Einstellungen/Systemsteuerung/Zusatzsoftware -> Datei CCU_RM/HB-UNI-Sensor1-addon.tgz installieren.

![pic](Images/HB-UNI-Sensor1_Install.png)


# RaspberryMatic WebUI
Der angemeldete Sensor auf der RaspberryMatic:

![pic](Images/HB-UNI-Sensor1_WebUI.png)

![pic](Images/HB-UNI-Sensor1_Parameter.png)


# FHEM Installation
Die Datei FHEM/HMConfig_UniSensor1.pm nach /opt/fhem/FHEM kopieren, dann FHEM neustarten.
94 changes: 94 additions & 0 deletions HB-UNI-Sensor1/Sensors/BatterySensorLoad.h
@@ -0,0 +1,94 @@

#ifndef _SENSOR_BATTERY_H_
#define _SENSOR_BATTERY_H_

#include <Debug.h>
#include <AlarmClock.h>

namespace as {

template <uint8_t SENSPIN, uint8_t ACTIVATIONPIN>
class BatterySensorLoad : public Alarm {

uint8_t m_SensePin, m_ActivationPin;
uint16_t m_LastValue, m_Low, m_Critical, m_Factor;
uint32_t m_Period;

public:
BatterySensorLoad () : Alarm(0), m_LastValue(0), m_Period(0), m_Low(0), m_Critical(0), m_Factor(2000), m_SensePin(SENSPIN), m_ActivationPin(ACTIVATIONPIN) {}
virtual ~BatterySensorLoad() {}

virtual void trigger (AlarmClock& clock) {
DPRINTLN(F("BattLoad trigger"));
tick = m_Period;
clock.add(*this);
m_LastValue = voltage();
}

uint16_t current () const {
return m_LastValue;
}

bool critical () const {
return m_LastValue < m_Critical;
}

void critical (uint16_t value) {
m_Critical = value;
DPRINT(F("BattLoad set crit: ")); DDECLN(m_Critical);
}

bool low () const {
return m_LastValue < m_Low;
}

void low (uint16_t value) {
m_Low = value;
DPRINT(F("BattLoad set low: ")); DDECLN(m_Low);
}

void init(uint32_t period, AlarmClock& clock, uint16_t factor = 2000) {
m_Factor = factor;
pinMode(m_ActivationPin, OUTPUT);
digitalWrite(m_ActivationPin, LOW); // N-Channel Mosfet off
pinMode(m_SensePin, INPUT);
digitalWrite(m_SensePin, LOW); // pull-up off
m_LastValue = voltage();
m_Period = period;
tick = m_Period;
clock.add(*this);
}

virtual uint16_t voltage() {
uint8_t timeout;
uint32_t adc;

// setup ADC: complete ADC init in case other modules have chamged this
ADCSRA = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0; // enable ADC, prescaler 128 = 62.5kHz ADC clock @8MHz (range 50..1000 kHz)
ADMUX = 1<<REFS1 | 1<<REFS0; // AREF: Internal 1.1V Voltage Reference with external capacitor at AREF pin
ADCSRB = 0;
uint8_t channel = m_SensePin - PIN_A0;
ADMUX |= (channel & 0x0F); // select channel
//delay(30); // load CVref 100nF, 5*Tau = 25ms -> not needed here because of delay(300) below

digitalWrite(m_ActivationPin, HIGH); // N-Channel Mosfet on
delay(200); // Batterie vor der Messung für 200ms belasten

// 1x dummy read
ADCSRA |= 1<<ADSC; timeout = 50;
while (ADCSRA & (1<<ADSC)) { delayMicroseconds(10); timeout--; if (timeout==0) break; }

ADCSRA |= 1<<ADSC; timeout = 50;
while (ADCSRA & (1<<ADSC)) { delayMicroseconds(10); timeout--; if (timeout==0) break; }

digitalWrite(m_ActivationPin, LOW); // N-Channel Mosfet off

adc = 11UL * m_Factor * (ADC & 0x3FF) / 1024 / 10;
DPRINT(F("BattLoad voltage: ")); DDECLN(adc);
return (uint16_t)adc;
}
};

}

#endif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 6 additions & 6 deletions Info/Babbling Idiot Protection/README.md
Expand Up @@ -19,15 +19,15 @@ Die CCU sagte mir "Kommunikationsstörung" zu so ziemlich allen meinen Geräten.
[[Quelle: FHEM Forum, Antw: AskSin++ Library]](https://forum.fhem.de/index.php/topic,57486.msg783197.html#msg783197)


#### Eine weiteres Beispiel:
#### Ein weiteres Beispiel:

> *Mich hat jemand angeschrieben, der das 8fach-DS18B20 Projekt nachgebaut hat und - oh Wunder - bei leerer Batterie einen BI hatte! :<br>
Du sag mal, wenn der Temperatursensor leer wird, also die Batterien zu schwach sind, warum geht dann hier keine Funkfernbedienung mehr?*

[Quelle: Projekt 8fach-DS18B20, Info über Private Nachricht erhalten]


#### Eine weiteres Beispiel:
#### Noch ein Beispiel:

> *Re: schlagartig Kommunikationsstörungen<br>
Schließlich habe ich die Ursache gefunden: Ein einziger Sensor HM-SCI-3-FM hat den Funkverkehr weitgehend lahmgelegt. Ob nur die Batterie entladen ist oder der Sensor defekt muss ich noch untersuchen.<br>
Expand All @@ -36,7 +36,7 @@ Auf die Spur hat mich CCU-Historian gebracht, der bei mir auch alle (Alchy-)Syst
[[Quelle: homematic-forum, schlagartig Kommunikationsstörungen]](https://homematic-forum.de/forum/viewtopic.php?f=65&t=43150)


#### Eine weiteres Beispiel:
#### Und noch ein Beispiel:

> Jetzt hab' ich tatsächlich exakt das vom Themenersteller beschriebene Problem - allerdings leider bislang ohne Lösung.<br>
Meine Zentrale zeigt zwischen 60 und 120 Servicemeldungen an, und selbst Direktverknüpfungen funktionieren nur noch, wenn man den Sender wenige Zentimenter nah an den Empfänger bringt.<br>
Expand Down Expand Up @@ -68,6 +68,8 @@ Der BI könnte entstehen, wenn beim Senden die Batteriespannung so weit zusammen
Ich möchte außerdem anmerken dass die Störung des Programmablaufes beim Senden nicht nur durch den AVR entstehen kann sondern wahrscheinlich auch durch den CC1101 selbst. Dieser hat ebenso einen Mikrocontroller mit Firmware integriert, die beim Senden aufgrund des Spannungseinbruchs genau so wie der AVR abstürzen könnte.<br>
Ob ein BI also im AVR oder CC1101 entsteht kann nur durch Messung im Falle des Falles am Gerät bewiesen werden, wegen der Reproduzierbarkeit ein schwieriges Unterfangen.

![pic](Images/Schaltung.png)

### Schaltung A

Aus meiner Sicht würde es sehr helfen, eine echte Messung des Batteriezustands unter Last zu haben, um frühzeitig leere Batterien zu erkennen und zu tauschen. Bekanntermaßen sagt eine Spannungsmessung an unbelasteter Batterie, je nach Batterie- bzw. Akkutyp, nicht viel über den Ladezustand aus.<br>
Expand All @@ -77,7 +79,7 @@ Dies führt meiner Meinung nach zu realistischeren Werten über den Batteriezust
Mit Schaltung A wird der 1,2V Akku mit ca. 75mA für die kurze Zeit der Messung belastet. Anpassungen an andere Spannungen und Ströme sind natürlich leicht über die Widerstände R5/R6 möglich.<br><br>
Das Bild zeigt den Einbruch der Batteriespannung wenn für 200ms mit 75mA belastet wird. Die Spannung bricht um 142mV ein und wird am Ende der 200ms gemessen. Aus meiner Sicht führt dies zu einer viel besseren Information über den Batteriezustand.<br>

![pic](Images/Batteriemessung_unter_Last.png)
![pic](Images/BatterySensorLoad.png)


### Schaltung B
Expand All @@ -98,5 +100,3 @@ Diese Maßnahme verwendet man am Besten wenn sicher ist dass der CC1101 und nich

Im momentanen Stadium der Prototypen verwende ich die Maßnahmen A und B, die die Sicherheit vor dem BI Zustand meines Erachtens deutlich erhöhen.<br>
Maßnahme C würde da noch mal eins drauf setzen und den CC1101 ebenfalls abschalten.

![pic](Images/Schaltung.png)

0 comments on commit e7e559a

Please sign in to comment.