Go Down

Topic: DS18B20 serial print slow? (Read 3591 times) previous topic - next topic

Dared

Jan 09, 2011, 11:07 pm Last Edit: Jan 09, 2011, 11:20 pm by Dared Reason: 1
Hey

When i'm using the following sketch for the DS18B20 sensor, and I check the serial monitor, I'm not getting temp values every 1000 ms = 1 sec, but every 2 sec.

Mind that I'm using 12 bit instead of 10 bit, can this cause any problems?

Anyone have an idea what I am doing wrong?

Code: [Select]
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS A3

// 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.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

DeviceAddress insideThermometer = { 0x28, 0xE5, 0x88, 0xC5, 0x02, 0x00, 0x00, 0xDE };

void setup(void)
{
 // start serial port
 Serial.begin(9600);
 // Start up the library
 sensors.begin();
 // set the resolution to 10 bit (good enough?)
 sensors.setResolution(insideThermometer, 12);
}

void printTemperature(DeviceAddress deviceAddress)
{
 float tempC = sensors.getTempC(deviceAddress);
   Serial.print("C: ");
   Serial.print(tempC);
}

void loop(void)
{
 delay(1000);
 sensors.requestTemperatures();
 

 printTemperature(insideThermometer);
 Serial.print("\n\r");

}


Greetings

PaulS

There is some time required to collect the temperature, and to shift the data out the serial port. It would not surprise me that that takes a full second.

davekw7x

#2
Jan 10, 2011, 12:57 am Last Edit: Jan 10, 2011, 01:02 am by davekw7x Reason: 1
Since it takes something like 750 milliseconds to get the bits from the sensor, if you want to report temperature readings every 1000 milliseconds you can use the same principle that is illustrated in the "Blink Without Delay" sample sketch of the Arduino distribution

My take on it would (probably) be something like the following:
Code: [Select]

//
// Uncomment the first two print statements inside the loop to find the
// amount of time it takes to obtain sensor data.  After you have satisfied
// your curiosity, you can comment them out so that only the actual temperature
// print statement is left.
//
//  davekw7x
//
void loop(void)
{
   unsigned long nowTime = millis();
   
   // Do nothing until 1 second after the last request
   if (nowTime > oldTime + sampleInterval) {
       oldTime = nowTime;
       Serial.print("Requesting Temperatures at ");Serial.println(millis());
       sensors.requestTemperatures();
       Serial.print("Back from request       at ");Serial.println(millis());Serial.println();

       Serial.print("Temperature at ");Serial.print(millis()); Serial.print(" is ");
       printTemperature(insideThermometer);Serial.println();Serial.println();
   }
   // You can do othr stuff in your loop if you need to.
   // Put the stuff here
}


Output will be something like:

Requesting Temperatures at 1027
Back from request       at 1811

Temperature at 1835 is C: 16.81

Requesting Temperatures at 2028
Back from request       at 2812

Temperature at 2836 is C: 16.81

Requesting Temperatures at 3028
Back from request       at 3813

Temperature at 3836 is C: 16.87
.
.
.




Regards,

Dave

Harold Lee

If you look at the library code for the DallasTemperature routines you will see that there are delays inserted which allows the chip to perform an internal conversion. The higher the resolution the greater the delay. Here is a snippet of code from the library showing the delay:

// sends command for one device to perform a temperature by address
void DallasTemperature::requestTemperaturesByAddress(uint8_t* deviceAddress)
{
 _wire->reset();
 _wire->select(deviceAddress);
 _wire->write(STARTCONVO, parasite);

 switch (conversionDelay)
 {
   case TEMP_9_BIT:
     delay(94);
     break;
   case TEMP_10_BIT:
     delay(188);
     break;
   case TEMP_11_BIT:
     delay(375);
     break;
   case TEMP_12_BIT:
   default:
     delay(750);
     break;
 }
}

robtillaart

#4
Jan 10, 2011, 06:13 pm Last Edit: Jan 11, 2011, 06:56 am by robtillaart Reason: 1
I allready contacted Miles Burton the maintainer of the lib with some small additions to use the library in an asynchronous mode.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

TeamMCS

Hi guys,

Apologies, Rob was kind enough to send me some of his changes to enable asynchronous mode a while ago and I managed to totally forget about it.

The synchronous version (the copy you downloaded) cannot be any faster as the IC needs time to process but we can add a "callback" when the reading is ready or allow you to check whether it's ready yet so you can continue processing other work (non-blocking).

I'll discuss with Rob getting the library updated.

Dared

Thanks for the feedback guys.

So the values I was getting were from 1000 ms + 750m/s of the 12 bit.

I'll be waiting for the new library. In the meanwhile im going to try to seperate the code for temp receiving time and clock time like davekw7x says just for learning.


Greetings

pwillard

#7
Jan 12, 2011, 03:27 am Last Edit: Jan 12, 2011, 03:27 am by pwillard Reason: 1
You will be ultimately limited by the way that DALLAS/MAXIM implemented the MICROLAN protocol for 1-wire devices.

davekw7x

#8
Jan 12, 2011, 08:20 pm Last Edit: Jan 12, 2011, 11:55 pm by davekw7x Reason: 1
For practical purposes you are limited by the time the DS18B20 takes for the analog to digital conversion to get the temperature value into its internal data registers.

From the DS18B20 data sheet:

The maximum time for a 12 bit conversion can be as much as 750 milliseconds.
The maximum times for 11, 10, and 9 bit conversions are 1/2, 1/4, and 1/8 of the maximum 12-bit conversion time  (375 ms, 187.5 ms, and 93.75 ms, respectively).


My observation of a few devices shows that the actual time for a 12-bit conversion is something a little more than 500 milliseconds..  (It's easy to test to see if the conversion is complete, and I assume that's what the library's author intends to add.)  So the conversion can be a little faster, but the main point is that you don't have to wait around with an explicit delay of 750 milliseconds.  You can start the conversion, do some other stuff, and then check back later to see whether it is finished.

Anyhow...

For my own project, instead of the DallasTemperature library, I just used the Arduino OneWire library directly.  (It's not as convenient as using the DallasTemperature library, but it works for me.)

The I2C communication method used in the OneWire library takes about 500 microseconds to read a single byte, so you can read the the two temperature bytes in about a millisecond.  Assuming that the device is directly powered (none of that parasitic stuff), it may take a millisecond or so to select the device and give the read command.  You can read the entire scratchpad, including the CRC byte, in five or six milliseconds.


Regards,

Dave

Go Up