HOME  > >  ARDUINO MAIN PAGE > >  HINTS AND HOW-TOs > >  NuELEC DATALOG  t.o.c.     Delicious Bookmark this on Delicious   Recommend to StumbleUpon

Two or more temperature sensors


This tutorial shows you how to access two or more Dallas 1-Wire digital temperature sensors, DS18B20s. Don't be scared by the "DS"... yes, this is a chip from Dallas's 1-wire family , but you don't have to deal with the usual 1-Wire programming things. You don't need the general Arduino 1-Wire library.

If you feel you want to ease into this subject gently, I have a "How to connect one DS18B20 to an Arduino" essay for you.

It might not look like it, but "all" you need to understand of the code farther down the page is....

void loop()
{
  readTture(tture1);
       printTture();
       Serial.print("   ");

  delay(120);

  readTture(tture2);
      printTture();
      delay(200);
      Serial.print("\n");
}

Well... okay... and a few extra details. We'll come back to the above in a moment. The details are....

At the head of the code:

#define tture1 14
#define tture2 15

int HighByte, LowByte, TReading,
         SignBit, Tc_100, Whole, Fract;

And in the setup() function:

    pinMode(tture1, INPUT);
    pinMode(tture2, INPUT);

    digitalWrite(tture1, LOW);
    digitalWrite(tture2, LOW);

Everything else in the code is either basic, basic, general stuff, or "black box" stuff that you put in and leave alone, as is.

So... details of what is in "loop()"...

I've done a Bad Thing in order to keep the code simple. I've used global variables: HighByte, LowByte, etc.

The command "readTture(xx)" tells the Arduino to go off and check one of the sensors, and place the answer in the global variables. (None of them has to be in any particular state before you called readTture.)

If you call "printTture();", and you have put sensible values in the global variable before calling it, you will get a temperature displayed via the serial monitor. (It is easy to write similar procedures to send the output someplace else.)"printTture();" sends just something like "15.0" to the monitor, so we have the Serial.print statements to put a space between the two readings and start a new line when both sensors have been read.

That use of global variables is "poor programming"... but it works. It is a Bad Idea because it is easy for bugs to creep in and hide in such opaque programming. But The Right Way To Do It requires that you understand a complex data type, and I want this essay accessible to many readers.

But that's really pretty well "it"!

Details of how to connect the sensor... really easy... and details of what goes on inside the "black box" parts of the program are covered in detail in my page about reading just one DS18B20.

An aside: You will see "one wire" and "one wire interface" in the nuelectronics.com documentation. This is not always connected with "1-Wire" (a Dallas trademark) at all, and even when you are connecting a 1-Wire device to a nuelectronics "one wire" connection point, you won't often (ever?) get dragged into some of the more complex 1-Wire issues. Don't get me wrong... I like 1-Wire... it is powerful. But to get everything you can from 1-Wire gets dangerously close to Serious Work. The datalogging shield from nuelectonics.com lets you use some of the (marvelous) 1-Wire devices without the work!

Code for reading two DS18B20's on an Arduino....

Apologies if you visited this page on the morning of 19Jly2010 and were faced with totally irrelevant code!

/*ReadDS18B20two
ver: 18 Jly 2010
Started end of term eve WG/TA/LE/EW/JGB

Reading two DS18B20s

See...

http://sheepdogguides.com/arduino/ar3ne1tt2.htm

... for explanation of this code.

Code adapted from code from nuelectronics.com demo*/

#define tture1 14//no ; here
#define tture2 15//no ; here

/*Forward declarations. Only the last two need concern the user
Remmed out, as they seem unnecessary
void OneWireReset(int Pin);//Called by readTture
void OneWireOutByte(int Pin, byte d);//Called by readTture
byte OneWireInByte(int Pin);//Called by readTture

void readTture(byte Pin);//Of use to users
void printTture();//Of use to users
*/

//Following globals used to communicate results back
//from readTture(Pin), and to send data to printTture...
int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;

void setup() {
    //For each tture sensor: Do a pinMode and a digitalWrite
    pinMode(tture1, INPUT);
    pinMode(tture2, INPUT);

    digitalWrite(tture1, LOW);//Disable internal pull-up.
    digitalWrite(tture2, LOW);

    Serial.begin(9600);
    delay(300);//Wait for newly restarted system to stabilize
    Serial.print("Temperature measurement, two sensors:\n\n");
}

void loop(){

  readTture(tture1);//N.B.: Values passed back in globals
  printTture();//N.B.: Takes values from globals. Also...
     //no newline part of pritTture;
  Serial.print("   ");
  delay(120);// Delay... must not be too short.
  readTture(tture2);//Now read and report 2nd tture.
  printTture();
  delay(200);// Delay... must not be too short.
  Serial.print("\n");//Start new line
}


//Everything below here... just copy it into your program "as is".
//You are only likely to need to use readTture(pin) and printTture()
//   directly. Others are subordinate to those.
//These routine access the following global variables...
//   int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
void OneWireReset(int Pin) // reset.  Should improve to act as a presence pulse
{
     digitalWrite(Pin, LOW);
     pinMode(Pin, OUTPUT); // bring low for 500 us
     delayMicroseconds(500);
     pinMode(Pin, INPUT);
     delayMicroseconds(500);
}//end OneWireReset

void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first).
{
   byte n;

   for(n=8; n!=0; n--)
   {
      if ((d & 0x01) == 1)  // test least sig bit
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(5);
         pinMode(Pin, INPUT);
         delayMicroseconds(60);
      }
      else
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(60);
         pinMode(Pin, INPUT);
      }
      d=d>>1; // now the next bit is in the least sig bit position.
   }
}//end OneWireOutByte

byte OneWireInByte(int Pin) // read byte, least sig byte first
{
    byte d, n, b;

    for (n=0; n<8; n++)
    {
        digitalWrite(Pin, LOW);
        pinMode(Pin, OUTPUT);
        delayMicroseconds(5);
        pinMode(Pin, INPUT);
        delayMicroseconds(5);
        b = digitalRead(Pin);
        delayMicroseconds(50);
        d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
    }
    return(d);
}//end OneWireInByte

void readTture(byte Pin){
//Pass WHICH pin you want to read in "Pin"
//Returns values in... (See global declarations)
  OneWireReset(Pin);
  OneWireOutByte(Pin, 0xcc);
  OneWireOutByte(Pin, 0x44); // perform temperature conversion, strong pullup for one sec

  OneWireReset(Pin);
  OneWireOutByte(Pin, 0xcc);
  OneWireOutByte(Pin, 0xbe);

  LowByte = OneWireInByte(Pin);
  HighByte = OneWireInByte(Pin);
  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;
};//end readTture

void printTture(){//Uses values from global variables.
//See global declarations.
//N.B.: No new line inside printTture
if (SignBit) // If it's negative
    {
     Serial.print("-");
    };
  Serial.print(Whole);
  Serial.print(".");
  if (Fract < 10)
    {
     Serial.print("0");
    };
  Serial.print(Fract);
};//end printTture

I hope the above Just Works for you.

A word about...

/*Forward declarations. Only the last two need concern the user
Remmed out, as they seem unnecessary
void OneWireReset(int Pin);//Called by readTture
void OneWireOutByte(int Pin, byte d);//Called by readTture
byte OneWireInByte(int Pin);//Called by readTture

void readTture(byte Pin);//Of use to users
void printTture();//Of use to users
*/

I THINK you can just take that out, if you want to. And I think it does no harm to take out the "/*" and "*/" which turn the block into a comment, or "rem".

There was a time when if you didn't put function declarations into your Arduino code in a particular order, or didn't use forward declarations, then you'd have compile problems. I think those days are past. If any reader can comment from a secure, "expert", point of view, the comments would be welcome!

The End

That's pretty well it for "how to read two or more temperature sensors with a microprocessor, e.g. Arduino".

Back in the Bad Old Days when programming was Hard Work, I did quite a lot with Dallas 1-Wire chips. They have quite fantastic capabilities, of which the above code doesn't avail itself at all. If you are interested in learning more about 1-Wire chip programming, in a context probably more relevant to users of "big" computers, I offer you my tutorials about programming for the Dallas Semiconductor 1-Wire (tm) chips, as used on a MicroLan (tm). Those tutorials are written for Delphi (language) programmers, but they contain much information that would apply to other language environments. I also maintain pages which introduce MicroLans and explain the hardware.


-------------------

Going back to Arduinos, and away from Dallas 1-Wire, see also: The Arduino programming course from Sheepdog Guides:

I have written a series of essays which try to help you become a better Arduino programmer and engineer... but, for the best result, you will have to buckle down and work your way through them in sequence. The collection of "How To's" this page comes from can be accessed in whatever order you like.


Feel free to use this information in programming courses, etc, but a credit of the source would be appreciated. If you simply copy the pages to other web pages you will do your readers a disservice: Your copies won't stay current. Far better to link to these pages, and then your readers see up-to-date versions. For those who care- thank you- I have posted a page with more information on what copyright waivers I extend, and suggestions for those who wish to put this material on CDs, etc.





Editorial Philosophy

See the discussion near the bottom of the "top level" page covering the bulk of my Arduino contributions. There is information there, too, about things like "May I copy your material?", and the system of file names I am trying to work to.


   Search this site or the web        powered by FreeFind
 
  Site search Web search
Site Map    What's New    Search

The search engine is not intelligent. It merely seeks the words you specify. It will not do anything sensible with "What does the 'could not compile' error mean?" It will just return references to pages with "what", "does", "could", "not".... etc.
In addition to the information about the nuelectronics data shield of which this page is part, I have other sites with material you might find useful.....

Tutorials about the free database which is part of the free Open Office.
Sequenced set of tutorials on Pascal programming and electronics interfacing.
Some pages for programmers.
Using the parallel port of a Windows computer.

If you visit 1&1's site from here, it helps me. They host my website, and I wouldn't put this link up for them if I wasn't happy with their service... although I was less than pleased the other day to have what I was doing interrupted by a telephone call from their sales team, trying to get me to extend my involvement. Sigh. Hardly a rare event, but I'd thought 1&1 were a bit classier that some of the people who have my telephone number.



Ad from page's editor: Yes.. I do enjoy compiling these things for you... hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows PC) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!

Click here to visit editor's Sheepdog Software (tm) freeware, shareware pages.


And if you liked that, or want different things, here are some more pages from the editor of these tutorials....

Click here to visit the homepage of my biggest site.

Click here to visit the homepage of Sheepdogsoftware.co.uk. Apologies if the "?Frmar3ne1tt2" I added to that link causes your browser problems. Please let me know, if so?

Click here to visit editor's pages about using computers in Sensing and Control, e.g. weather logging.



To email this page's editor, Tom Boyd.... Editor's email address. Suggestions welcomed!


Valid HTML 4.01 Transitional Page tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org


Why does this page cause a script to run? Because of the Google panels, and the code for the search button. Why do I mention the script? Be sure you know all you need to about spyware.

....... P a g e . . . E n d s .....