[gelöst] MySensors DS18B20 Sketch Problem

Begonnen von Markus., 13 März 2017, 19:10:43

Vorheriges Thema - Nächstes Thema

Markus.

Hallo Zusammen,

ich habe mir einen Sensors basierend auf einem Pro Mini zusammengebaut für Batteriebetrieb. An dem Sensor sind zwei Wasserdichte Dallas Temp.Sensoren angeschlossen. Über den Spannungsteiler überwache ich die Batteriespannung. Dann habe ich das vorhandene Sketch auf Version 2.1 umgebaut. Funktioniert auch soweit alles super gut jedoch bekomm ich zum verrecken nicht den Spannungswert ans Gateway gesendet. Als Debug Wert auf Serial print funktioniert das und der Wert wird angezeigt. Irgendwie übersteigt das im Moment meine Programmierkenntnisse...
Hoffe da kann mir einer mal auf die Sprünge helfen..

Hier mal der Sketch.

// Enable debug prints to serial monitor
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_NRF24

// Example sketch showing how to send in OneWire temperature readings
#include <MySensors.h>
#include <SPI.h>
#include <DallasTemperature.h>
#include <OneWire.h>

#define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
#define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected
#define MAX_ATTACHED_DS18B20 16
unsigned long SLEEP_TIME = 300000; // Sleep time between reads (in milliseconds)
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

float lastTemperature[MAX_ATTACHED_DS18B20];
int numSensors=0;
boolean receivedConfig = false;
boolean metric = true;
// Initialize temperature message
MyMessage msg(0,V_TEMP);

int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
int oldBatteryPcnt = 0;

void setup()
{
// Startup OneWire
sensors.begin();

// Send the sketch version information to the gateway and Controller
sendSketchInfo("Temperature Sensor", "1.0");

// Fetch the number of attached temperature sensors
numSensors = sensors.getDeviceCount();

// Present all sensors to controller
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
present(i, S_TEMP);
}

// use the 1.1 V internal reference
analogReference(INTERNAL);
}

void loop()
{

// Fetch temperatures from Dallas sensors
sensors.requestTemperatures();

// Read temperatures and send them to controller
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
// Fetch and round temperature to one decimal
float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;

// Only send data if temperature has changed and no error
if (lastTemperature[i] != temperature && temperature != -127.00) {

  // Send in the new temperature
  send(msg.setSensor(i).set(temperature,1));
  lastTemperature[i]=temperature;
}
}

// get the battery Voltage
int sensorValue = analogRead(BATTERY_SENSE_PIN);
Serial.println(sensorValue);
// 1M, 470K divider across battery and using internal ADC ref of 1.1V
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point
// ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
// 3.44/1023 = Volts per bit = 0.003363075
float batteryV = sensorValue * 0.004106;
int batteryPcnt = sensorValue / 10;

Serial.print("Battery Voltage: ");
Serial.print(batteryV);
Serial.println(" V");
Serial.print("Battery percent: ");
Serial.print(batteryPcnt);
Serial.println(" %");
if (oldBatteryPcnt != batteryPcnt) {
// Power up radio after sleep
sendBatteryLevel(batteryPcnt);
oldBatteryPcnt = batteryPcnt;

}


sleep(SLEEP_TIME);
}



Gruß

Markus

Beta-User

Pack' mal den Block mit "Serial.print"s in die if-Abfrage. Dann siehst Du, ob die Bedingung wahr wird und eigentlich gesendet werden müßte.
Dann tauchen die Readings (auch die internen wie battery) uU. erst sichtbar auf, wenn man nach dem Senden des 1. Wertes einen Browser-refresh macht.

Vielleicht hilft schon letzteres. 

Und 2.1 ist hoffentlich 2.1.1, und nicht 2.1.0 (da gab es nRF-seitig noch verschluckte Werte)!

Gruß,
Beta-User
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Markus.

Hallo Beta-user,

Der Prozentwert der Batterieladung wird ja einwandfrei als Reading übertragen. Es muss doch irgendwie an der Definition des Volt Werten liegen oder? Aber ich pack den Teil trotzdem mal in den IF-block und check das nochmal.

Gruß
Markus

Beta-User

OK,

jetzt habe ich Dein Anliegen vermutlich verstanden, Du willst neben dem %-Wert auch die absolute Voltage haben.

Dazu gibt es aber im Moment in dem von Dir geposteten Sketch gar keine Sende-Anweisung und - soweit mir ohne nähere Untersuchung bekannt - ist das jedenfalls als Internal auch gar nicht vorgesehen. Dazu müßtest Du Teile aus dem Multimeter-Sketch mit verwenden. (Dazu gab es in dem "Integration..."-Thread auch einige Beiträge vor ca. 3 Monaten).

Gruß, Beta-User
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Markus.

Genau, das wäre cool neben dem % auch die Voltage zu haben. Werde mich mal durch den Beitrag durchwühlen...

Vielen Dank nochmal !!

Gruß

Markus

Markus.

Also ich glaube ich hab die Lösung gefunden...:-)

So Funktioniert das Sketch nun bei mir.


// Enable debug prints to serial monitor
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_NRF24

// Example sketch showing how to send in OneWire temperature readings
#include <MySensors.h>
#include <SPI.h>
#include <DallasTemperature.h>
#include <OneWire.h>

#define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
#define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected
#define MAX_ATTACHED_DS18B20 3
#define VOLTAGE_CHILD_ID    5

unsigned long SLEEP_TIME = 300000; // Sleep time between reads (in milliseconds)
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

float lastTemperature[MAX_ATTACHED_DS18B20];
int numSensors=0;
boolean receivedConfig = false;
boolean metric = true;
// Initialize temperature message
MyMessage msg(0,V_TEMP);
MyMessage voltageMsg(VOLTAGE_CHILD_ID, V_VOLTAGE);

int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
int oldBatteryPcnt = 0;
int oldBatteryV = 0;

void setup()
{
// Startup OneWire
sensors.begin();

// Send the sketch version information to the gateway and Controller
sendSketchInfo("Temperature Sensor", "1.0");

// Fetch the number of attached temperature sensors
numSensors = sensors.getDeviceCount();

// Present all sensors to controller
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
present(i, S_TEMP);
}
present(VOLTAGE_CHILD_ID, S_MULTIMETER);


// use the 1.1 V internal reference
analogReference(INTERNAL);
}

void loop()
{

// Fetch temperatures from Dallas sensors
sensors.requestTemperatures();

// Read temperatures and send them to controller
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
// Fetch and round temperature to one decimal
float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;

// Only send data if temperature has changed and no error
if (lastTemperature[i] != temperature && temperature != -127.00) {

  // Send in the new temperature
  send(msg.setSensor(i).set(temperature,1));
  lastTemperature[i]=temperature;
}
}

// get the battery Voltage
int sensorValue = analogRead(BATTERY_SENSE_PIN);
Serial.println(sensorValue);
// 1M, 470K divider across battery and using internal ADC ref of 1.1V
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point
// ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
// 3.44/1023 = Volts per bit = 0.003363075
float batteryV = sensorValue * 0.004106;
int batteryPcnt = sensorValue / 10;

Serial.print("Battery Voltage: ");
Serial.print(batteryV);
Serial.println(" V");
Serial.print("Battery percent: ");
Serial.print(batteryPcnt);
Serial.println(" %");
if (oldBatteryPcnt != batteryPcnt) {
// Power up radio after sleep
sendBatteryLevel(batteryPcnt);
oldBatteryPcnt = batteryPcnt;
}
  if (oldBatteryV != batteryV) {
// Power up radio after sleep
send(voltageMsg.set(batteryV,2));
oldBatteryPcnt = batteryV;
  }


sleep(SLEEP_TIME);
}



Glaube das kann man noch schöner machen aber Ich bekomme jetzt alle Daten angezeigt die ich brauche...frooi,..

Gruß

Markus

Beta-User

Hi Markus,

mindestens folgendes kommt mir komisch vor:
- int oldBatteryV = 0;
Sollte wohl float statt int sein?
- oldBatteryPcnt = batteryV;
Gemeint ist wohl oldBatteryV, oder?

Anregung noch:
- metric
Es würde reichen, diesen Wert nur ein einziges Mal in setup() abzufragen, dann bräuchte es nachfolgend in der loop() keine getControllerConfig()-Aufrufe mehr (seit 2.1.0 wird setup() nach presentation() ausgeführt, ältere Beispiele und nicht upgedatete Sketche berücksichtigen das noch nicht).

Sonst: thumbs up!
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Markus.

#7
ja muss noch was ändern ...
Und zwar wird bei jeder zweiten Übertragung für beide Temperatursensoren 85 übertragen.... :-(
Bei der drauf folgenden Übertragung stimmen die Werte wieder...

Werde die Fehler mal beseitigen und dann nochmal testen
hab mich zu früh gefreut ...

Beta-User

Das liegt vermutlich daran, dass die Dallasse evtl. noch am arbeiten sind, wenn Du sie schon abfragst, conversionTime wäre das Stichwort.

Beispiele dazu auf meinem github, da -je nach Dallas-Temp-lib- eventuell der Zeitaufruf nicht funktioniert.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Markus.

oje wenn das mal nicht zu hoch wird für mich....
Also mit dem ersten Sketch ohne die Abfrage der Batteriespannung hatte ich das Problem nicht. Alles wurde richtig übertragen..
Kann es denn sein, das das nur durch die Abarbeitung der Spannungswerte kommt?

Hier mal das Sketch was auf dem Sensor vorher gelaufen ist.


// Enable debug prints to serial monitor
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_NRF24

// Example sketch showing how to send in OneWire temperature readings
#include <MySensors.h>
#include <SPI.h>
#include <DallasTemperature.h>
#include <OneWire.h>

#define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
#define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected
#define MAX_ATTACHED_DS18B20 16
unsigned long SLEEP_TIME = 300000; // Sleep time between reads (in milliseconds)
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

float lastTemperature[MAX_ATTACHED_DS18B20];
int numSensors=0;
boolean receivedConfig = false;
boolean metric = true;
// Initialize temperature message
MyMessage msg(0,V_TEMP);

int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
int oldBatteryPcnt = 0;

void setup()
{
// Startup OneWire
sensors.begin();

// Send the sketch version information to the gateway and Controller
sendSketchInfo("Temperature Sensor", "1.0");

// Fetch the number of attached temperature sensors
numSensors = sensors.getDeviceCount();

// Present all sensors to controller
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
present(i, S_TEMP);
}

// use the 1.1 V internal reference
analogReference(INTERNAL);
}

void loop()
{

// Fetch temperatures from Dallas sensors
sensors.requestTemperatures();

// Read temperatures and send them to controller
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
// Fetch and round temperature to one decimal
float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;

// Only send data if temperature has changed and no error
if (lastTemperature[i] != temperature && temperature != -127.00) {

  // Send in the new temperature
  send(msg.setSensor(i).set(temperature,1));
  lastTemperature[i]=temperature;
}
}

// get the battery Voltage
int sensorValue = analogRead(BATTERY_SENSE_PIN);
Serial.println(sensorValue);
// 1M, 470K divider across battery and using internal ADC ref of 1.1V
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point
// ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
// 3.44/1023 = Volts per bit = 0.003363075
float batteryV = sensorValue * 0.004106;
int batteryPcnt = sensorValue / 10;

Serial.print("Battery Voltage: ");
Serial.print(batteryV);
Serial.println(" V");
Serial.print("Battery percent: ");
Serial.print(batteryPcnt);
Serial.println(" %");
if (oldBatteryPcnt != batteryPcnt) {
// Power up radio after sleep
sendBatteryLevel(batteryPcnt);
oldBatteryPcnt = batteryPcnt;

}


sleep(SLEEP_TIME);
}



Was ich eigentlich geändert habe ist, die maximale Anzahl der Dallas Sensoren für die Schleife auf 3 gesetzt und dem Bat Sensor dann halt fix die ChildID 5 gegeben. Aber das dürfte dieses Phänomen doch nicht auslösen..

Gruß

Markus



Beta-User

hmmm....

OK, Du liest die Dallasse ja "blocking", das habe ich in der Anmerkung vorher nicht im Blick, eine diesbezügliche Änderung des Sketches ist daher eigentlich nicht nötig.

Soweit ich das im Kopf habe, ist 85° gleichbedeutend mit einer "0" aus dem Scratchpad, will heißen, es kommt schlicht nichts zurück. Prüf doch mal die Verkabelung, vielleicht ist ein Wackler drin, insbesondere beim Widerstand.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Markus.

ich glaube mit dem Wackler hast du recht. Ich hab jetzt mal den akten Sketch geladen und nun habe ich das gleiche Problem.

Gruß

Markus

Markus.

Also ich wollte mal kurz einen Status melden für die Leute die eventuell das selbe Problem haben...
Ich habe die "Verdrahtung" mal ein wenig überarbeitet, aber nach einer Betriebsdauer von ca. 5 Stunden hatte ich wieder das Problem mit dem 85er Wert. Laut diveresen Foren wird dieser Wert eigentlich nur bei einem Sensor-Reset oder nach einschalten der Spannung übertragen. Da nun das Problem nur Zeitweise auftritt und ich einen neuen Sensor erst bauen kann wenn ich alle Teile habe, bin ich mal hingegenagen und habe die Übertragungsbedingung ein wenig geändert. Und zwar wird nebem dem -127 Wert auch 85 als Fehler erkannt und die Übertragung nicht durchgeführt


#if COMPARE_TEMP == 1
    if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
    #else
    if (temperature != -127.00 && temperature != 85.00) {
    #endif


Bisher funktioniert es so ganz gut. Ist zwar keine echte Lösung aber was solls.. ;-)

Gruß

Markus

Beta-User

Thx for update.

Das mit dem "&& !=85" habe ich auch seit langem in meinen Sketchen drin.
2 Bitten noch:
- Dein Titel ist nicht sooo aussagefähig, vielleicht wäre MySensors DS18B20 Sketch Problem etwas spezifischer?
- Wenn gelöst, auch ein [gelöst] davor

Beides geht, wenn man den Ausgangsbeitrag editiert...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Markus.