Go Down

Topic: [SOLVED] 18B20 timing problem (Read 7485 times) previous topic - next topic

Testato


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: [Select]
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
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

robtillaart

#31
Aug 11, 2011, 11:16 am Last Edit: Aug 12, 2011, 09:27 pm by robtillaart Reason: 1
(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: [Select]
 // EXPERIMENTAL read device's scratchpad fast
 void readScratchPadFast(uint8_t*, uint8_t*);


in the .cpp file add
Code: [Select]

// 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: [Select]

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


to
Code: [Select]

// 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.
Rob Tillaart

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

Testato

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
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

robtillaart

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
Rob Tillaart

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

Testato

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: [Select]
#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);

}

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

robtillaart

#35
Aug 12, 2011, 01:38 pm Last Edit: Aug 12, 2011, 01:48 pm by robtillaart Reason: 1
Quote
i do not know the way for measure the response time of getTempCByIndex,


Code: [Select]

unsigned long before = millis();
temp = sensors.getTempCByIndex(0);
Serial.println(millis() - before);

Rob Tillaart

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

robtillaart


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: [Select]
#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);
  }
}
Rob Tillaart

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

robtillaart

#37
Aug 12, 2011, 02:58 pm Last Edit: Aug 12, 2011, 03:44 pm by robtillaart Reason: 1
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: [Select]

// 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
Rob Tillaart

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

Testato

#38
Aug 12, 2011, 06:08 pm Last Edit: Aug 12, 2011, 06:20 pm by Testato Reason: 1
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: [Select]
#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);
}
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

robtillaart

#39
Aug 12, 2011, 09:24 pm Last Edit: Aug 12, 2011, 09:29 pm by robtillaart Reason: 1
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: [Select]

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

(I'll fix the code in the prev post too) done

Rob Tillaart

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

Testato

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
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

robtillaart

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
Rob Tillaart

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

Testato

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.
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

robtillaart

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?
Rob Tillaart

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

robtillaart

Your patched library looks OK.
Rob Tillaart

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

Go Up