Pages: 1 2 [3] 4 5   Go Down
Author Topic: [SOLVED] 18B20 timing problem  (Read 6628 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Faraday Member
**
Karma: 46
Posts: 5881
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Single device can be tested with with getDeviceCount() ==> optional use the device address)

Combined with my prev post void readScratchPadFast for a single device could become:

Code:
void readScratchPadFast(uint8_t* deviceAddress, uint8_t* scratchPad)
{
  // send the command                      
  _wire->reset();                                 // 1.5 millis
  if (devices > 1) _wire->select(deviceAddress);           // command + 8 bytes == 9 * 0.6 = 5.4 millis.
  _wire->write(READSCRATCH);            // command == 0.6 millis
  scratchPad[0] = _wire->read();          // read only the temperature bytes
  scratchPad[1] = _wire->read();          // 2 * 0.6 = 1.2 millis
}

In case of onde device ~3.2 millis active waiting iso 14 ;  That could bring getTempC from 20 ms down to 9 ms.

Worth testing & investigating.  

Rob may I try your last code ? i do not know which file in library must change.
Thanks
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13718
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

(disclaimer, could not test these modifications as I have several other mods in my Dallas Lib in progress, sorry)

You need to adapt both DallasTemperature.cpp and the .h file

In the .h file add
Code:
 // EXPERIMENTAL read device's scratchpad fast
  void readScratchPadFast(uint8_t*, uint8_t*);

in the .cpp file add
Code:
// EXPERIMENTAL
void DallasTemperature::readScratchPadFast(uint8_t* deviceAddress, uint8_t* scratchPad)
{
  // send the command                      
  _wire->reset();                                 // 1.5 millis
  if (devices > 1) _wire->select(deviceAddress);           // command + 8 bytes == 9 * 0.6 = 5.4 millis.
  else _wire->skip();                      // 1 Byte = 0.6 millis.  // needed for 1 device
  _wire->write(READSCRATCH);            // command == 0.6 millis
  scratchPad[0] = _wire->read();          // read only the temperature bytes
  scratchPad[1] = _wire->read();          // 2 * 0.6 = 1.2 millis
}

in the .cpp file change
Code:
bool DallasTemperature::isConnected(uint8_t* deviceAddress, uint8_t* scratchPad)
{
  readScratchPad(deviceAddress, scratchPad);
  return (_wire->crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC]);
}

to
Code:
// EXPERIMENTAL
bool DallasTemperature::isConnected(uint8_t* deviceAddress, uint8_t* scratchPad)
{
  readScratchPadFast(deviceAddress, scratchPad);
  return true;
}

// ORIGINAL
//bool DallasTemperature::isConnected(uint8_t* deviceAddress, uint8_t* scratchPad)
//{
//  readScratchPad(deviceAddress, scratchPad);
//  return (_wire->crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC]);
//}

Give it a try, and share the results.

update - fixed some bugs in code above.
« Last Edit: August 12, 2011, 02:27:45 pm by robtillaart » Logged

Rob Tillaart

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

0
Offline Offline
Faraday Member
**
Karma: 46
Posts: 5881
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

nope, same problem
please check if i correctly modified the files, i put the changed code here:

- at line 134 of .h

- at the very end of .cpp, line 730

- the other code correctly changed
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13718
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
nope, same problem
So same problem of the spikes...

Quote
please check if i correctly modified the files, i put the changed code here:
If code compiled the code is "patched properly"    (you could have changed it at many different lines.)


Was the timing with readScratchPadFast() faster or slower or no difference? just for my information
Logged

Rob Tillaart

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

0
Offline Offline
Faraday Member
**
Karma: 46
Posts: 5881
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i do not know the way for measure the response time of getTempCByIndex,

this is my code, you can view the problem directly on Arduino TX Led

i tried the non-parasite supply also with no result

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



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

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


// variabili temp
  float temp;
  long previousMillis = 0;
 

void setup(void)
{
   sensors.begin();
  sensors.setResolution(12);
  sensors.setWaitForConversion(false);  // makes it async asincrono=non blocca il programma durante la lettura
  Serial.begin(9600);
}

void loop(void)
{
 

 if (millis() - previousMillis > 750)   // mette la temperatura nella variabile temp dopo 750ms
 {
    temp=sensors.getTempCByIndex(0); // comando che crea il problema
   sensors.requestTemperatures(); // Send the command to get temperatures
    previousMillis = millis(); // riparte il temporizzatore
 }
 
Serial.println(temp);

}
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13718
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
i do not know the way for measure the response time of getTempCByIndex,

Code:
unsigned long before = millis();
temp = sensors.getTempCByIndex(0);
Serial.println(millis() - before);
« Last Edit: August 12, 2011, 06:48:04 am by robtillaart » Logged

Rob Tillaart

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

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13718
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


I modified your code a bit:
* added two lines in setup() for a proper start

* moved the serial.print(temp) into the conditional part (so only print after a new reading, to not get flooded with values)
* commented out this same serial.println(temp) as that causes the tx led to blink
* LED 13 blinks after every read (just to see that the code still works)

==> I have no blinking tx LED at my Arduino 2009 (no UNO nearby)

Please try this code..
Code:
#include <DallasTemperature.h>
#include <OneWire.h>

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

float temp;
long previousMillis = 0;

void setup(void)
{
  pinMode(13, OUTPUT);
  sensors.begin();
  sensors.setResolution(12);
  sensors.setWaitForConversion(false);  // makes it async asincrono=non blocca il programma durante la lettura
  Serial.begin(9600);

  sensors.requestTemperatures(); // Send the command to get temperatures
  previousMillis = millis();
}

void loop(void)
{
  if (millis() - previousMillis > 750)   // mette la temperatura nella variabile temp dopo 750ms
  {
    temp = sensors.getTempCByIndex(0);
    sensors.requestTemperatures(); // Send the command to get temperatures
    previousMillis = millis(); // riparte il temporizzatore
    digitalWrite(13, !digitalRead(13));
    // Serial.println(temp);
  }
}
Logged

Rob Tillaart

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

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13718
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Did some poking & tweaking in the Dallas Library to optimize fetching the temperature only.  To be applied as previous specified. The comments give the hard coded delays of the wire class.

Code:
// EXPERIMENTAL
void DallasTemperature::readScratchPadFast(uint8_t* deviceAddress, uint8_t* scratchPad)
{
  // send the command                      
  _wire->reset();                                //  1.5 millis
  if (devices > 1) _wire->select(deviceAddress);  // command + 8 bytes == 9 * 0.6 = 5.4 millis.
  else _wire->skip();                          // 1 Byte = 0.6 millis.  // needed for 1 device

  _wire->write(READSCRATCH);          // 1 BYTE = 0.6 millis
  scratchPad[0] = _wire->read();         // read only the temperature bytes
  scratchPad[1] = _wire->read();         // 2 * 0.6 = 1.2 millis
}
Results sofar one sensor:

1) readScratchPad()         sensors.getTempCByIndex(0); takes 28 millis()
2) readScratchPadFast()   sensors.getTempCByIndex(0); takes 18 millis()

Results sofar two sensors:

1) readScratchPad()         sensors.getTempCByIndex(0); takes 28 millis()
2) readScratchPadFast()   sensors.getTempCByIndex(0); takes 23 millis()


Conclusion:
There is time to be gained, however to get more one probably need to dive into the wire lib.



disclaimer - code still experimental
« Last Edit: August 12, 2011, 08:44:15 am by robtillaart » Logged

Rob Tillaart

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

0
Offline Offline
Faraday Member
**
Karma: 46
Posts: 5881
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i updated the .ccp but have always 28ms with 1 sensor
may send me your library ?

i used this code (sensor on pin16 (A2))

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

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 16
// 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);

// temp variable
float temp;

void setup(void)
{
  sensors.begin();
  sensors.setResolution(12);
  sensors.setWaitForConversion(false);  // makes it async asincrono=non blocca il programma durante la lettur
  Serial.begin(9600);
}


void loop(void)
{
 unsigned long before = millis();
 temp = sensors.getTempCByIndex(0);
 Serial.println(millis() - before);
}
« Last Edit: August 12, 2011, 11:20:27 am by Testato » Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13718
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
i updated the .ccp but have always 28ms with 1 sensor
may send me your library ?

sorry but no, too much (other) experimental code in it. As soon as it is stable I'll get it incorporated in the official library.

I went through my previous post and found this bug  (sorry)
Code:
// EXPERIMENTAL
bool DallasTemperature::isConnected(uint8_t* deviceAddress, uint8_t* scratchPad)
{
  readScratchPad(deviceAddress, scratchPad);  <<<<<<<<<<< should be readScratchPadFast(deviceAddress, scratchPad); of course
  return true;
}

Explains why you still get 28 millis, it is experimental code (no guarantees smiley-wink

(I'll fix the code in the prev post too) done
 
« Last Edit: August 12, 2011, 02:29:24 pm by robtillaart » Logged

Rob Tillaart

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

0
Offline Offline
Faraday Member
**
Karma: 46
Posts: 5881
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

always 28ms

i have dallas 3.7.1 on onewire2 whit no other change, if you want i may send you the two library for check ?

i think this work is important because 18ms off is not interpretable by human eyes and this mean using 18B20 in realtime temp reading
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13718
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
i think this work is important because 18ms off is not interpretable by human eyes and this mean using 18B20 in realtime temp reading

The reading of the sensor took 18 ms,  but I had to wait 750ms before conversion was ready ....

You can attach your library as a zip file (See additional options), if time permits I can have a look
Logged

Rob Tillaart

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

0
Offline Offline
Faraday Member
**
Karma: 46
Posts: 5881
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I attached the files,

i know the 750ms delay, but my idea of "real time temp" derived from display used.
My display work on BCD, so arduino pick the TEMP variable from gettempbyindex, convert in bcd, and send this to display.

So during 750ms conversion time arduino convert always the same value to bcd (no problem), but during the GetTempByIndex we need 28ms, and during this 28ms the TEMP variable is empy, so NO BCD CONVERSION, so display off.

* DallasTemperature_371Beta.zip (23.32 KB - downloaded 10 times.)
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13718
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So during 750ms conversion time arduino convert always the same value to bcd (no problem), but during the GetTempByIndex we need 28ms, and during this 28ms the TEMP variable is empy, so NO BCD CONVERSION, so display off.

I don't understand your code logic from what you write. You should just keep on displaying the last temperature until the GetTemperatureByINdex is ready

Can you post the latest code of your sketch?
Logged

Rob Tillaart

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

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13718
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your patched library looks OK.
Logged

Rob Tillaart

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

Pages: 1 2 [3] 4 5   Go Up
Jump to: