OneWire full reset to erase DS18B20 85° reading?

Hi All
I' have a strange behavior with a module on development for temperature measurement et comparison. the sketch is supposed to be implemented on Arduino IOT CLOUD
the Arduino Nano33IOT and it's sketch works as supposed on the cloud but when some instability happens (maybe electrical noise or interferences) one or the three sensors go down and give the 85° status (Power on reset response from DS18B20) and the OneWire bus gets stucked.
I've looked around in the forums many posts on this problem, I've read a lot on Dallas temperature/OneWire libraries and and I've given some delays to the time of conversion and also make several tests to let the sensors the time to answer but nevertheless the problem is erratically persistent.
I've tested also the OneWire reset function without success
I would like to know if there is a way to fully reset the OneWire bus to start over the process when the sensors readings are wrong. else if someone has an different approach to workarround this condition. maybe the watchdog could be called but ...problem is that a normal reset doesn't really powers off the Arduino and so the sensors register are not fully erased, the only thing that resets the registers is a full power down of sensors (unplug Arduino from it's power supply)
I'm wondering if I can force the whole process to start over while this error occurs.
I've read a workarround somewhere "...wiring the temperature sensors +Vin to any Output hi/low to unpower the sensors for a while" with some detractors advicing no to do that ...
here my simplified sketch (sorry for my really basic programing knowledge)
any idea or lead to follow would be really appreciated
Thanks in advance
Ale-x

// Version
float VER = 0.1;
#include "thingProperties.h"
// Include the libraries we need
// maxim one wire
#include <OneWire.h>
#include <DallasTemperature.h>
// Wire I2C
#include <Wire.h>
//laser level Variables
//initial distance to max
int z = 100; //230
int x;
float h;
float vol;
float TempW;
float TempC;
float TempCV;
String msg;
//temperature limits gap
float GAP = 3;
unsigned char ok_flag;
unsigned char fail_flag;
unsigned short length_val = 0;
unsigned char i2c_rx_buf[16];
unsigned char dirsend_flag = 0;
int serial_putc( char c, struct __file * ) {
  Serial.write( c );
  return c;
}
// Data wire is plugged into port 10 on the Arduino
#define ONE_WIRE_BUS 10
#define T_RES 10
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// Laser level setup
void SensorRead(unsigned char addr, unsigned char* datbuf, unsigned char cnt)
{
  unsigned short result = 0;
  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(82); // transmit to device #82 (0x52)
  // the address specified in the datasheet is 164 (0xa4)
  // but i2c adressing uses the high 7 bits so it's 82
  Wire.write(byte(addr));      // sets distance data address (addr)
  Wire.endTransmission();      // stop transmitting
  // step 2: wait for readings to happen
  delay(100);                   // datasheet suggests at least 30uS
  // step 3: request reading from sensor
  Wire.requestFrom(82, cnt);    // request cnt bytes from slave device #82 (0x52)
  // step 5: receive reading from sensor
  if (cnt <= Wire.available()) { // if two bytes were received
    *datbuf++ = Wire.read();  // receive high byte (overwrites previous reading)
    *datbuf++ = Wire.read(); // receive low byte as lower 8 bits
  }
}
int ReadDistance() {
  SensorRead(0x00, i2c_rx_buf, 2);
  length_val = i2c_rx_buf[0];
  length_val = length_val << 8;
  length_val |= i2c_rx_buf[1];
  return length_val;
}
void setup() {
  oneWire.reset();
  delay(1000);
  version = VER;
  pinMode(2, OUTPUT); //RED
  pinMode(3, OUTPUT); //GREEN
  pinMode(4, OUTPUT); //BLUE
  pinMode(5, OUTPUT); //COOL
  pinMode(6, OUTPUT); //HEAT
  warnings = ("");
  // Defined in thingProperties.h
  initProperties();
  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
  */
  setDebugMessageLevel(4);
  ArduinoCloud.printDebugInfo();
  sensors.begin();
  sensors.setResolution(T_RES);
  sensors.requestTemperatures();
  delay(1000);
}

void loop() {
  if (automatic == false) {
    cooling = false;
    digitalWrite(5, LOW);
    heating = false;
    digitalWrite(6, LOW);
  }

  ArduinoCloud.update();
  // ask the laser to measure the distance
  x = ReadDistance();

  //--------------------------
  // calculate volume //
  h = (1785 - (x - z));
  vol = (PI / 3000000 * h * h * ((3 * 898) - h));
  if (h > 1786) {
    vol = 3010 + ((PI * sq(2)) * ((h - 1786) / 100));
  }
  vatVolume = vol;

 // Send the command to get temperatures

  TempW = (sensors.getTempCByIndex(0));

  if ((TempW > -127) && (TempW < 85.0)) {
    WTemp = TempW;

    if (WTemp >= upLimit + 0.25 || WTemp <= downLimit - 0.25) //Temperature Alarm Condition
    {
      alarm = true; //ON
      digitalWrite(2, HIGH);
    }

    else  {
      alarm = false; //OFF
      digitalWrite(2, LOW);
    }

    if (alarm == false) //OFF
    {
      digitalWrite(3, HIGH);
      delay(10);
      digitalWrite(3, LOW);
    }

    if ((WTemp >= upLimit - 0.5) && (automatic == true))  // start cooling condition // 
    {
      cooling = true;
      digitalWrite(5, HIGH);
      heating = false;
      digitalWrite(6, LOW);

    }

    else {

      if (WTemp <= upLimit - 1.5) // stop cooling condition
      {
        cooling = false;
        digitalWrite(5, LOW);
      }
    }


    if ((WTemp <= downLimit + 0.25) && (automatic == true)) // start heating condition // 
    {
      heating = true;
      digitalWrite(6, HIGH);
      cooling = false;
      digitalWrite(5, LOW);
    }

    else {
      if (WTemp >= downLimit + 1.5) // stop heating condition
      {
        heating = false;
        digitalWrite(6, LOW);
      }
    }
  }

  else  {
    msg = (" W temperature sensor read error: ");
    msg = msg + TempW;
    msg = msg + (", ");
    automatic = false;
    alarm = true;
  }

  TempC = (sensors.getTempCByIndex(1));

  if ((TempC > -127) && (TempC < 85.0)) {
    CTemp = TempC;
  }

  else  {

    msg = (" C temperature sensor read error: ");
    msg = msg + TempC;
    msg = msg + (", ");
  }

  TempCV = (sensors.getTempCByIndex(2));

  if ((TempCV > -127) && (TempC < 85.0)) {
    CVTemp = TempCV;
  }
  else  {
    msg = (" CV temperature sensor read error: ");
    msg = msg + TempCV;
    msg = msg + (", ");

  }
  // delay(500);

  online = !online;
  if (msg != ("")) {
    warnings = (msg);
    msg = "";
  }
  sensors.requestTemperatures();
  delay(1000);

}

void onUpLimitChange() {
  warnings = ("New MAX temperature limit ");

  if (upLimit < downLimit + GAP) {
    downLimit = (upLimit - GAP);
    warnings = ((warnings) + "  (MIN auto adjusted)");
  }
}

void onDownLimitChange() {
  warnings = ("New MIN temperature limit ");

  if (downLimit > upLimit - GAP) {
    upLimit = (downLimit + GAP);
    warnings = ((warnings) + "  (MAX auto adjusted)");
  }
}

void onWarningsChange() {
  // Do something
}

void onAutomaticChange() {
  if (automatic == true) {
    warnings = ("automatic control is ON");
  }
  else  {
    warnings = ("automatic control is OFF");
    cooling = false;
    heating = false;
  }
}

The purpose of the ds.reset() command is to bring the 1-wire bus into idle state (Fig-1). It has nothing to do with the erasing of the contents of the DS18B20's registers (Fig-2).

dsreset
Figure-1:


Figure-2:

Thanks Golam, i've tested the reset command just in case, to see if putting the OneWire bus in idle should bring back the sensors responsive, but obviously that confirms what I've tried by many ways: I need another approach to solve this problem, have you any idea to share to help me? ..
Thanks in advance
Alex

Hi @Ale-X ,

I recently helped a friend who set up a craft brewery.
He used 16xDS18B20 to monitor the temperature of the tanks.
The problem was that the DS18B20 kept crashing randomly.
We made changes to the cables, we used shielded cables, we varied the pullup resistor, but nothing solved.
He told me that he bought all these DS18B20 from a supplier in China.
I recommended that he buy the DS18B20 again, but from a supplier he could trust.
From the day he installed the new sensors until today he has had no more problems (5 months have passed).

RV mineirin

1 Like

Probably all nonsense anyway.
The 85 is simply an indication that the DS18B20 has not had time to complete its job. Reasons? You have asked the question to soon after "power-on", or the loop is too short.

As far as code is concerned, it is all far too complicated to me but, if it works at all, it is probably kosher, and I submit the delay(1000) s in the setup, and the loop, should cover both of the above instances.

Also, the fact that you get readings at all rather suggests the sensors are kosher.

Therefore, this leaves the wiring, and your words "erratically persistent" rather suggests it is badly designed or slack-arsed. The former shouldn't really be an issue but you can have grief over longer distances, and you don't say anything about what you are really doing. The latter may simply be unreliable power because of a cheapo breadboard, and the sensors incur involuntary restarts.

Ok, thanks very much for the answers,
Your answers leads me to search the origin of the problem and the main suspect is "power control charge discharge regulator circuit" affected by the noise of the power supply line disturbed by some intermittent charges (industrial environment)
for INFO erratically persistent means:
I have three modules working on same conditions (frequently upgraded OTA to have the same sketch as I make modifications)
the first one works without any issues since 45 days,
the other two worked for a while, but after one week they went 85° practically at the same time
then after unplug, discharge and restart they worked a couple of days and again they went 85 almost at same time, so principal suspect is power source that lets OneWire bus blocked
I have one more here with the same components that works since 3 months without any troubles
the boards are all genuine Arduino Nano 33 IOT. I think all sensors are good but I will use the DallasTemperature example method to look at the serial number of all DS18B20 sensors to verify if they are fake or something just in case.

I think I should have used a combination of capacitors to make a filter at the input of the battery power control circuit,
but now it's too late for that,
all Arduinos are powered by an auto-switching power control circuit: input 5V // output 5V
that powers the Arduino, charges the battery, and switches between 5V input and battery when there is any power interruption (this could be the cheapo suspect but at leas one of them is better than the other two )
while the test period all the Arduino worked OK during several weeks.
if any one has another idea to wake up the sensors or something maybe write directly the scratchpad to force the bus to ask again for all sensors
or maybe write a function as follows: not really a code
" if I get 85° { stop sensors and do sensors begin again}

Thanks again a lot for your answers and suggestions
Alex

Hi,
How far apart and how far from the Nano33 are the DS sensors situated?
Do you have the pullup resistor in circuit?
What is your power supply for your project?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Hi Tom,
the sensors are at 3 mts distance, directly connected to arduino, Three of them in paralel with a single 4K7 pullup resistor sensors VIN is the +3.3Vout of ARDUINNO NANO 33 IOT (as it's supposed no to feed sensors with 5V that could put a "high" status higher than 3.3V)
The power supply of the circuit is a 5VCC power suply commercial transformer pour USB-A /for each Arduino/ (I'm not very sure on it's quality as they was supplied by the people in place) then a power/charge/discharge control circuit for LiPo batteries with a 3,7 V LiPo battery attached and
this circuits switches between the source and the battery as needed, and gives always 5V at the output -> VIN arduino, as I've said I have two modules working without any troubles an two others which sooner or later (some hours or days after) will give the 85° reading from the sensors
Thanks for your help and for taking the time to share your thoughts

Hi,
Thanks for the info.
If you have two other setups working okay, then it looks like it is an environmental problem.

Are the senor wires or power supply wires routed near AC mains wiring?
What is does the cooling/heating outputs control?
Do you have bypass capacitors on the supply wires the the DS units to suppress any inductive interference?

What is the application?

Tom... :smiley: :+1: :coffee: :australia:

Thanks Tom,
I agree with the environment problem... all the modules except the prototype I have by mi side are identical and really close between them, but I can't be sure if the external noise or external ac wires are affecting them in the same way, at least I have now several leads to follow! :wink:
One test I'll do in first place, is to plug the second unit (faulty) in the same wall outlet as the first (working ok) so as I'll have the same power supply source for both, if the problem disappears then is most probably the noisy power source of the second (then I'll do it with the third )
the cooling /heating outputs should be connected by optocouplers to electro valves to open or close cooling/heating water circuits
the application is supposed to measure and compare temperatures at different points in order to keep a recipient temperature between the desired limits, but the automatic control is not enabled yet (no external charges on these pins signals except a couple of resistors/leds to show activity)
Thanks for your thoughts

Hi,
Okay, see how it goes.
I used to work maintenance in the brick factory so understand the needs for a controlled temperature profile.

Tom... :smiley: :+1: :coffee: :australia:

1 Like

The distance is not unreasonable, you can get the sensors with 5m cable, but if you are using cheapo wires, it may still be a problem. A 4.7k pullup is standard for 5v Arduinos but it you might check that it is still kosher for 3.3v.

1 Like

Hi Nick
Thanks for your help, what do you mean by "kosher" I'm not sure of the sense of word as you have used it in many different cases in your posts.

anyway the 4K7 pullup resistor is advised by maxim's datasheet with a voltage between 3 and 5V, and all components were buyed together for all devices, I'll check this lead anyway just in case.
Thanks

Thanks a lot Tom

Hi,

In this case it means will work properly, original, the real deal, not a clone or copy.
It has been adopted for the Hebrew for "proper" or "pure".

So, in Aussie speak...
Check that the 4k7 will work for 3v3 application.

Tom... :smiley: :+1: :coffee: :australia:
PS. @Ale-X we will have you talking Australian in no time... :+1: :+1: :+1: :smiley: :smiley:

1 Like

"Proper for the job" will suffice....

I was not aware that the data sheet specifically mentions 4.7K pullup with 3.3v, and I still haven't seen it. On p19, the voltage is indeed mentioned, but they are really coy about the resistance and you usually just see the word "strong". Apart from the pictures, I recall "about 5 ohms" is about the best you actually get. I only raise this because users have been obliged to use about 2.2k for longer cables and I don't think the data sheets mention that either.

I can confirm that genuine DS18B20's are as rock solid as anything (if used correctly), and yes its very unlikely you'll get genuine DS18B20's from a random supplier in china (you just aren't its a high value chip that's laser-trimmed, so will be targetted heavily by the counterfeiters/scammers).

Basically buying genuine semiconductors means going to the genuine electronic stockists, since the rest of the market has been taken over by scammers as they heavily undercut prices for the honest vendors putting them out of business - and of course the small vendors also have problems sourcing genuines, and they don't have the resources to test every batch.

Hi Tom & Nick I'm really grateful for all your answers, and explanations (even with my English! ... I should have deduce that! ) I will give a whole round of tests and /or modifications if possible to be sure all the subjects we have discussed here are taken in care...
just a question @TomGeorge were would you place the Bypass capacitors and the value of these capacitors because I was thinking to place a filter at VIN/GND of Arduino to kill all the noise or variations but I've never thought about a capacitor in the sensors, maybe better choice!
Thanks again
Alex

no problem with that!! I'm having a tough time to keep my few lasting neurons aligned with the languages I should use everyday but I'll take it! Australian English is very funny!!!

Thanks for your add! even if I've get them from a Germany supplier I'm not sure of his suppliers
I'll make the serial number test to see if something is wrong.

HI,
Place 0.1uF capacitors across 5V and gnd at each DS18B20.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

1 Like