Go Down

Topic: Multiple DS18B20, read problems (Read 4574 times) previous topic - next topic

Pinky

Hello,

I've got two DS18B20 with "waterproof" housing and communicate using the OneWire library and an old Arduino NG. I brew beer from time to time and I'm checking if these sensors will work for monitoring the process. This means they will be in very warm water, sometimes boiling hot.
I got everything working with the code below at room temperature. I then proceeded to put one of them in some water while i heated it until it was boiling. At about 65-70C I stopped getting values from the sensor that was not in the water. Sometimes it reported back but with a weird device adress. A few more C and they both stopped working. I then disconnected the sensor that was not in the water and the other sensor started working again. When the boiled sensor cooled down they both worked again.

My theory is that when larger values are returned from the sensor it will somehow interfere with the onewire communication alltogether. Any ideas?


I got the code from a guide on the interwebs. I modified it somewhat so that it would only print device adress and temperature for my project.
Code: [Select]
#include <OneWire.h>

// DS18S20 Temperature chip i/o
OneWire ds(10);  // on pin 10

void setup(void) {
 // initialize inputs/outputs
 // start serial port
 Serial.begin(9600);
}

void loop(void) {
 int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
 byte i;
 byte present = 0;
 byte data[12];
 byte addr[8];

 if ( !ds.search(addr)) {
//      Serial.print("No more addresses.\n");
     ds.reset_search();
     return;
 }

 Serial.print("R=");
 for( i = 0; i < 8; i++) {
   Serial.print(addr[i], HEX);
   Serial.print(" ");
 }
 Serial.print("\n");

 if ( OneWire::crc8( addr, 7) != addr[7]) {
//      Serial.print("CRC is not valid!\n");
     return;
 }

 if ( addr[0] == 0x10) {
     Serial.print("Device is a DS18S20 family device.\n");
 }
 else if ( addr[0] == 0x28) {
//      Serial.print("Device is a DS18B20 family device.\n");
 }
 else {
     Serial.print("Device family is not recognized: 0x");
     Serial.println(addr[0],HEX);
     return;
 }

 ds.reset();
 ds.select(addr);
 ds.write(0x44,1);         // start conversion, with parasite power on at the end

 delay(1000);     // maybe 750ms is enough, maybe not
 // we might do a ds.depower() here, but the reset will take care of it.

 present = ds.reset();
 ds.select(addr);    
 ds.write(0xBE);         // Read Scratchpad

//  Serial.print("P=");
//  Serial.print(present,HEX);
//  Serial.print(" ");
 for ( i = 0; i < 9; i++) {           // we need 9 bytes
   data[i] = ds.read();
//    Serial.print(data[i], HEX);
//    Serial.print(" ");
 }
//  Serial.print(" CRC=");
//  Serial.print( OneWire::crc8( data, 8), HEX);
//  Serial.println();
 LowByte = data[0];
 HighByte = data[1];
 TReading = (HighByte << 8) + LowByte;
 SignBit = TReading & 0x8000;  // test most sig bit
 if (SignBit) // negative
 {
   TReading = (TReading ^ 0xffff) + 1; // 2's comp
 }
 Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

 Whole = Tc_100 / 100;  // separate off the whole and fractional portions
 Fract = Tc_100 % 100;

Serial.print("D=");
 if (SignBit) // If its negative
 {
    Serial.print("-");
 }
 Serial.print(Whole);
 Serial.print(".");
 if (Fract < 10)
 {
    Serial.print("0");
 }
 Serial.print(Fract);

 Serial.print("\n");
}

wildbill

You might find it easier to use the DallasTemperature library instead. It's doing much the same as yours behind the scenes, but you don't need to worry about having fat fingered something when you adapted that code.

Nick_Pyner


My theory is that when larger values are returned from the sensor it will somehow interfere with the onewire communication altogether. Any ideas?


The DS18B20 is good for 125C. If your theory was correct, everybody would know about it by now and the device would have been superceded, or Dallas would be out of business. I wouldn't like to say the sensor is dud. They can take a lot of abuse.

The code looks junk. Here is something that works. Check the Hacktronics tutorial.

Code: [Select]
//  This Arduino sketch reads DS18B20 "1-Wire" digital
//  temperature sensors.
//  Copyright (c) 2010 Mark McComb, hacktronics LLC
//  License: http://www.opensource.org/licenses/mit-license.php (Go crazy)
//  Tutorial:
//  http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html
//  code uses Arduino LCD stuff, for shield on Freetronics EtherTen.
//  Serial print commands are for PLX-DAQ


#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(8,9,56,5,6,7); // patchwire is D4 to A0 (pin14) on this proto
int flag;
// Data wire is on pin 3
#define ONE_WIRE_BUS 3
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Assign the addresses of your 1-Wire temp sensors.
DeviceAddress InThermo = {  
 0x28, 0x69, 0xC2, 0xB0, 0x03, 0x00, 0x00, 0X9F };
DeviceAddress OutThermo = {
 0x28, 0x7A, 0x8B, 0xC0, 0x03, 0x00, 0x00, 0x2F };

//temperature variables
float InTemp, OutTemp, diff, drain, flow, power, tempC;

void setup(void)
{
 // start serial port
 Serial.begin(9600);

 // set up the LCD,s number of columns and rows:
 lcd.begin(16, 2);
 Serial.println("LABEL,Time,TempIn,TempOut,diff");
 // Print a message to the LCD.
 lcd.print("temp in     out");    

 // Start up the library
 sensors.begin();
 sensors.setResolution(InThermo, 12);
 sensors.setResolution(OutThermo, 12);
}

void loop(void)
{
 delay(1000);
   Serial.print("DATA,TIME,       ");
 flag = 0;
 //Get the sensor readings. There are two of them
 sensors.requestTemperatures();

 GetandPrint(InThermo);
 InTemp=tempC;
 flag = 1;

 GetandPrint(OutThermo);
 diff = tempC - InTemp;
 Serial.print (diff);
 Serial.println(" ,  ");

}

void GetandPrint(DeviceAddress deviceAddress)
{
 tempC = sensors.getTempC(deviceAddress);
 if (tempC == -127.00) {
   Serial.print("Error getting temperature");
 }
 else {
   Serial.print(tempC);
   Serial.print(" ,  ");
 }
 lcd.setCursor (1,1);
 if (flag==1)
   (
   lcd.setCursor (11,1)
     );
 lcd.print (tempC);
}




Pinky

I've tried using the DallasTemperature library earlier. I chose not to use it because it needs a lot of my precious memory. I'm on a NG with the ATMEGA8 so I dont have a lot to spare. The modifications of that code was simply commenting out a few println's to keep only the output i wanted. The original is here, on the playground: http://playground.arduino.cc/Learning/OneWire.

I'll do the experiment again using the DallasTemperature lib anyway. I'll report right back when it's done.

Pinky

#4
Apr 28, 2013, 05:56 pm Last Edit: Apr 28, 2013, 05:58 pm by Pinky Reason: 1
Not much luck for me today. I used the very simple code below and it wont even detect my sensors if they are both connected. No problem one at a time though.
I've wired my sensors exactly like this:

Code: [Select]
#include <OneWire.h>

#include <DallasTemperature.h>



// Data wire is plugged into pin 10 on the Arduino
#define ONE_WIRE_BUS 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);
DeviceAddress tmp_address;
int numberOfDevices;
void setup(void)
{
 // start serial port
 Serial.begin(9600);
 Serial.println("Looking for sensors...");
 // Start up the library
 sensors.begin();
 delay(6000);

numberOfDevices = sensors.getDeviceCount();
Serial.print("Found ");
Serial.print(numberOfDevices);
Serial.println(" sensors. Starting now...");
}


void loop(void)
{
 // call sensors.requestTemperatures() to issue a global temperature
 // request to all devices on the bus
 sensors.requestTemperatures(); // Send the command to get temperatures
for(int i=0;i<numberOfDevices; i++)
 {
   Serial.print(i);
   Serial.print(":");
   Serial.println(sensors.getTempCByIndex(i));
   delay(100);
   
 }
 Serial.println();
 delay(1000);
 

}

Nick_Pyner

While that diagram may be kosher, I fail to see the point in doing it that way.

Just try connecting

1. both 5v to 5v
2. both gnd to gnd
3. both signal to signal
4. add the 4.7 pullup

thereby removing all doubts.

Pinky

The point is using what's called parasitic mode. Read more about that here: http://playground.arduino.cc/Learning/OneWire

That being said i did try it the way you described and got the exact same result.

el_supremo

Just to make sure that the library detected that parasite mode was being used add this after the delay(6000) in setup.
Code: [Select]
  if(sensors.isParasitePowerMode())Serial.println("parasite powered");
  else Serial.println("NOT parasite powered");


Pete

Nick_Pyner

No, the point is, there is no point. And the first par under

Powering OneWire devices

makes (faintly) interesting reading, where the words "often" and "probably" come up more than they should.

As I said, the devices seem very robust, so I guess that leaves your code....

Pinky


Just to make sure that the library detected that parasite mode was being used add this after the delay(6000) in setup.
Code: [Select]
  if(sensors.isParasitePowerMode())Serial.println("parasite powered");
  else Serial.println("NOT parasite powered");


Pete


Now that's interesting. I put everything back to parasitic mode, but the printout says NOT parasite powered... I triple checked the connections.


No, the point is, there is no point.

There is a point, but that is not the point of this conversation. Almost all examples using the DS18B20 sensor is using that setup, thats why I chose it.

el_supremo

Quote
the words "often" and "probably" come up more than they should

But that isn't the datasheet.

Quote
the printout says NOT parasite powered

The begin function in the Dallas library searches the bus for devices. For each device that answers it checks to see if the device is parasite powered. If so, it sets a "parasite" flag and then assumes everything is parasite powered after that. It doesn't think your bus is parasite powered.
The problem, I think, is that the resistor you are using is too high a value for parasite mode. Try a 1k5 - that's what I'm using on a bus that has four DS18B20.

Pete

wildbill

I've never been able to get them to work in parasite mode. Obviously it's achievable, but you might as well eliminate one source of possible problems while you're debugging.

Pinky

#12
Apr 28, 2013, 08:13 pm Last Edit: Apr 28, 2013, 08:21 pm by Pinky Reason: 1
OK, I went the non-parasitic way. Again.
Now things are working intermittently. Below is an output example:

Code: [Select]
Looking for sensors...
NOT parasite powered
Found 2 sensors. Starting now...
0:22.00
1:22.56

0:-127.00
1:22.56

0:-127.00
1:22.00

0:22.00
1:-127.00

0:22.00
1:22.50

0:21.94
1:21.94

0:21.94
1:22.44

0:-127.00
1:22.44

0:21.94
1:22.37

0:21.87
1:-127.00

0:21.87
1:22.37

0:-127.00
1:-127.00


EDIT: This is weird. Left it running for a few minutes and the errors are getting further and further inbetween. Do these things need to warm up? LOL  :)
Anyway it would seem we are on to something with parasitic mode not being detected and me needing glasses. I don't know what I did between the different times I set up the non parasitic wiring but it must have been something.

Pinky

#13
Apr 28, 2013, 08:50 pm Last Edit: Apr 28, 2013, 09:09 pm by Pinky Reason: 1
It seems I am getting the -127 readings only when touching the sensor cables. I got them waterproofed with 1.8m cable and as soon as I touch the cable or sensor housing (all plastic) i get -127 readings. How can that be?

EDIT: And also i did another boil test. Somewhere around 80C i start getting -127 readings as well. *sigh*

MarkT

You are using screened cable and decoupling capacitors on each device?   You can't often get away with unscreened cable
in an electrically noisy environment.  Adding supply decoupling will reduce the chances of noise problems too.

One of the reasons parasite power isn't easy to get working is that you cannot use decoupling with it.

And no, DS18B20's don't have a warming-up period.
[ I won't respond to messages, use the forum please ]

Go Up