Pages: [1] 2   Go Down
Author Topic: Multiple DS18B20, read problems  (Read 3423 times)
0 Members and 1 Guest are viewing this topic.
Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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");
}
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 65
Posts: 3638
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Dee Why NSW
Offline Offline
Edison Member
*
Karma: 47
Posts: 2173
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
//  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);
}


Logged

Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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);
  
 
}
« Last Edit: April 28, 2013, 10:58:27 am by Pinky » Logged

Dee Why NSW
Offline Offline
Edison Member
*
Karma: 47
Posts: 2173
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Edison Member
*
Karma: 43
Posts: 1551
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pete
Logged

Where are the Nick Gammons of yesteryear?

Dee Why NSW
Offline Offline
Edison Member
*
Karma: 47
Posts: 2173
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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....
Logged

Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just to make sure that the library detected that parasite mode was being used add this after the delay(6000) in setup.
Code:
  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.
Logged

Offline Offline
Edison Member
*
Karma: 43
Posts: 1551
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Where are the Nick Gammons of yesteryear?

New Jersey
Offline Offline
Faraday Member
**
Karma: 65
Posts: 3638
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, I went the non-parasitic way. Again.
Now things are working intermittently. Below is an output example:

Code:
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  smiley
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.
« Last Edit: April 28, 2013, 01:21:40 pm by Pinky » Logged

Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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*
« Last Edit: April 28, 2013, 02:09:51 pm by Pinky » Logged

0
Offline Offline
Shannon Member
****
Karma: 200
Posts: 11671
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

[ I won't respond to messages, use the forum please ]

Pages: [1] 2   Go Up
Jump to: