Single wire digital temperature. DS18B20 + Arduino

Discussions area for bildr's blog posts.
Hi,
Thanks a lot for al the work and effort you put into your site!
It's great, and because of your site i decided to buy a arduino board.

I have the following problem:
After i downloaded the files and saved them in the libaries folder,
i opened the file and pushed compile, to test if everything is working.
Well, it doesn't. It gives me the following errors:
Code: Select all
C:\Users\RDLE\Downloads\arduino-1.0-windows\arduino-1.0\libraries\OneWire\OneWire.cpp:62:24: error: WConstants.h: No such file or directory
C:\Users\RDLE\Downloads\arduino-1.0-windows\arduino-1.0\libraries\OneWire\OneWire.cpp: In constructor 'OneWire::OneWire(uint8_t)':
C:\Users\RDLE\Downloads\arduino-1.0-windows\arduino-1.0\libraries\OneWire\OneWire.cpp:71: error: 'digitalPinToPort' was not declared in this scope
C:\ .... etc


I am very new to arduino, so i have no idea what i'm doing wrong. It seems like it can't find WConstants.h but where do i get it, or where should it be?
I hope you guys can help me out!

Regards,
Richard
rtenklooster
 
Posts: 4
Joined: Dec 20th, 2011

Im guessing you are using arduino 1.0?

They changed everything since version 0.23 so I have to upgrade all the code now.

You can download 23 from here: http://www.arduino.cc/en/Main/software

I dont know when Ill have this updated. Should be in the next month.

Sorry about that.


rtenklooster wrote:Hi,
Thanks a lot for al the work and effort you put into your site!
It's great, and because of your site i decided to buy a arduino board.

I have the following problem:
After i downloaded the files and saved them in the libaries folder,
i opened the file and pushed compile, to test if everything is working.
Well, it doesn't. It gives me the following errors:
Code: Select all
C:\Users\RDLE\Downloads\arduino-1.0-windows\arduino-1.0\libraries\OneWire\OneWire.cpp:62:24: error: WConstants.h: No such file or directory
C:\Users\RDLE\Downloads\arduino-1.0-windows\arduino-1.0\libraries\OneWire\OneWire.cpp: In constructor 'OneWire::OneWire(uint8_t)':
C:\Users\RDLE\Downloads\arduino-1.0-windows\arduino-1.0\libraries\OneWire\OneWire.cpp:71: error: 'digitalPinToPort' was not declared in this scope
C:\ .... etc


I am very new to arduino, so i have no idea what i'm doing wrong. It seems like it can't find WConstants.h but where do i get it, or where should it be?
I hope you guys can help me out!

Regards,
Richard
ameyer
Founder
 
Posts: 2916
Joined: Jan 21st, 2010
Location: The Bay Area

get the last version of the one wire library - it has support for arduino 1.0
here is the link http://www.pjrc.com/teensy/td_libs_OneWire.html
putyn
 
Posts: 66
Joined: May 9th, 2011
Location: Romania

Thank's a lot. Downgrading did the trick!
:-)
Will try the new oneire libary later! Thanks for your fast reply's.
My home - web based thermostat for my central heating is working now! 8-)
rtenklooster
 
Posts: 4
Joined: Dec 20th, 2011

Hi all,
How can i extend the original code from the tutorial to use multiple sensors?
I've been searching around but all the code i try either gives wierd readings or I don' understand the code well enough to modify it.

appreciate any advice,

cheers erbey
erbey
 
Posts: 2
Joined: Feb 13th, 2012

Im not 100% sure, and I only have one to test with, but this should work.
It is a little crude because they do allow you to have them all connected to one wire, but this code just has each sensor on a different pin.

I set it up for 4 sensors, but it should be easy to see how you add or reduce that


Code: Select all

#include <OneWire.h>

int DS18S20_1_Pin = 2; //DS18S20 1 Signal pin on digital 2
int DS18S20_2_Pin = 3; //DS18S20 2 Signal pin on digital 3
int DS18S20_3_Pin = 4; //DS18S20 3 Signal pin on digital 4
int DS18S20_4_Pin = 5; //DS18S20 4 Signal pin on digital 5

//Temperature chip i/o
OneWire ds1(DS18S20_1_Pin); // on digital pin 2
OneWire ds2(DS18S20_2_Pin); // on digital pin 3
OneWire ds3(DS18S20_3_Pin); // on digital pin 4
OneWire ds4(DS18S20_4_Pin); // on digital pin 5


void setup(void) {
Serial.begin(9600);
}

void loop(void) {
  float temperature1 = getTemp(ds1);
  float temperature2 = getTemp(ds2);
  float temperature3 = getTemp(ds3);
  float temperature4 = getTemp(ds4);

  Serial.print(temperature1);
  Serial.print(" | ");
  Serial.print(temperature2);
  Serial.print(" | ");
  Serial.print(temperature3);
  Serial.print(" | ");
  Serial.println(temperature4);
   
  delay(100); //just here to slow down the output so it is easier to read
}


float getTemp(OneWire sensor){
//returns the temperature from one DS18S20 in DEG Celsius

byte data[12];
byte addr[8];

if ( !sensor.search(addr)) {
   //no more sensors on chain, reset search
   sensor.reset_search();
   return -1000;
}

if ( OneWire::crc8( addr, 7) != addr[7]) {
   Serial.println("CRC is not valid!");
   return -1000;
}

if ( addr[0] != 0x10 && addr[0] != 0x28) {
   Serial.print("Device is not recognized");
   return -1000;
}

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

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


for (int i = 0; i < 9; i++) { // we need 9 bytes
  data[i] = sensor.read();
}

sensor.reset_search();

byte MSB = data[1];
byte LSB = data[0];

float tempRead = ((MSB << 8) | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;

return TemperatureSum;

}





erbey wrote:Hi all,
How can i extend the original code from the tutorial to use multiple sensors?
I've been searching around but all the code i try either gives wierd readings or I don' understand the code well enough to modify it.

appreciate any advice,

cheers erbey
ameyer
Founder
 
Posts: 2916
Joined: Jan 21st, 2010
Location: The Bay Area

Thanks for the quick reply and asking on twitter, But i kind of need the the data pins need to be on the same wire so in the future i can add in a 1-wire RTC and humidity sensor and have enough pins to control an LCD display in the future. I'll do some more research tomorrow when I'm not so tired and see what i can find.
Thanks Erbey
erbey
 
Posts: 2
Joined: Feb 13th, 2012

This is entirely possible to do on one pin. The code actually supports this by default but in the code written by ameyer, he only uses the first address found. This is seen in the following code segment:

Code: Select all
if ( !sensor.search(addr)) {
   //no more sensors on chain, reset search
   sensor.reset_search();
   return -1000;
}


The sensor.search() function is as follows:
//
// Perform a search. If this function returns a '1' then it has
// enumerated the next device and you may retrieve the ROM from the
// OneWire::address variable. If there are no devices, no further
// devices, or something horrible happens in the middle of the
// enumeration then a 0 is returned. If a new device is found then
// its address is copied to newAddr. Use OneWire::reset_search() to
// start over.
//


If you wanted to read the temperature from a specific device, you could do something like this:

Code: Select all
float getTemp(OneWire sensor, byte * address){
//returns the temperature from the DS18S20 of the address specified in DEG Celsius

byte data[12];
byte addr[8];

while(1==1) {
   if(sensor.search(addr) == 0) //End of the chain
   {
      sensor.reset_search();
      return -1000;
   }
   if(memcmp(addr, address, 8) == 0) //Found our address!
   {
      break;
   }
}

....THE REST IS THE SAME...
}


Good Luck!

Jon

erbey wrote:Thanks for the quick reply and asking on twitter, But i kind of need the the data pins need to be on the same wire so in the future i can add in a 1-wire RTC and humidity sensor and have enough pins to control an LCD display in the future. I'll do some more research tomorrow when I'm not so tired and see what i can find.
Thanks Erbey
Xnient
 
Posts: 30
Joined: Jan 28th, 2012

I can't get the DS18B20 to work with my Arduino Mega2560. Tried almost every pin. Why? Borrowed a Uno and it worked on the first try. Which pin should I use on the Mega? I use a 4.7kOhm pull-up to 5V on the data line.
This is driving me crazy. :-(
dme88
 
Posts: 2
Joined: Apr 16th, 2012

Not sure why. So weird.
You could try this library here: http://www.pjrc.com/teensy/arduino_libr ... neWire.zip


dme88 wrote:I can't get the DS18B20 to work with my Arduino Mega2560. Tried almost every pin. Why? Borrowed a Uno and it worked on the first try. Which pin should I use on the Mega? I use a 4.7kOhm pull-up to 5V on the data line.
This is driving me crazy. :-(
ameyer
Founder
 
Posts: 2916
Joined: Jan 21st, 2010
Location: The Bay Area

Awesome bits from all of you; I was up and running inside of five minutes and brand new to Arduino, too!

Took me longer to find a terminal than it did to plunk in the code...


So, question: I can see where we configure multiple sensors and their relevant pins... but how would one wire this up? I thought there are three wires per sensor?

Also, I saw this bit:

Code: Select all
float getTemp(OneWire sensor){
//returns the temperature from one DS18S20 in DEG Celsius


I imagine the value of only one sensor is returned; what about four? Earlier in the code we have:

Code: Select all
OneWire ds1(DS18S20_1_Pin); // on digital pin 2
OneWire ds2(DS18S20_2_Pin); // on digital pin 3
OneWire ds3(DS18S20_3_Pin); // on digital pin 4
OneWire ds4(DS18S20_4_Pin); // on digital pin 5


I would assume we can write something to return all four, and do an average or something?

I have what I want it to do in my head; just still learning how the code works / what the different names mean to make it work. Apologies in advance for the newbieness. :)

Kudos for the codework, though :D :mrgreen:
mike_yyc
 
Posts: 2
Joined: Apr 16th, 2012

You can do something like this I believe.


Code: Select all


#include <OneWire.h>

int DS18S20_1_Pin = 2; //DS18S20 1 Signal pin on digital 2
int DS18S20_2_Pin = 3; //DS18S20 2 Signal pin on digital 3
int DS18S20_3_Pin = 4; //DS18S20 3 Signal pin on digital 4
int DS18S20_4_Pin = 5; //DS18S20 4 Signal pin on digital 5

//Temperature chip i/o
OneWire ds1(DS18S20_1_Pin); // on digital pin 2
OneWire ds2(DS18S20_2_Pin); // on digital pin 3
OneWire ds3(DS18S20_3_Pin); // on digital pin 4
OneWire ds4(DS18S20_4_Pin); // on digital pin 5


void setup(void) {
Serial.begin(9600);
}

void loop(void) {
  float temperature1 = getTemp(ds1);
  float temperature2 = getTemp(ds2);
  float temperature3 = getTemp(ds3);
  float temperature4 = getTemp(ds4);

  Serial.print(temperature1);
  Serial.print(" | ");
  Serial.print(temperature2);
  Serial.print(" | ");
  Serial.print(temperature3);
  Serial.print(" | ");
  Serial.println(temperature4);
   
  delay(100); //just here to slow down the output so it is easier to read
}


float getTemp(OneWire sensor){
//returns the temperature from one DS18S20 in DEG Celsius

byte data[12];
byte addr[8];

if ( !sensor.search(addr)) {
   //no more sensors on chain, reset search
   sensor.reset_search();
   return -1000;
}

if ( OneWire::crc8( addr, 7) != addr[7]) {
   Serial.println("CRC is not valid!");
   return -1000;
}

if ( addr[0] != 0x10 && addr[0] != 0x28) {
   Serial.print("Device is not recognized");
   return -1000;
}

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

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


for (int i = 0; i < 9; i++) { // we need 9 bytes
  data[i] = sensor.read();
}

sensor.reset_search();

byte MSB = data[1];
byte LSB = data[0];

float tempRead = ((MSB << 8) | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;

return TemperatureSum;

}





Also check out this post: viewtopic.php?p=5080#p5080



mike_yyc wrote:Awesome bits from all of you; I was up and running inside of five minutes and brand new to Arduino, too!

Took me longer to find a terminal than it did to plunk in the code...


So, question: I can see where we configure multiple sensors and their relevant pins... but how would one wire this up? I thought there are three wires per sensor?

Also, I saw this bit:

Code: Select all
float getTemp(OneWire sensor){
//returns the temperature from one DS18S20 in DEG Celsius


I imagine the value of only one sensor is returned; what about four? Earlier in the code we have:

Code: Select all
OneWire ds1(DS18S20_1_Pin); // on digital pin 2
OneWire ds2(DS18S20_2_Pin); // on digital pin 3
OneWire ds3(DS18S20_3_Pin); // on digital pin 4
OneWire ds4(DS18S20_4_Pin); // on digital pin 5


I would assume we can write something to return all four, and do an average or something?

I have what I want it to do in my head; just still learning how the code works / what the different names mean to make it work. Apologies in advance for the newbieness. :)

Kudos for the codework, though :D :mrgreen:
ameyer
Founder
 
Posts: 2916
Joined: Jan 21st, 2010
Location: The Bay Area

Thanks Ameyer :mrgreen:

I had a look at the post referenced but don't really see anything about the physical wiring part. The actual connect-y bits, not the code bits. :oops:
mike_yyc
 
Posts: 2
Joined: Apr 16th, 2012

ameyer wrote:Not sure why. So weird.
You could try this library here: http://www.pjrc.com/teensy/arduino_libr ... neWire.zip



Same result, won't work. Using latest Arduino. Is the libraries not compatible with Mega2560?
dme88
 
Posts: 2
Joined: Apr 16th, 2012

It should be. Im really not sure why that would be the case at all.


dme88 wrote:
ameyer wrote:Not sure why. So weird.
You could try this library here: http://www.pjrc.com/teensy/arduino_libr ... neWire.zip



Same result, won't work. Using latest Arduino. Is the libraries not compatible with Mega2560?
ameyer
Founder
 
Posts: 2916
Joined: Jan 21st, 2010
Location: The Bay Area

float tempRead = ((MSB << 8) | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;


Why the tempRead/16? I understand the bit shift
jtacquaiii
 
Posts: 7
Joined: Aug 20th, 2011

Also why do i only get .00 precision? Shouldn't it go out to .0625 in 12bit mode? Which i assume is what this is in as i don't see anything to the contrary.
jtacquaiii
 
Posts: 7
Joined: Aug 20th, 2011

Just the conversion that is stated in the doc sheet I believe. (been quite some time since I read it.)

jtacquaiii wrote:float tempRead = ((MSB << 8) | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;


Why the tempRead/16? I understand the bit shift
ameyer
Founder
 
Posts: 2916
Joined: Jan 21st, 2010
Location: The Bay Area

Could be a rounding error, or something as simple as the serial print precision.

jtacquaiii wrote:Also why do i only get .00 precision? Shouldn't it go out to .0625 in 12bit mode? Which i assume is what this is in as i don't see anything to the contrary.
ameyer
Founder
 
Posts: 2916
Joined: Jan 21st, 2010
Location: The Bay Area

Okay, I have like 50 of the DS18S20 thermometers and I just got two samples of the DS18B20 from Maxim today, I know they return different numbers (either 9 bit or 12 bit); throughout this thread I have seen people using the S20 and the B20, which device is the example code for the S20 or the B20?
whitnasty1
 
Posts: 8
Joined: Jun 11th, 2012
Location: Wilmington, North Carolina

B20


whitnasty1 wrote:Okay, I have like 50 of the DS18S20 thermometers and I just got two samples of the DS18B20 from Maxim today, I know they return different numbers (either 9 bit or 12 bit); throughout this thread I have seen people using the S20 and the B20, which device is the example code for the S20 or the B20?
ameyer
Founder
 
Posts: 2916
Joined: Jan 21st, 2010
Location: The Bay Area

Great code, and Yes, this code only works for the B20 and NOT the S20. I was wondering if you could add something in there to convert to Fahrenheit with the same precisions at least the hundredths place.

Also, what would need to be changed to make this code work for the S20??

Thanks
BCHurricane89
 
Posts: 1
Joined: Jul 20th, 2012

F = (C temp * 9 / 5) + 32

Sorry, I have never worked with the S20


BCHurricane89 wrote:Great code, and Yes, this code only works for the B20 and NOT the S20. I was wondering if you could add something in there to convert to Fahrenheit with the same precisions at least the hundredths place.

Also, what would need to be changed to make this code work for the S20??

Thanks
ameyer
Founder
 
Posts: 2916
Joined: Jan 21st, 2010
Location: The Bay Area

Very thankful this code works, I have never used one-wire and am not very fluent in C++. I just assumed this would be as easy as all the serial devices I've used. So far Arduino's reference page has provided me all the info I've ever needed to write software for all my projects, but I can't find any of this stuff from this code on there and I really want to learn. Is there anyway I could get a version with detailed comments for a chemist? I understand the general structure, but I have no idea what these ds... commands do, and I am really confused why my user manual says 44h is the protocol command for temperature conversion, but this code uses 0x44 instead (and 0xBE instead of BEh)? How is 0x44 related to 44h etc.?
sandbeda
 
Posts: 1
Joined: Oct 30th, 2012

I myself dont understand all of it, I based it on other code.

This is a way to take 2 bytes and combine them to make a 12bit integer that uses what is called twos compliment.

twos compliment is a way to define a negative number in binary. http://en.wikipedia.org/wiki/Two's_complement

arduino needs 16 bits to make a twos compliment integer. But we only get 12 bits from this sensor. So I make it a 16 bit by basically just adding 4 0s to the end of it. But we have to divide by 16 because of that. (those 4 0s would make the number 16times larger otherwise).


Code: Select all
byte MSB = data[1];
byte LSB = data[0];

float tempRead = ((MSB << 8) | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;

return TemperatureSum;




0x44 and 44h are the same.
0x... is the prefix for a hex value
...h is a suffix used for a hex value.

Im not sure why anyone uses ...h but they do.


sandbeda wrote:Very thankful this code works, I have never used one-wire and am not very fluent in C++. I just assumed this would be as easy as all the serial devices I've used. So far Arduino's reference page has provided me all the info I've ever needed to write software for all my projects, but I can't find any of this stuff from this code on there and I really want to learn. Is there anyway I could get a version with detailed comments for a chemist? I understand the general structure, but I have no idea what these ds... commands do, and I am really confused why my user manual says 44h is the protocol command for temperature conversion, but this code uses 0x44 instead (and 0xBE instead of BEh)? How is 0x44 related to 44h etc.?
ameyer
Founder
 
Posts: 2916
Joined: Jan 21st, 2010
Location: The Bay Area

PreviousNext

Return to Blog Posts

Who is online

Users browsing this forum: Google Adsense [Bot] and 1 guest