- Teil wg 9000 Zeichengrenze
flTSensorBaum.h
/*
Auswerten der DS1820 Sensoren und berichten
Vorausssetzung Sensoren Adresse in folgender Form:
DeviceAddress TA[2] = {
{ 0x28, 0x5F, 0x6A, 0xD7, 0x04, 0x00, 0x00, 0x16 }, // Heizung Rücklauf Heizkreis
{ 0x28, 0xC8, 0x68, 0xD2, 0x03, 0x00, 0x00, 0x6C }, // Heizung Rücklauf gesamt
};
*/
#ifndef __flTSensorBaum__
#define __flTSensorBaum__
#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>
class flTSensorBaum {
private:
// Achtung Reihenfolge der Deklaration ist wichtig
// oneWireA(ONE_WIRE_BUS), sensorsA(&oneWireA), TA(TA), _AnzSen(AnzSen)
byte _ONE_WIRE_BUS;
OneWire oneWireA;
DallasTemperature sensorsA;
DeviceAddress* TA;
byte _AnzSen;
int _GeraeteID;
byte _Temperature_Precision = 11; // 9 - 12 bit
const unsigned int _TempConvertZeit = 800; // Millisekunden Zeit für die Konvertierung; DS1820 Sensoren benötigen; normalerweise 750 Millisekunden
unsigned long _warteInterval = 60000 - _TempConvertZeit; // Messintervall 60000 -> 1 mal pro Min
unsigned long _timestamp;
byte _messStatus = 0;
unsigned int _AnzTempSensoren; // int da in array verwendet
float* TempA = 0;
float* lTempA = 0;
float _TempDiff; // Zwischenergebnis
float _MinTempDiff = 0.25; // Mindesttemperaturdifferenz, damit eine Übertragung stattfindet
public:
flTSensorBaum (byte ONE_WIRE_BUS, int GeraeteID, DeviceAddress* TA, byte AnzSen);
void begin(); // Hardware Initialisierung
void TempMelden(); // Auswerten der DS1820 Sensoren und berichten
// Setter
void setTemperature_Precision(byte Temperature_Precision); // Sucht die vorhandenen Sensoren, gibt deren Adressen aus und setzt Messgenauigkeit neu
void setTempIntervall(unsigned long TempIntervall) ;
void setMinTempDiff(float MinTempDiff) ;
void JetztLesen(); // zusätzliches Lesen der Temperatursensoren
void printAddress(DeviceAddress deviceAddress); // Funktion zur Ausgabe der SensorAddresse
};
#endif
flTSensorBaum.cpp
#include <flTSensorBaum.h>
flTSensorBaum::flTSensorBaum (const byte ONE_WIRE_BUS, const int GeraeteID, DeviceAddress* TA, byte AnzSen) : oneWireA(ONE_WIRE_BUS), sensorsA(&oneWireA), TA(TA), _AnzSen(AnzSen) {
_ONE_WIRE_BUS = ONE_WIRE_BUS;
_GeraeteID = GeraeteID;
}
void flTSensorBaum::begin() {
sensorsA.begin(); // library starten
delay(1000);
_AnzTempSensoren = sensorsA.getDeviceCount(); // Sensoren auf dem Bus ermittteln
Serial.print(F("GeraeteID: "));
Serial.println(_GeraeteID);
Serial.print(F("Temperatursenoren werden gesucht... Baum an Pin "));
Serial.println(_ONE_WIRE_BUS, DEC);
Serial.print(_AnzTempSensoren, DEC);
Serial.println(F(" Sensoren gefunden"));
TempA = new float [_AnzTempSensoren] ;
lTempA = new float [_AnzTempSensoren] ;
}
void flTSensorBaum::TempMelden() {
switch (_messStatus)
{
case 0 : // Ausgangszustand
// Temperaturermittlung anstoßen
sensorsA.setWaitForConversion(false); // asynchrone Temperaturabfrage geht schneller; jetzt muss aber über die Programmierung sichergestellt werden, dass die Abfrage erst erfolgt, wenn die Convertierung fertig ist. Vorteil: in der Zwischenzeit können andere Befehle abgearbeitet werden.
sensorsA.requestTemperatures(); // alle Temperatursensoren abfragen
_timestamp = millis();
_messStatus++;
break;
case 1 : // Messung ist angestoßen auf Ergebnis warten
if (millis() - _timestamp < _TempConvertZeit) return;
// Ergebnisse Lesen
for (uint8_t i = 0; i < _AnzTempSensoren; i++) {
TempA[i] = sensorsA.getTempC(TA[i]);
// Differenz zur vorherigen Messung ermitteln, nur bei Abweichung > _MinTempDiff übermitteln
_TempDiff = lTempA[i] - TempA[i];
_TempDiff = abs(_TempDiff); // keine Berechnungen innerhalb abs(); gemäß Doku
if (_TempDiff >= _MinTempDiff) {
// Werte übermitteln 131<DS1820>Sensor: 286ADA1E00004050 23.4</DS1820>
Serial.print(_GeraeteID);
Serial.print(F("<DS1820>Sensor: "));
printAddress(TA[i]);
Serial.print(F(" "));
Serial.print(TempA[i]); // Temp in Grad C
Serial.println(F("</DS1820>"));
lTempA[i] = TempA[i];
}
}
_timestamp += _TempConvertZeit;
_messStatus++;
break;
case 2 : // Pause bis zur nächsten Messung
if (millis() - _timestamp < _warteInterval) return;
_timestamp += _warteInterval;
_messStatus = 0;
break;
}
}
// Setter
void flTSensorBaum::setTemperature_Precision(byte Temperature_Precision) {
// Sucht die vorhandenen Sensoren, gibt deren Adressen aus und setzt Messgenauigkeit neu
_Temperature_Precision = constrain(Temperature_Precision, 9, 12); // 9 - 12 bit
_AnzTempSensoren = sensorsA.getDeviceCount(); // Sensoren auf dem Bus ermittteln
DeviceAddress neueAdressSammlung[_AnzTempSensoren];
Serial.println(F("Baum an Pin "));
Serial.println(_ONE_WIRE_BUS, DEC);
for (uint8_t i = 0; i < _AnzTempSensoren; i++)
{
Serial.print(F("Sensor "));
Serial.print(i);
Serial.print(F(" Adresse: "));
if (sensorsA.getAddress(neueAdressSammlung[i], i))
{
printAddress(neueAdressSammlung[i]);
// Genauigkeit auf oben definierten bit-Wert setzen
sensorsA.setResolution(neueAdressSammlung[i], _Temperature_Precision);
Serial.print(F(" Genauigkeit: "));
Serial.println(sensorsA.getResolution(neueAdressSammlung[i]), DEC);
}
else
{
Serial.print(F("Adressermittlung nicht moeglich für Sensor "));
Serial.println(i);
}
}
Serial.print(F("Parasitaerer Stromversorgungsmodus Baum an Pin "));
Serial.print(_ONE_WIRE_BUS, DEC);
if (sensorsA.isParasitePowerMode()) Serial.println(F(" ist ON"));
else Serial.println(F(" ist OFF"));
}
void flTSensorBaum::setTempIntervall(unsigned long TempIntervall) {
_warteInterval = constrain(TempIntervall, _TempConvertZeit + 100, 86400000) - _TempConvertZeit; // ConvertZeit und Zeit für Datenübertragung muss sein; 1 Tag ist Obergrenze
}
void flTSensorBaum::setMinTempDiff(float MinTempDiff) {
_MinTempDiff = constrain(MinTempDiff, 0 , 180); // nicht negativ, Messbereich -55 - 125°C -> 180 ist max. Unterschied
}
// zusätzliches Lesen der Temperatursensoren
void flTSensorBaum::JetztLesen() {
if (_messStatus == 2) {
_messStatus = 0;
}
}
// Funktion zur Ausgabe der SensorAddresse
void flTSensorBaum::printAddress(DeviceAddress deviceAddress) {
for (uint8_t i = 0; i < 8; i++) {
// zero pad the address if necessary
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}