Go Down

Topic: DS2438 library (Read 10655 times) previous topic - next topic

billcramer07

Hi all,

I'm using the DS2438 library from Guilherme Barros at http://code.google.com/p/gfb/source/browse/#svn/arduino/DS2438 along with the 1-wire library. I am reading temp and humidity using the example that came with the DS2438 library. Everything is fine until the temp drops below 32.00 degrees F. At that point both temp and humidity jump to over 200 degrees and 150% rh. Is anyone using this library and have you had problems. BTW, I have tried 2 different 1-wire sensor boards with the same problem. As soon as the temp rises to 32 again everything is good.

robtillaart

#1
Nov 09, 2010, 08:45 pm Last Edit: Nov 09, 2010, 09:07 pm by robtillaart Reason: 1
32.00 degrees F is zero Celsius, so maybe there is an overflow or divide by zero or such condition. zero's are nasty numbers in programming as they are the lowest unsigned number. Strange things happened before.

Have to dive into the lib. may take a while .....

update 1: checking the datasheet http://pdfserv.maxim-ic.com/en/ds/DS2438.pdf
DS2438 is a smart Battery Monitor, with a 13 bit temperature sensor, 8 bit before digital point and 5 thereafter, giving a precision of 1/32 degree. (nice IC). Temperature is in Celsius. So it is not a restriction of the sensor, it must be in the lib.

Q: Can you share your code in which it happens?

update 2: Just looking at the lib shows that readHum() uses readTempC() so if the latter is wrong the first one will be too.

update 3: readTempC()
Code: [Select]
float ds2438::readTempC()
{
 //override for now, [glow][b]plsfixkthx[/b][/glow]
 _parasite = 1;

 //request temp conversion
 _wire->reset();
 _wire->select(_deviceAddress);
 _wire->write(CONVERTT, _parasite);
 delay(20);

 //copy data from eeprom to scratchpad & read scratchpad
 ScratchPad _scratchPad;
 _readMem(_scratchPad);
 

 //return tempC (ignore 3 lsb as they are always 0);
 int16_t rawTemp = ( ((int16_t)_scratchPad[TEMP_MSB]) << 5) | (_scratchPad[TEMP_LSB] >> 3);

 return (float)rawTemp * 0.03125;
}


Could the highlighted "Please Fix This" related to your problem? Do you use parasite power?
Rob Tillaart

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

robtillaart

From datasheet:
Quote
PARASITE POWER
The block diagram (Figure 1) shows the parasite-powered circuitry. This circuitry "steals" power whenever the DQ pin is high. DQ will provide sufficient power as long as the specified timing and voltage requirements are met (see the section titled "1-Wire Bus System"). The advantage of parasite power is that the ROM may be read in absence of normal power, i.e., if the battery pack is completely
discharged.
Rob Tillaart

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

billcramer07

Hi robtillaart
First, thanks for looking at this.
Look at the example code with the library. I ran that last night and as soon as the outdoor temp went below 32f or 0c it gave me the strange results. Like you I suspect the calculation used to convert the temperature is at fault but I'm not well versed in C or library building to figure it out.

billcramer07

plsfixkthx


no I did not add that. And no I am not using parasite power

robtillaart

From datasheet:
Quote
Convert T [44h]
This command begins a temperature conversion. No further data is required. The temperature conversion will be performed, setting the TB flag in the Status/Configuration register to a "1" during conversion. When the temperature conversion is done, the TB flag will clear to a "0". If the bus master issues read time slots following this command, the DS2438 will output "0" on the bus as long as it is busy making a temperature conversion; it will return a "1" when the temperature conversion is complete.


When I look at the code of the library it just does a delay(20); after the call for convert. As I am familiar with the DS18B20 temp sensor, that takes 750 msec for 12 bit, so 13 bit may even take longer (OK Assumption with big A)  but it seems to me that the library just waits to short for conversion.

Rob



Rob Tillaart

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

robtillaart

#6
Nov 09, 2010, 09:34 pm Last Edit: Nov 09, 2010, 09:36 pm by robtillaart Reason: 1
Could you please try to replace readTempC in the library with this one. It waits until the TB flag (Temperature Busy) is cleared. Code is not compiled or tested ;)

Rob

Code: [Select]

float ds2438::readTempC()
{
 //override for now, plsfixkthx
 _parasite = 1;

 //request temp conversion
 _wire->reset();
 _wire->select(_deviceAddress);
 _wire->write(CONVERTT, _parasite);
 // delay(20);  


 ScratchPad _scratchPad;

 // wait until TB register clears, see page 15/29 datasheet
 // iso delay(20);
 boolean ready = false;
 while (!ready)
 {
    //copy data from eeprom to scratchpad & read scratchpad
   _readMem(_scratchPad);
   ready = ( _scratchPad[STATUS]  & 0x10) == 0x00;
   delay(10);  // wait before reread of the scratchpad
 }
 // TB is cleared so conversion is ready

 //return tempC (ignore 3 lsb as they are always 0);
 int16_t rawTemp = ( ((int16_t)_scratchPad[TEMP_MSB]) << 5) | (_scratchPad[TEMP_LSB] >> 3);

 return (float)rawTemp * 0.03125;
}

Rob Tillaart

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

billcramer07

Should I make that delay say 750ms and see if that helps

Bill

billcramer07

I"ll try you fix and let you know. Thanks for your help!

Bill

robtillaart

If you just want to tweak the delay I would propose to start with 2000 millisec iso 750. that's quite long but if the IC behaves similar to the DS18B20 2000 is a reasonable value. The DS18B20 doubles the delay time for every extra bit ( it can be configured from 9-12 bits with a max of 750 msec)

If 2000 works you might go down in steps of 100 msec until it fails.

Rob
Rob Tillaart

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

PaulS

@Rob
Why would the delay become a factor only when the temperature drops below 0C/32F?
The art of getting good answers lies in asking good questions.

mowcius

I had a similar problem on the TC74 temp sensors, it overflows back to 255 when the temp drops below 0. Pretty simple to solve in code though as the max temp is 125C (I think) so anything above that is mapped to minus values in code.

Mowcius

robtillaart

#12
Nov 09, 2010, 10:14 pm Last Edit: Nov 09, 2010, 10:28 pm by robtillaart Reason: 1
@PaulS
Just don't know, but I have seen too many bugs caused by zero or -signs changing the behaviour unexpectedly.
e.g. http://it.slashdot.org/article.pl?sid=07/02/25/2038217 or http://catless.ncl.ac.uk/Risks/3.44.html

Technically, I can imagine that with lower temperatures the ADC goes slower but never that much slower. So that's not the cause.
My current line of thought is that as long as the TB flag is not cleared the scratchpad reads an undefined value ... (based upon datasheet)

Better ideas allways welcome.
Rob
Rob Tillaart

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

robtillaart

Found cause for the bug, please confirm as I have no sensor to test with.

The scratchpad is defined as array of unsigned int 8 (see ds2438.h)
Code: [Select]
typedef uint8_t ScratchPad[9];
in readTempC(); the temperature reading is done and two shifts are  used to merge the value of the MSB and LSB register. As the value of MSB is an unsigned int,  the value casting it to an int_16_t does not do a sign extension. Therefor as the value becomes (should be) negative, it is interpreted as 255 instead of -1.

The problem reveals itself in this line:
Code: [Select]
int16_t rawTemp = ( ((int16_t)_scratchPad[TEMP_MSB]) << 5) | (_scratchPad[TEMP_LSB] >> 3);

Solution: Change readTempC() to

Code: [Select]

float ds2438::readTempC()
{
 //override for now, plsfixkthx
 _parasite = 1;

 //request temp conversion
 _wire->reset();
 _wire->select(_deviceAddress);
 _wire->write(CONVERTT, _parasite);
 delay(20);

 //copy data from eeprom to scratchpad & read scratchpad
 ScratchPad _scratchPad;
 _readMem(_scratchPad);
 
 //return tempC (ignore 3 lsb as they are always 0);
 uint8_t x = _scratchPad[TEMP_MSB];
 int rawTemp = (x & 0x80)?(-256+x): x;  // uint8_t => int
 float f = rawTemp + (_scratchPad[TEMP_LSB] >> 3) * 0.03125;

 return f;
}


Rob

Note: Other solution could be the changing the type of the scratchpad to signed but I did not investigate the impact of that change to the rest of the DS2438 class.
Rob Tillaart

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

robtillaart

#14
Nov 10, 2010, 09:19 am Last Edit: Nov 10, 2010, 09:25 am by robtillaart Reason: 1
Reported this as a bug on http://code.google.com/p/gfb/source/browse/#svn/arduino/DS2438

Also reported the delay(20) iso waiting for TB clear flag instatus register as bug.
Rob Tillaart

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

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy