Z-Uno - negative temperature value from DS18B20

Discussion about Z-Uno product. Visit http://z-uno.z-wave.me for more details.
rumen33
Posts: 4
Joined: 11 Sep 2016 22:45

Z-Uno - negative temperature value from DS18B20

Post by rumen33 »

After switching Z-Uno power supply Off for about 10 sec and the switching it back ON, the temperature readings from 1-WIRE temperature sensor DS18B20 are going to -327 Deg. The problem exists even with the example sketch for 1-WIRE temperature sensor, posted on Z-Uno web site.

I found this value is defined as a BAD_TEMP in ZUNO_DS18B20.h.

#define BAD_TEMP -32767

so if I understood the concept, this value appears in case the 1-Wire communication with the sensor is down.

After resetting Z-Uno by the Reset button, the temperature readings are going back to normal.

As I understood, there is no option to perform Z-Uno Reset by the sketch. How can I reset the 1-WIRE communication ? Does anybody else try this example ?


* I am using Arduino IDE 1.6.5 and Z-Uno package version 2.0.6. The temperature sensor is connected to pin 12. I have tested with two different controllers - Z-Wave Me UZB stick and Fibaro HC Lite. The sketch is exactly the same as in the example just PIN_DS18B20 is changed from 11 to 12.
p0lyg0n1
Posts: 242
Joined: 04 Aug 2016 07:14

Re: Z-Uno - negative temperature value from DS18B20

Post by p0lyg0n1 »

Hi, rumen33. Thank you for this test. We didn't test ds18b20 with sleeping devices yet. You found really important thing ! I checked this sample with my logic analyzer and found the reason why it works so strange. The problem in reset interval of OneWire. It's too short at this moment and ds18b20 can't recognize the start of transmission when device wakes up. The fix of this problem is pretty simple. We will fix it in the next release, but you can do it yourself using these instruction:
1. Go to the folder where Z-Uno cores is placed on your PC. The simpliest way to find it is to open "preferences" of Arduino IDE and click on "preferences.txt" in the right bottom edge of dialog box. It will open files-explorer. Then go to packages/Z-Uno/hardware/zw8051/2.0.6/libraries/ZUNO_OneWire/
2. Open OneWire.cpp via any TextEditor (Sublime/Notepad/Notepad++/Kate/GEdit.. any). Go to line #155. You have to see "delayMicroseconds(480);" just replace it with "delayMicroseconds(1500);"
3. Save the file.
4. Rebuild and upload your sketch to Z-Uno.

I tested this with that sketch:
It uses Serial1 for debug. It's a good practice to use Serial1 + External UART to USB board instead of Serial, because you will see all output and there is no need to connect/disconnect terminal from main port of your Z-Uno.

// demo sketch for connecting OneWire temperature sensor DS18B20 to Z-Uno

// add library ds18b20
#include "ZUNO_DS18B20.h"

// pin connection ds18b20
#define PIN_DS18B20 11

OneWire ow(PIN_DS18B20);

// onewire connection temperature sensors
DS18B20Sensor ds1820(&ow);

#define MY_SERIAL Serial1

byte addr1[8];//={0x28, 0x11, 0x5F, 0x9B, 0x06 ,0x0, 0x0, 0x2C};
int temp; // here we will store the temperature

byte g_num_loops = 2;

ZUNO_SETUP_SLEEPING_MODE(ZUNO_SLEEPING_MODE_SLEEPING);
ZUNO_SETUP_DEBUG_MODE(DEBUG_ON);

// set up channel
ZUNO_SETUP_CHANNELS(
ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE,
SENSOR_MULTILEVEL_SCALE_CELSIUS,
SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
getterTemp)
);

void setup() {
MY_SERIAL.begin(115200);
MY_SERIAL.println("start");



}

void loop() {
ds1820.scanAloneSensor(addr1); // You can comment this if you know address of your sensor.... See ^
// obtaining readings from the sensor ds18b20
float temerature = ds1820.getTemperature(addr1);
// make scaled word value for report
temp=int(temerature*100);
MY_SERIAL.print("Your sensor address is: ");
for(int i = 0; i < 8; i++) {
// print OneWire code
MY_SERIAL.print(addr1, HEX);
MY_SERIAL.print(" ");
}
MY_SERIAL.println();

MY_SERIAL.print("Temperature: ");
MY_SERIAL.println(temerature);


// send data to channel
zunoSendReport(1);


MY_SERIAL.println("GO SLEEP");
zunoSendDeviceToSleep();

}

word getterTemp() {
return temp;
}
rumen33
Posts: 4
Joined: 11 Sep 2016 22:45

Re: Z-Uno - negative temperature value from DS18B20

Post by rumen33 »

Hi p0lyg0n1. Thank you for your detailed explanation. However this is not case as in the original example, used by me, the device is not defined as a battery supplied. The problem exists even in case of:

ZUNO_SETUP_SLEEPING_MODE(ZUNO_SLEEPING_MODE_ALWAYS_AWAKE);

Does anybody else tried this example. Please just switch the Z-Uno power supply Off for couple of seconds and then switch it On again. The temperature readings in UI always are gong to -327 and remain there a until Z-Uno Reset is performed.
A.Harrenberg
Posts: 201
Joined: 05 Sep 2016 22:27

Re: Z-Uno - negative temperature value from DS18B20

Post by A.Harrenberg »

Hi,

i haven't tried the original example but have now included a DS18B20 sensor in my mulit-sensor test sketch. My code is based on the example, I redefined the pin to 16, changed some names, but basically the code is the same.
One thing I changed is that after I had it up-and-running, I made the address of the DS18B20 static and removed the "ds1820.scanAloneSensor(addr1);" statement. I just realized now that p0lyg0n1 has proposed this in the revised example.

I have made the change for the delay time in Onewire as mentioned by p0lyg0n1.

I also added some delays in my sketch, in the setup() I added a 2 second delay (dealy(2000)) before initializing the DTH sensor and tbe BMP180 sensor. I also initialize my waiting functions to have the first readings after 5 seconds.

Maybe these delays do the trick...

With my current sketch I can't confirm your behavior. As I have already 9 channels created and integrated the sensors in my system, I can not test this sketch specifically without loosing my setup...

During my initial testing, sometimes the first reading was -327.67 but after that it is ok. One thing I noted was that in my first (HW)setup I forgot the pull-up resistor, leading to an Address of "all zeros" and the value was then also -327.67 as this is the default fault value. But without the pull-up sensor there was no measurement possible at all...

If you like you can have a look at my current sketch (I increased the waiting timt to 15 seconds, but my current sketch is still programmed with 5 seconds, I didn't updated it yet)

Code: Select all

/*
 * This is based on the Simple Multilevel Dimmer example,
 * the dht22_test example, the Simple MultiSensor example
 * and the 1-wire DS18B20 example...
 * It gives you the ability to control the
 * built in LED brightness via Z-Wave commands
 * It should report values from the DHT11 sensor on the multisensor channnel
 */

#include "ZUNO_DHT.h"
#include "Wire.h"
#include "ZUNO_BMP180.h"
#include "ZUNO_DS18B20.h"

// HW declaration

// use pin 11 for DHT sensor
DHT           dht11_sensor(11, DHT11);
ZUNO_BMP180   bmp;


#define LUMINANCE_PIN    6
#define SWITCH_LED_PIN   9
#define MOTION_LED_PIN  10
#define MOTION_PIN      12
#define LED_PIN         13
#define SCL_PIN         14
#define SDA_PIN         15
#define PIN_DS18B20     16

OneWire       ow(PIN_DS18B20);
DS18B20Sensor ds1820(&ow);
I2CDriver alternative_I2C(SCL_PIN, SDA_PIN); 


byte  lastSetDimmer       = 0;      // variable to store current dimmer value
float temperature         = -99.0;  // variable to store the temperature
float humidity            = -99.0;  // variable to store the humidity
byte  currentLEDValue     = 0;      // variables to store the current switch state
byte  lastLuminanceValue  = 0;      // variable to store the last luminance
byte  lastMotionValue     = 0;      // motion
float lastTempBMP180      = -99.0;  // variable to store the temperature from the BMP180
long  lastPressureBMP180  = 0;      // variable to store the pressure from the BMP180
int   lastTempDS18B20     = 0;      // variable to store the temperature from the DS18B20

byte addrDS18B20[8] = {0x28, 0x8c, 0xde, 0x26, 0x00, 0x00, 0x80, 0x80}; // static address of "my" DS18B20
  
// timer values
#define T_REPORT 30000
unsigned long WaitMillis_tReport;
#define T_READANALOG  500
unsigned long WaitMillis_tReadAnalog;

// set up the Z-Uno channels
// definition converted to "one" line to get warnings/error reported with correct line numbers
// CH1 - Dimmer:      ZUNO_SWITCH_MULTILEVEL(getterDim, setterDim)
// CH2 - Temperature: ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE,SENSOR_MULTILEVEL_SCALE_CELSIUS, SENSOR_MULTILEVEL_SIZE_TWO_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterTemp)
// CH3 - Humidity:    ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_RELATIVE_HUMIDITY, SENSOR_MULTILEVEL_SCALE_PERCENTAGE_VALUE, SENSOR_MULTILEVEL_SIZE_TWO_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterHum)
// CH4 - Luminance:   ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_LUMINANCE, SENSOR_MULTILEVEL_SCALE_PERCENTAGE_VALUE, SENSOR_MULTILEVEL_SIZE_ONE_BYTE, SENSOR_MULTILEVEL_PRECISION_ZERO_DECIMALS, getterLum)
// CH5 - Motion:      ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_MOTION, getterMotion)
// CH6 - Switch:      ZUNO_SWITCH_BINARY(getterSwitch, setterSwitch)
// CH7 - TempBMP180:  ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE,SENSOR_MULTILEVEL_SCALE_CELSIUS, SENSOR_MULTILEVEL_SIZE_TWO_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterTempBMP180)
// CH8 - Pressure:    ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_ATMOSPHERIC_PRESSURE,SENSOR_MULTILEVEL_SCALE_KILOPASCAL, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ZERO_DECIMALS, getterPressure)
// CH9 - TempDS18B20: ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE,SENSOR_MULTILEVEL_SCALE_CELSIUS, SENSOR_MULTILEVEL_SIZE_TWO_BYTES, SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS, getterTempDS18B20)
ZUNO_SETUP_CHANNELS(ZUNO_SWITCH_MULTILEVEL(getterDim, setterDim), ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE, SENSOR_MULTILEVEL_SCALE_CELSIUS, SENSOR_MULTILEVEL_SIZE_TWO_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterTemp), ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_RELATIVE_HUMIDITY, SENSOR_MULTILEVEL_SCALE_PERCENTAGE_VALUE, SENSOR_MULTILEVEL_SIZE_TWO_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterHum), ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_LUMINANCE, SENSOR_MULTILEVEL_SCALE_PERCENTAGE_VALUE, SENSOR_MULTILEVEL_SIZE_ONE_BYTE, SENSOR_MULTILEVEL_PRECISION_ZERO_DECIMALS, getterLum), ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_MOTION, getterMotion), ZUNO_SWITCH_BINARY(getterSwitch, setterSwitch), ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE,SENSOR_MULTILEVEL_SCALE_CELSIUS, SENSOR_MULTILEVEL_SIZE_TWO_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterTempBMP180),ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_ATMOSPHERIC_PRESSURE,SENSOR_MULTILEVEL_SCALE_KILOPASCAL, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ZERO_DECIMALS, getterPressure), ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE,SENSOR_MULTILEVEL_SCALE_CELSIUS, SENSOR_MULTILEVEL_SIZE_TWO_BYTES, SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS, getterTempDS18B20));
ZUNO_SETUP_DEBUG_MODE(DEBUG_ON);

void setup() {


//  Serial.begin();
//  Serial.println("start");
  
  pinMode(LUMINANCE_PIN,  INPUT);
  pinMode(LED_PIN,        OUTPUT);
  pinMode(SWITCH_LED_PIN, OUTPUT);
  pinMode(MOTION_LED_PIN, OUTPUT);
  pinMode(MOTION_PIN,     INPUT);

  Wire.bindDriver(&alternative_I2C); // This instructs to use other pins than default
  
  // initial setup for timer values
  WaitMillis_tReport      = millis() + 15000;
  WaitMillis_tReadAnalog  = millis() + 15000;
  
  delay(2000); // wait that sensors are ready ??
  dht11_sensor.begin();
  bmp.begin(); // calls internally Wire.begin()
//  ds1820.scanAloneSensor(addrDS18B20);  // static address defined 
}

void loop() {
  if ( (long)( millis() - WaitMillis_tReadAnalog ) >= 0) {
    // don't check in every loop...
    checkMotion();  // check motion sensor
    WaitMillis_tReadAnalog += T_READANALOG;  // set next timer value
  }

  // update values and send out reports
  if ( (long)( millis() - WaitMillis_tReport ) >= 0) {
    // Loop for reports with timer every T_REPORTS
    read_DHT();
    readLuminance();
    readBMP180();
    readDS18B20();
    
//  zunoSendReport(1); // report the state of the dimmer in channel 1
    zunoSendReport(2); // report the temperature from the DHT11 in channel 2
    zunoSendReport(3); // report the relative humidity from the DHT11 in channel 3
    zunoSendReport(4); // report the luminance in channel 4
//  zunoSendReport(5); // report the motion in channel 5
//  zunoSendReport(6); // report the state of the switch in channel 6
    zunoSendReport(7); // report the temperature from the BMP180 in channel 7
    zunoSendReport(8); // report the pressure from the BMP180 in channel 8
    zunoSendReport(9); // report the temperature from the DS8B20 in channel 9

    WaitMillis_tReport += T_REPORT;  // set next timer value
  }
  delay(200);  // wait at least 200 ms
}

void readDS18B20() {
//  ds1820.scanAloneSensor(addrDS18B20);
  float temp = ds1820.getTemperature(addrDS18B20);
  lastTempDS18B20 = int(100.0 * temp);

//  Serial.print("Your sensor address is: ");
//  for(int i = 0; i < 8; i++) {
//          // print OneWire code
//          Serial.print(addrDS18B20[i], HEX);
//          Serial.print(" ");
//  }
//  Serial.println();
//    
//  Serial.print("Temperature: ");
//  Serial.println(temp);
}

void readBMP180() {
  lastTempBMP180      = bmp.readTemperature();
  lastPressureBMP180  = bmp.readPressure();

//  bmp.dumpInternal();
//  Serial.println(bmp.readRawTemperature());
//  
//  Serial.print("BMP 180: Temperatur: ");
//  Serial.print(lastTempBMP180);
//  Serial.print(" C, Druck: ");
//  Serial.print(lastPressureBMP180);
//  Serial.println(" kpa");
}

void read_DHT() {
  byte result;

  result = dht11_sensor.read(true);
  if (result == 0) {
    // only update temperature if reading is ok
    temperature = dht11_sensor.readTemperature();
    humidity    = dht11_sensor.readHumidity();
  }
}

void readLuminance() {
  lastLuminanceValue = (byte) ((0x3FF - analogRead(A3)) / 10.23); // scale 0..1023 to 0..100 (%), sensor is inverted 0=light, 1023=dark
}

void checkMotion() {
  byte currentSensorValue = digitalRead(MOTION_PIN);

  if (currentSensorValue != lastMotionValue) {
    lastMotionValue = currentSensorValue;
    zunoSendReport(5);                    // send report directly, motion is not reported in reporting loop
    if (currentSensorValue == HIGH) {
      digitalWrite(MOTION_LED_PIN, HIGH);
    } else {
      digitalWrite(MOTION_LED_PIN, LOW);
    }
  }
}

// getter / setter function calls

// CH1 - Dimmer
byte getterDim(void) {
  return lastSetDimmer;
}

void setterDim(byte value) {
  byte tempVariable;
  if (value > 99) {
    // by Z-Wave specification, this value can't be more then 99
    value = 99;
  }

  // set the LED brightness scaled to 0..99
  analogWrite(PWM1, ((long)value) * 255 / 99);

  lastSetDimmer = value;
//    // report the state in channel 1
//    zunoSendReport(1);
}

// CH2 - Temperature
word getterTemp() {
//  read_DHT(); // Update value before sending, normal update only during report loop
  word t;
  t = (word)(10.0 * temperature);
  return t;
}

// CH3 - Humidity
word getterHum() {
  word h;
  h = (word)(10.0 * humidity);
  return h;
}

// CH4 - Luminance
byte getterLum(void) {
  return lastLuminanceValue;
}

// CH5 - Motion
byte getterMotion() {
  if (lastMotionValue == 1) {    // if motion is detected
    return 0xff;                 // return "Triggered" state to the controller
  } else {                       // if motion stopped
    return 0;                    // return "Idle" state to the controller
  }
}

// CH6 - Switch
byte getterSwitch () {
  return currentLEDValue;
}

void setterSwitch (byte value) {
  if (value > 0) {                
    digitalWrite (SWITCH_LED_PIN, HIGH); //turn LED on
  } else {                        
    digitalWrite(SWITCH_LED_PIN, LOW);   //turn LED off
  }
  currentLEDValue = value;
}

// CH7 - TempBMP180
word getterTempBMP180() {
  word t;
  t = (word)(10.0 * lastTempBMP180);
  return t;
}

// CH8 - Pressure
//getterPressure
long getterPressure() {
  return lastPressureBMP180;
}

// CH9 - TempDS18B20
word getterTempDS18B20() {
  word t;
  t = (word)(lastTempDS18B20);
  return t;
}
// getterTempDS18B20
There is still something to clean up and some room for optimization, but for now it is working quite good.

Regards,
Andreas.
fhem.de - ZWave development support
michap
Posts: 437
Joined: 26 Mar 2013 10:35
Contact:

Re: Z-Uno - negative temperature value from DS18B20

Post by michap »

Hi,

I can confirm that the modification ofthe value solve this problem.
p0lyg0n1 wrote:...Then go to packages/Z-Uno/hardware/zw8051/2.0.6/libraries/ZUNO_OneWire/
2. Open OneWire.cpp via any TextEditor (Sublime/Notepad/Notepad++/Kate/GEdit.. any). Go to line #155. You have to see "delayMicroseconds(480);" just replace it with "delayMicroseconds(1500);"...
The first reported value in "no sleeping mode" (ALWAYS_AWAKE) will be now the right value.

In sleeping mode this is working too, additional the problem that Z-Uno didn't came back from sleeping (using the 18B20) was resolved - wake-up is working now as expected.

Michael
rumen33
Posts: 4
Joined: 11 Sep 2016 22:45

Re: Z-Uno - negative temperature value from DS18B20

Post by rumen33 »

Hi P0lyg0n1,
This is just to confirm the problem is solved. Thank you! I didn't realize it immediately as there was another error to fix in the sketch. Now, after editing the library file according to your advice, temperature readings are restoring in 15-20 seconds, without Z-Uno reset. Thanks to everybody who participated here.
SergeyPetrov
Posts: 3
Joined: 26 Oct 2016 01:38

Re: Z-Uno - negative temperature value from DS18B20

Post by SergeyPetrov »

Hi, p0lyg0n1
After you change the line # 155, z-uno sleep. And I can not download the new sketch. There is a way hard reset?
p0lyg0n1
Posts: 242
Joined: 04 Aug 2016 07:14

Re: Z-Uno - negative temperature value from DS18B20

Post by p0lyg0n1 »

Sergey, please look here: http://z-uno.z-wave.me/getting-started/troubleshooting
You have to boot z-uno in recovery mode if you have "sleeping" sketch uploaded.
Just hold "rst" and "btn" and then release "rst" and then release "btn".
SergeyPetrov
Posts: 3
Joined: 26 Oct 2016 01:38

Re: Z-Uno - negative temperature value from DS18B20

Post by SergeyPetrov »

thank you very much
Ralf.E
Posts: 5
Joined: 10 Jan 2017 20:35
Location: Germany (near Hamburg)

Re: Z-Uno - negative temperature value from DS18B20

Post by Ralf.E »

Hi,

for any reason I run into this problem with two DS18B20 both returning BAD_TEMP. I've applied the patches to ZUNO_OneWire and ZUNO_DS18B20 already and I'm using version 2.0.7.

I don't have a real answer on that behavior, but the order of global variables/objects in my sketch makes the DS18B20 working or not working.

Weird, feels like a timing problem...
Post Reply