Open mayjack0312 opened 5 months ago
Two tips.
Flush serial before measurements Do all your measurements before printing the results
Two tips.
Flush serial before measurements Do all your measurements before printing the results
I tried both methods, but neither seems to work for me.
According to the datasheet, their units should be in microseconds (us), but my actual measurements are in milliseconds (ms). How should I modify my measurement method?
Your code does measure in microseconds.
I tried both methods, but neither seems to work for me.
What is wrong with the numbers? Are they different than you expect? If so, what numbers do you expect?
Think you should read the datasheet carefully as it does mentions variation on the numbers. E.g. the conversion time for 12 bit is max 750 ms which is based upon the worst case conversion (and maybe even a bit extra).
I slightly modified your code, as you do not take into account that printing variables and strings takes time and these affect your measurements. The code below is a bit more stable as it adds delays to wait until the serial output buffer is empty.
Note that there are always variations per call, so you might need to execute your tests 100 times and take the average.
Furthermore you need to know that micro() has a resolution of 4 us. So it will never return 550. (and it will add the overhead of the function call).
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress DS18B20_ID;
void setup()
{
Serial.begin(9600);
while(!Serial); // wait until Serial device is ready.
Serial.println(__FILE__);
delay(100); // wait until output buffer of Serial is empty.
unsigned long initStartTime = micros();
sensors.begin();
sensors.setResolution(12); // force an explicit resolution, 9..12
unsigned long initEndTime = micros();
Serial.print("Initialization Time: ");
Serial.print(initEndTime - initStartTime);
Serial.println(" us");
delay(100); // wait until output buffer of Serial is empty.
}
void loop()
{
if (Serial.available() > 0)
{
String command = Serial.readStringUntil('\n');
command.trim();
if (command == "GET")
{
delay(100); // wait for Serial output empty.
// why measure this?
unsigned long waitStartTime = micros();
delayMicroseconds(550);
unsigned long waitEndTime = micros();
unsigned long convStartTime = micros();
sensors.requestTemperatures();
unsigned long convEndTime = micros();
unsigned long readCmdStartTime = micros();
float temperature = sensors.getTempCByIndex(0);
unsigned long readCmdEndTime = micros();
// here you measure the time to put the strings
// in the serial output buffer. not the print time.
unsigned long readRegStartTime = micros();
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" C");
unsigned long readRegEndTime = micros();
Serial.print("Wait for Bus Release Time: ");
Serial.print(waitEndTime - waitStartTime);
Serial.println(" us");
Serial.print("Trigger Conversion Time: ");
Serial.print(convEndTime - convStartTime);
Serial.println(" us");
Serial.print("Send Read Command Time: ");
Serial.print(readCmdEndTime - readCmdStartTime);
Serial.println(" us");
Serial.print("Read Register Value Time: ");
Serial.print(readRegEndTime - readRegStartTime);
Serial.println(" us");
} else {
Serial.println("Unknown command.");
}
}
delay(1000); // wait for all output to be done
}
According to the datasheet, their units should be in microseconds (us), but my actual measurements are in milliseconds (ms). How should I modify my measurement method?
Your code does measure in microseconds.
I tried both methods, but neither seems to work for me.
What is wrong with the numbers? Are they different than you expect? If so, what numbers do you expect?
Think you should read the datasheet carefully as it does mentions variation on the numbers. E.g. the conversion time for 12 bit is max 750 ms which is based upon the worst case conversion (and maybe even a bit extra).
I slightly modified your code, as you do not take into account that printing variables and strings takes time and these affect your measurements. The code below is a bit more stable as it adds delays to wait until the serial output buffer is empty.
Note that there are always variations per call, so you might need to execute your tests 100 times and take the average.
Furthermore you need to know that micro() has a resolution of 4 us. So it will never return 550. (and it will add the overhead of the function call).
#include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 2 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress DS18B20_ID; void setup() { Serial.begin(9600); while(!Serial); // wait until Serial device is ready. Serial.println(__FILE__); delay(100); // wait until output buffer of Serial is empty. unsigned long initStartTime = micros(); sensors.begin(); sensors.setResolution(12); // force an explicit resolution, 9..12 unsigned long initEndTime = micros(); Serial.print("Initialization Time: "); Serial.print(initEndTime - initStartTime); Serial.println(" us"); delay(100); // wait until output buffer of Serial is empty. } void loop() { if (Serial.available() > 0) { String command = Serial.readStringUntil('\n'); command.trim(); if (command == "GET") { delay(100); // wait for Serial output empty. // why measure this? unsigned long waitStartTime = micros(); delayMicroseconds(550); unsigned long waitEndTime = micros(); unsigned long convStartTime = micros(); sensors.requestTemperatures(); unsigned long convEndTime = micros(); unsigned long readCmdStartTime = micros(); float temperature = sensors.getTempCByIndex(0); unsigned long readCmdEndTime = micros(); // here you measure the time to put the strings // in the serial output buffer. not the print time. unsigned long readRegStartTime = micros(); Serial.print("Temperature: "); Serial.print(temperature); Serial.println(" C"); unsigned long readRegEndTime = micros(); Serial.print("Wait for Bus Release Time: "); Serial.print(waitEndTime - waitStartTime); Serial.println(" us"); Serial.print("Trigger Conversion Time: "); Serial.print(convEndTime - convStartTime); Serial.println(" us"); Serial.print("Send Read Command Time: "); Serial.print(readCmdEndTime - readCmdStartTime); Serial.println(" us"); Serial.print("Read Register Value Time: "); Serial.print(readRegEndTime - readRegStartTime); Serial.println(" us"); } else { Serial.println("Unknown command."); } } delay(1000); // wait for all output to be done }
Oh, thank you so much! After reading your reply, I realized that my consideration was indeed not very comprehensive. Below is the table representing the results I expect to achieve:
data | time (us) |
---|---|
The time to initialize the DS18B20 and monitor the online information | 610 |
The time to wait for the DS18B20 to release the bus | 550 |
The time to trigger the temperature conversion | 887 |
The time to send the read data command | 886 |
The time to read the register value and obtain the temperature value | 560 |
I want to use a logic analyzer to measure the relevant timing parameters:
According to the datasheet, their units should be in microseconds (us), but my actual measurements are in milliseconds (ms). How should I modify my measurement method? Here is my code: