Go Down

Topic: DS18S20, max two sensor limitation (Read 345 times) previous topic - next topic

warrenboyle

Hi,
I am building a electric baseboard control system for my house.  I am using an Arduino Mega 2560 Rev3 controller and I have modified my thermostats to each have a DS18S20 sensor in them. I am using the waterproof type sensors in the metal tube with the 3' wire lead.
I mocked up the system before I installed it and had everything working fine, sensors were returning temps and all was good. At this point, the sensors were wired direct to the controller, using a DF robot breakout for DS18S20 sensors that has a 4.7kOhm pull-up baked in.  I have now installed the sensors in the rooms, and ran Cat5e back to the controller.  I use one twisted pair for each V+, V- and Data lines, leaving one pair spare.
Initially I ran just one room to test it, there is about 40'(10m) of cat5 between the sensor and controller.  On a previous project I ran over 100' of Cat5 with 3 sensors along its length and had no issues with getting sensors to work.  With the one sensor installed I was getting a temperature reading as expected. 
I then connected sensors 2 and 3, which have about 20' and 30' of cat5 between sensors and board, respectively. 
When plugged in individually, each sensor works as expected and I get a reading, However, If I connect more than one sensor they will all return -127 (Error). If I run a simple 1-wire sketch to find sensor addresses, it would not find any sensors on the bus.  The sensors are wired in a "star" configuration with the controller at the centre.
I tried a bunch of different solutions to try and fix the issue. Most recently, I replaced the DF robot breakout  and wired all the sensors directly back to the one wire terminal (2) and put a new 4.7kohm resistor from the pin2 to V+.  With this new set up I can now get temperatures from of any combination of TWO sensors, but if I connect a 3rd sensor, all three error to -127.

Other things:
-I've had the V+ connected to the 5v output and also wired direct from a 5v power supply.  Both give the same result.
-I updated to the latest onewire and Dallas temp libraries - before I updated to the latest library I would get 0.00 degrees returned from the sensors instead of -127.  Not sure on why that happened. 
-I have the addresses for each probe and am calling them directly. 
-void TempCheck() is where the code gets the sensor temperatures,  this was all working fine during the mock up, (limited wire) so I'm assuming its not a code issue, but here it is anyways if you are curious.
-I have tried adding delays between each temperature read with no difference.
-At the probes I'm getting about 4.9v
-I have run the screen from both board and a separate power supply, same result.
-The controller is being powered from 2amp 5v source plugged into the USB port.  I am reading the sensor values from the display.

If you have any thoughts as to what is causing this device limitation I would be grateful to hear them.
I had to trim down my code to fit in the post cap. all the display and keypad code was removed.

Code: [Select]

#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
 
/
//VARIABLE ASSIGNMENT
#define LED 13
#define ONE_WIRE_BUS_PIN 2


//SENSOR STUFF

OneWire oneWire(ONE_WIRE_BUS_PIN);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C lcd(0x27,20,4);

//Probe order - -Nursery - Probe1

DeviceAddress Probe1 = { 0x28, 0xFF, 0xE8, 0x23, 0x71, 0x16, 0x04, 0x37 }; //Nursery
DeviceAddress Probe2 = { 0x28, 0xB5, 0xD3, 0xE0, 0x08, 0x00, 0x00, 0x8E }; //Bedroom
DeviceAddress Probe3 = { 0x28, 0xFF, 0x57, 0x7B, 0x64, 0x16, 0x03, 0x2F }; //Master
//DeviceAddress Probe4 = { 0x28, 0xFF, 0x86, 0x19, 0xB0, 0x16, 0x05, 0x71 };
//DeviceAddress Probe5 = { 0x28, 0xFF, 0x87, 0x01, 0xB0, 0x16, 0x03, 0x45 };
unsigned char* Probes[] = {Probe1,Probe2,Probe3};


void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  sensors.begin();

   
  // set the resolution to 10 bit (Can be 9 to 12 bits .. lower is faster)
  sensors.setResolution(Probe1, 10);
  delay(200);
  sensors.setResolution(Probe2, 10);
   delay(200);
  sensors.setResolution(Probe3, 10);
   delay(200);
  //sensors.setResolution(Probe4, 10);
  //sensors.setResolution(Probe5, 10);

  pinMode(LED,OUTPUT);

 

void TempCheck(){
for(int x = 0; x<3; x++){
 
   Temps[x]=GetTemp(Probes[x]);
   // Temps[x]=23;
     //delay(500);
    if (Temps[x] >= Sets[x]){
    TempCall[x] = 0;
    //state = "off";
    }
   
    if (Temps[x] < Sets[x]){
    TempCall[x] = 1;
    //state = "on";
    }
 
   }
}

/

Any thoughts are welcome.

Nick_Pyner

I had to trim down my code to fit in the post cap.
Perhaps a little too far. There is no loop.

I bet you don't need to read anything more frequently that once per second, and therefore you can safely delete all code pertaining to resolution, thereby just using the default. I'm not sure that it will help, but it will certainly simplify things.

warrenboyle

Thanks for the reply.  I will try that when I am back from work.  I guess I trimmed out too much for the post, I have attached the full file.  I'll let you know how it goes!

warrenboyle

Hi Nick, I tried the code update, no change in performance.  Have you ever tried having multiple one-wire busses?  I think that might the be simplest solution to get this working, I have enough I/O.  I wish I knew what was causing sensors to lockup though.

photoncatcher

Hi warrenboyle,

In your sketch the (loop) is missing ! This implies a once-and-that-is-it reading.
success, photoncatcher

photoncatcher

Maybe the following sketch can be of assistance  to test a  few of your issues. I hooked up two of my Dallas DS18B20 to pin D10 of an Arduino Nano, standard way - 5V - GND - data wire 4.7 k pull up resistor. The temperature value recorded by each DS18B20 is stored in a float variable; Temp1, Temp2, Temp3, etc.
Please note that sources on the Internet claim that the DS18B20 and DS18S20 differ only in resolution: 10-bit vs. 12-bit.
 
The sketch below initializes each DS18B20, reads, stores and reports on Serial Monitor the ambient temperatures. After that you can compare the stored Temp variables with the thermostat settings or whatever and and promote action.   
success, photoncatcher

Code: [Select]





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

 

// VARIABLE ASSIGNMENT

#define ONE_WIRE_BUS_PIN 10
float Temp1, Temp2, Temp3;


//SENSOR STUFF

OneWire oneWire(ONE_WIRE_BUS_PIN);
DallasTemperature sensors(&oneWire);


// Probe order - -Nursery - Probe1

DeviceAddress Probe1 = { 0x28, 0xFF, 0xA3, 0x94, 0x93, 0x16, 0x05, 0x6F }; //Nursery
DeviceAddress Probe2 = { 0x28, 0xFF, 0xD7, 0x91, 0x92, 0x16, 0x04, 0x69 }; //Bedroom
DeviceAddress Probe3 = { 0x28, 0xFF, 0xD7, 0x91, 0x92, 0x16, 0x04, 0x69 }; //Master    -NOTE device address duplicate of Probe2


//DeviceAddress Probe3 = { 0x28, 0xFF, 0x57, 0x7B, 0x64, 0x16, 0x03, 0x2F }; //Master
//DeviceAddress Probe4 = { 0x28, 0xFF, 0x86, 0x19, 0xB0, 0x16, 0x05, 0x71 };
//DeviceAddress Probe5 = { 0x28, 0xFF, 0x87, 0x01, 0xB0, 0x16, 0x03, 0x45 };


void setup() {

  //Initialize serial and wait for port to open:
  Serial.begin(9600);

  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
  Serial.print("======================================================");
  Serial.println (" ");

  sensors.begin();
  sensors.setResolution(Probe1, 10);  //  set the resolution to 10 bit (Can be 9 to 12 bits .. lower is faster)
  sensors.setResolution(Probe2, 10);
  sensors.setResolution(Probe3, 10);
//  sensors.setResolution(Probe4, 10);
//  sensors.setResolution(Probe5, 10);

}


void loop (){

  delay (2000);
  sensors.requestTemperatures();

  Temp1 = sensors.getTempC (Probe1);   // first  probe temperature stored in float variable Probe1
  Temp2 = sensors.getTempC (Probe2);   // second probe temperature stored in float variable Probe2
  Temp3 = sensors.getTempC (Probe3);   // third  probe temperature stored in float variable Probe3

  Serial.println ("----------------------------------");
  Serial.print ("Nursery temperature:  ");
  Serial.println (Temp1);
  Serial.print ("Bedroom temperature:  ");
  Serial.println (Temp2);
  Serial.print ("Master temperature:   ");
  Serial.println (Temp3);       
  Serial.println ("----------------------------------"); 

 // TempCheck ();
  }


 
/*
void TempCheck (){
for(int x = 0; x<2; x++){
 
   Temps[x]=GetTempC(Probes[x]);
   // Temps[x]=23;
     //delay(500);
    if (Temps[x] >= Sets[x]){
    TempCall[x] = 0;
    //state = "off";
    }
   
    if (Temps[x] < Sets[x]){
    TempCall[x] = 1;
    //state = "on";
    }
 
   }
}
*/

void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00) {
Serial.print("Error");
} else {
Serial.print(tempC,1);
Serial.print("");

Serial.println (tempC);
}
}

MarkT

I've used as many as 20 DS18B20's in a string, with one pullup resistor at each end of the string,
but I made sure every sensor had a decoupling capacitor of its own.  Worked fine 24/7 for years.

Note that DS18B20's from eBay are extremely likely to be fakes these days, and fakes have all
sorts of issues - you don't want to touch them...
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

hammy

There are examples with the libraries for these sensors - I would run that as a check .

Nick_Pyner

Hi Nick, I tried the code update, no change in performance.  Have you ever tried having multiple one-wire busses?  I think that might the be simplest solution to get this working, I have enough I/O.  I wish I knew what was causing sensors to lockup though.
Your problems rather suggest inadequate power and/or bad connections.
I would strongly suggest you ditch all the code, and unnecessary peripherals, and do it again, starting from here. You already have the sensor addresses.

IF you want to admit defeat, it IS possible to have the sensors on individual pins, but that is not a one-wire bus so having individual one-wire busses is pointless. You can use sheepdog
http://sheepdogguides.com/arduino/ar3ne1tt.htm
thereby dispensing with the one-wire library altogether. This is not something you would want to proudly show your mother if you have more than one or, at most two, sensors but, if you just have one, I think it makes more sense to use this method.

warrenboyle

Thanks again. Working now. I followed your advice and ditched a patch cable I had interconnecting a field wiring terminal block to the controller;  everything booted up and I'm getting temperature readings again from all 3 probes. I'll have to re think how I'm landing the thermostat/probe wires in my panel. I really appreciate your help and everyone's suggestions.

Nick_Pyner

I'll have to re think how I'm landing the thermostat/probe wires in my panel.
That gets personal, and only you can work it out. The simplest is probably a small proto shield with screw terminals for the sensor wires.

Go Up