connect 3 sensors oneWire dallas DS 1820

hello ¡¡

I got 3 sensors oneWire dallas DS 1820 and i would like to get the data from them in arduino , i,m waiting for some 4.7k resistor to check the example with one but how could i use 3 in the same time ?

cheers :)

Which example? The 4k7 resistor is probably just to make the 1-Wire work BETTER... it will probably work pretty well without it IF IT IS THE RESISTOR I think YOU MEAN.

3 sensors connecting to one reader is, in general, not a problem. How you do it depends on how you are doing other things.

Lots on 1-Wire in general from....

http://www.arunet.co.uk/tkboyd/e1didx.htm

A complex way to connect 1-Wire to Arduino.. which saves you complexity in your code... is at...

sheepdogguides.com/arduino/asw1onew1.htm

but how could i use 3 in the same time ?

Just wire them up to the same signal wire. They will all have unique addresses when you do a bus search.

The resistor is a pull up for the bus. It is needed but only one of them. Are you parasitically powering the device? If so you can only initiate one conversion at a time.

hi , thanks for your quick replies , for first i was going to try this http://www.pjrc.com/teensy/td_libs_OneWire.html with one sensor , and then you guys say that i can connect 3 of them using the same cables toguether ? what would i have to change in the code to get the 3 values ? i read a few sites about and some staff is confusing , isent it better to connect the sensor in diferent pins for more precision ?

Hi,

to make things easy, have a look here:

http://milesburton.com/wiki/index.php?title=Dallas_Temperature_Control_Library

very easy to understand.

Greetings, EriSan500

isent it better to connect the sensor in diferent pins for more precision

No the precision of the sensor is the same no matter how you connect it.

It is a BUS - a bus is one or more wires that carry signals from one or more sensors.

ok thanks , so i,ll connect the 3 sensors to the same 5v ground and digital pin and then , would it be as easy as to add at the end of the code here http://milesburton.com/wiki/index.php?title=Dallas_Temperature_Control_Library

just change the index to get printed the others ? like

Serial.print(sensors.getTempCByIndex(0)); first one Serial.print(sensors.getTempCByIndex(1)); second Serial.print(sensors.getTempCByIndex(2)); third

will i get the values in celsius ,farenheit or i need other calculation to get the right degrees ?

will i get the values in celsius ,farenheit or i need other calculation to get the right degrees

It is in celsius. Here is a function I wrote to display the value on an LCD display. It will show you the sort of calculations you need to do.

Note it is only part of a program that did other things so there will be variables that are not defined if you try an just run this bit is shows you what to do.

void displayTemprature(byte *addr){
    byte i;
    byte data[12];
    int reading1, reading2;
   if(ds.reset()== 1){     // see if the device is present
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad
       for ( i = 0; i < 9; i++) {           // we need to read 9 bytes
    data[i] = ds.read();
    }
   reading1 = data[0] | (data[1] << 8);
   reading2 = reading1 >> 4;
   if (reading1 < 0) reading2 |= 0xF000;  // compensate for the shift if it is a negitave reading
    Serial.print(reading2, DEC);
    lcd.setCursor(0, 0);
     lcd.print(reading2, DEC);
    int fract = 0;
    if((reading1 & 0x8) != 0)fract += 50;
    if((reading1 & 0x4) != 0)fract += 25;
    if((reading1 & 0x2) != 0)fract += 12;  // not strictly accurate (12.5) but will do
    if((reading1 & 0x1) != 0)fract += 6;   // not strictly accurate (6.25) but will do
    Serial.print(".");
    lcd.print(".");
    Serial.print(fract, DEC);
    lcd.print(fract, DEC);
    Serial.println(" C");
    lcd.write(0xdf);
    lcd.print("C   ");
  }
else {
  Serial.println(" Device not present ");
     lcd.setCursor(0, 0);
     lcd.print("No 1-wire found ");
     lcd.setCursor(0x0, 1);
     lcd.print("e found ");
     }    // end of else on device present
}         // end of function displayScratch

thanks for your help i could not test with the sensors yet still waiting for th resistor but i have tried to start making some code for my final purpose and i found some problems . i would like to use the simple code to get values from 3 temperature sensors and in the same code i would like to send some serial data to control some pwm , when adding some lines from the pwm code i realised it does not work unless i disable line

//sensors.requestTemperatures(); // Send the command to get temperatures

then i will not be able to use the temperature sensors , anyone knows why the dallas code is bothering with the serial read code ?

here is the code :

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

int fanPin[] = {3,5,6,9,10,11}; 
int recivingValues[6]; 


// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

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

void setup(void)
{
 
  Serial.begin(9600);
 
  for (int i=0; i<6; i++) {
  pinMode(fanPin[i], OUTPUT);

  // Start up the library
  
  
  
}
sensors.begin();

}

void loop(void)

  {
  // this is the line that interf
 sensors.requestTemperatures(); // Send the command to get temperatures
    
    
  if (Serial.available() >= 6) {
    
    for (int i=0; i<6; i++) {
     
      recivingValues[i] = Serial.read();
      analogWrite(fanPin[i], recivingValues[i]);
      
    }
  }


  Serial.print(sensors.getTempCByIndex(0));
 
  Serial.print(" ");
 
  Serial.print(sensors.getTempCByIndex(1)); 
   
  Serial.println(); 
  
  
 }

cheers :wink:

Have you got the DallasTemperature library loaded?

then i will not be able to use the temperature sensors

No then you will not be able to use the libraries.

i realised it does not work unless i disable line

Do you mean it will not compile? If so what error messages are you getting?

hi thanks for your reply .

1-yes dallas library is loaded correctly

2- i can not use the serial read code if i leave the line

enalbed like this :

sensors.requestTemperatures(); // Send the command to get temperatures

that means that somehow the dallas temeprature or the onewire library somehow interferes in the serial read or my littles lines of code to receiveb data form the seral to the pwm .

3- yes the code compile perfectly with or without the line it,s just the serial read that does not work as expected anymore that means i can not send data from the serial to the pwm pins correctly anymore .

hello ¡¡¡

i received the resistor and connect 2 sensors , they work perfectly using just one resistor and one cable connected to digital pin 2 ,so this part is great .

but this is just part of the code that i need to do , i,m experimenting this problem receving data from the serial port , as i tried to explain above , i will like to send data with the serial port to control the 6 pwm pins of my arduino dicimila , i,m sending the values out of the computer with vvvv , the code works well on its own but when adding it to the temperature sensors code , arduino does not received the data properly , it looks like everything is deleyed and shifted one position in the loop also some strange behaviours .

could someone please help me with this ?

there is something in the onewire or dallas library that is causing this if you tried the code and disable line //sensors.requestTemperatures(); the serial works well again but of course i need this line for the dallas to work .

thanks for all the help so far and also for the guys that made the library ;)

Conversion of the temperature signal takes 750ms for the DS18S20. This delay is in the "sensors.requestTemperatures()" function. That means that everything else is on hold for 750ms per temperature request. That might explain the behaviour you see.

If you want to continue doing other stuff while the conversion takes place, you have to split requestTemperatures() function in a "requestScratchPad" and a "ReadScratchPad" function (refer to the datasheet of the DS18S20). When you requested the scratch pad, start a timer and meanwhile continue with the rest of your loop. When the timer equals 750ms, read the scratch pad and reset the timer and request the next scratch pad. At least this is how it worked for me.

I declared fixed ID’s for the sensors, With a read function, it will report the unique ID’s of the found sensors on the bus, then I configure them in my sensor declaration.

This is my code for reading the temperatures without delaying the rest of the program loop:

#include <OneWire.h>

// One wire bus on pin 14 of the Arduino duemilanove
OneWire ds(14);

int SensorNr = 1;
boolean ScratchPadRequested = false;


float TemperatureTop;
float TemperatureMiddle;
float TemperatureValve;

long previousMillis = 0;             // will store last time conversion was complete
long ConversionTime = 750;     // Conversion time for DS18S20 (milliseconds) in parasite mode

byte sensor1[8] = {
  0x10, 0xCE, 0x34, 0xD5, 0x01, 0x08, 0x00, 0xB1}; // ID 1st DS18S20 sensor
byte sensor2[8] = {
  0x10, 0x9A, 0x34, 0xD5, 0x01, 0x08, 0x00, 0x43}; // ID 2nd DS18S20 sensor
byte sensor3[8] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // ID 3rd DS18S20 sensor

void setup(void) {
  
}

void loop(void)
{ 
// Get temperatures
  if (SensorNr == 1 && ScratchPadRequested == false){
    RequestScratchPad(sensor1);
    ScratchPadRequested = true;
  }
  if (SensorNr == 1 && ScratchPadRequested == true && (millis() - previousMillis > ConversionTime)){
    TemperatureTop = GetTemperature(sensor1);
  }

  if (SensorNr == 2 && ScratchPadRequested == false){
    RequestScratchPad(sensor2);
    ScratchPadRequested = true;
  }
  if (SensorNr == 2 && ScratchPadRequested == true &&(millis() - previousMillis > ConversionTime)){
    TemperatureMiddle = GetTemperature(sensor2);
  }

  if (SensorNr == 3 && ScratchPadRequested == false){
    RequestScratchPad(sensor3);
    ScratchPadRequested = true;
  }
  if (SensorNr == 3 && ScratchPadRequested == true && (millis() - previousMillis > ConversionTime)){
    TemperatureValve = GetTemperature(sensor3);
  }
}

void RequestScratchPad(byte* address){
  ds.reset();
  ds.select(address);
  ds.write(0x44,1);
}

void ReadScratchPad(byte* address, byte* data){
  ds.reset();
  ds.select(address);
  ds.write(0xBE);
  for (byte i=0;i<9;i++)
  {
    data[i] = ds.read();
  }
}

float GetTemperature(byte* address){
  int tr;
  byte data[12];
  // save the last time the temperature was converted 
  previousMillis = millis();
  ReadScratchPad(address, data); 

  //put in temp all the 8 bits of LSB (least significant byte)
  int LSB;
  int HSB;

  LSB = data[0];
  HSB = data[1];

  //check for negative temperature
  if (HSB > 0x80){
    LSB = !LSB + 1; //two's complement adjustment
    LSB = LSB * -1; //flip value negative.
  }
  //COUNT PER Celsius degree (10h)
  int CPC = data[7];
  //COUNT REMAIN (0Ch)
  int CR = data[6];
  //drop bit 0
  tr = LSB >> 1;

  if (SensorNr < 3){
    SensorNr = SensorNr++;
  }
  else
  {
    SensorNr = 1;
  }
  ScratchPadRequested = false;
  //calculate the temperature based on this formula, to get resolution of 9 bits (0.25 °C) :
  //TEMPERATURE = TEMP READ - 0.25 + (COUNT PER Celsius Degree - COUNT REMAIN)/ (COUNT PER Celsius Degree)
  return (float)tr - (float)0.25 + (CPC - CR)/(float)CPC;
}

hey thanks a lot for the code , unfortunatly it is giving me many error to compile some declarations and funtion error i inlude the libraires #include <OneWire.h>
#include <DallasTemperature.h> in case but all the compiling error still there , does this code compile on your board ?

Hi,

I forgot to mention that you have to put in:

#include <OneWire.h>

// One wire bus on pin 14 of the Arduino duemilanove
OneWire ds(14);
boolean ScratchPadRequested = false;

You don’t need to include the DallasTemperature.h header file

include the setup function

I have updated the code in my previous post and it compiles at my end perfectly.

One thing, this code is for the DS18S20, which has the 9 bit resolution

hello , thanks it compiles now correctly , i,m using the DS1820 http://www2.produktinfo.conrad.com/datenblaetter/175000-199999/184067-da-01-en-TEMP_FUEHLER_EDELST_G_KABEL_2M.pdf which seem to be a a bit diferent , when you mean (ds 14 ) that sounds like another chip apart from the sensor itself ? or if you mean the arduino pin you mean pin 13 ?

in another forum topic i saw something about changing some numbers depending of the sensor chip which i can not find now like some hex string depending of teh sensor will that make any sense to get my sensor working ?

sorry guys for making so many question :-?

OneWire ds(14) means that I connected the one wire bus on pin 14, which is actually the first analog input on the Duemilanove. You are free to declare any other pin.

If your software returns an ID beginning with 0x10, it means that it is a DS18S20 type, if it is 0x28 it is a DS18B20. To convert the raw sensor reading to a temperature you have to apply a formula which is in the datasheet. In my case I am using a DS18S20, and the formula is:

//TEMPERATURE = TEMP READ - 0.25 + (COUNT PER Celsius Degree - COUNT REMAIN)/ (COUNT PER Celsius Degree) return (float)tr - (float)0.25 + (CPC - CR)/(float)CPC;

to convert for other types and for datasheets:

http://www.arduino.cc/playground/Learning/OneWire

thanks again , i connected to pin ds14 (analog pin 0 ) in the board i,m using a diecimila , i dont get anything from the sensor probably because it is a diferent one mine is dallas ds 1820 , also i tried to print many diferen variables i dont get quite well will be the actual temperature one : this ones : float TemperatureTop; float TemperatureMiddle; float TemperatureValve; i get nothing with them .

i would have love to learn how to do it this way , for now i just add a counter in the simple exaple code of the dallas library so it recheck everycertain time , doing this i can send values the pwm .

cheers and thanks a lot for your help

Are you aware of the fact that you have to replace the unique ID nr’s with the sensors you are using at:

byte sensor1[8] = {
0x10, 0xCE, 0x34, 0xD5, 0x01, 0x08, 0x00, 0xB1}; // ID 1st DS18S20 sensor
byte sensor2[8] = {
0x10, 0x9A, 0x34, 0xD5, 0x01, 0x08, 0x00, 0x43}; // ID 2nd DS18S20 sensor
byte sensor3[8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // ID 3rd DS18S20 sensor

the HEX numbers mentioned above are the ID’s of the sensors which I use. So if you have not changed these to the ones you are using, it is obvious that you get nothing from the variables, because the controller can simply not find these sensors on the bus.
The reason I have done this this way, so I always get the right value in the right container variable.

To get your unique ID’s you can add the follwoing code to your application in the loop:

// When "S" is sent from the computer, scan for sensors
  if (Serial.available() > 0)
    // read the oldest byte in the serial buffer:
  {
    //if it is "S" we can scan for sensors
    inByte = Serial.read();
    if (inByte == 'S')
    {
      ScanForSensors();
    }
  }

put this as a void function under the loop:

void ScanForSensors()
{
  byte address[8];
  int i=0;
  byte ok = 0, tmp = 0;
  //start the search
  Serial.println("--Search started--");
  while (ds.search(address)){
    tmp = 0;
    //0x10 = DS18S20
    if (address[0] == 0x10){
      Serial.print("Device is a DS18S20 : ");
      tmp = 1;
    } 
    else {
      //0x28 = DS18B20
      if (address[0] == 0x28){
        Serial.print("Device is a DS18B20 : ");
        tmp = 1;
      }
    }
    //display the address, if tmp is ok
    if (tmp == 1){
      if (OneWire::crc8(address, 7) != address[7]){
        Serial.println("but it doesn't have a valid CRC!");
      } 
      else {
        //all is ok, display it
        for (i=0;i<8;i++){
          if (address[i] < 9){
            Serial.print("0");
          }
          Serial.print(address[i],HEX);
          if (i<7){
            Serial.print("-");
          }
        }
        Serial.println("");
        ok = 1;
      }
    }//end if tmp
  }//end while
  if (ok == 0){
    Serial.println("No devices were found");
  }
  Serial.println("--Search ended--");
}

Open the serial monitor in Arduino and send the character “S”, the serial monitor displays the found sensor ID’s on the bus, if it found any.