I am trying to make a project with HCSR04 Sensor in unconventional way. What i want is measure the temperature with HCSR04 Ultrasonic Sensor. Ultrasonic Sensor works with sound waves to detect distance measurement.
This will calculate the speed of sound in units of centimetres per microsecond.
What units for speed of sound does this equation require in order to give the correct result as a temperature in C or F?
You are implying that you have made a mistake. What evidence do you have for this mistake? That would have been a very helpful thing to include in your original post
Example for a temperature of 18°C speed of sound is
331.5 + 0.6 * 18 = 342,3 m/sec
traveltime for a distance of 0.2 m
t = 0.2 m / 342.3 m/sec = 584 µsec.
584 µsec is the time that you measure
t =
t = distance / V(T) = distance / (331.5 m/sec + 0.6 m/ (secK) * T
t = distance / (331.5 m/sec + 0.6 m/(secK) *T
transforming the equation to T (Temperature)
Temperature T = ( (D / t) - 331.5) * 10 / 6
With "standard"-units like m you would get a float-calculation
Temperature T = (0.2 / (584.0/1000000.0) - 331.5) * 10.0 / 6.0
which might be unprecise as floats in C++ do not have many digits
So using bigger numbers to do the calculation with integers might be more precise
unsigned longs can hold values up to 2^32 = 4_294_967_296
to make the division D / t more precise the numbers can be multiplied by 1000 / 100
should give the temperature
unsigned long dfactor = 1000;
unsigned long zfactor = 100;
unsigned long speedOfSoundAt0C = 3315UL * zfactor;
// 123456
// 200000 µm * 1000 = 200_000_000
// 1234567890
// 4294967296
unsigned long distance = 200000UL * dfactor;
unsigned long travelTime = 584UL;
unsigned long temperature = 0;
float FspeedOfSoundAt0C = 331.5;
float Fdistance = 0.2;
float FtravelTime = 584.0 / 1000000;
float Ftemperature = 0.0;
void setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
temperature = ( ( (distance ) / travelTime) - (speedOfSoundAt0C) ) * 10 / 6;
Serial.print("integer-calc temperature=");
Serial.println(temperature / 1000.0,6);
Ftemperature = ( (Fdistance/ FtravelTime - FspeedOfSoundAt0C) * 10.0 ) / 6.0;
Serial.print("float-calc Ftemperature=");
Serial.println(Ftemperature,6);
}
void loop() {
// put your main code here, to run repeatedly:
}
Thanks but i am trying to measure the temperature with HCSR04 from speed of sound and distance. I am not trying to make pricise the measurement of sensor.
What you CAN do is measure the speed of sound and interpolate, which travels at a known speed in an environment of known altitude, pressure and temperature.
You know the distance from your transmitter to your reflector. As the temperature changes, so will the time to receive the reflection. See @StefanL38@robtillaart@PaulRB replies.
You may need to take many distance measurements and average them to remove random noise from the readings.
Even then, on most Arduino, pulseIn() may not be accurate to 1us, I'm not sure. If it is only actuate to, say 4us, then your temp readings will only be accurate to 4~5 degrees C.
I may be crying wolf. I remember that on Uno/Nano 3/Mega (16MHz AVR MCUs) the micros() function is only accurate to about 4us.
However, I also seem to remember that pulseIn() does not rely on micros() but rather uses a tight loop that increments a count during the pulse. That count is then converted microseconds using a calibrated constant. So maybe it is accurate to 1us.
100%, in fact its core is written in assembler IIRC.
What pulseIn does not do is disabling interrupts so there is a chance it gets disrupted e.g. if you do a Serial.print("whatever"); just before the call of pulseIn.
So I think for precise measurements I would add noInterrupts() or cli() before PulseIn(),
To investigate...
micros() is hardware timer based so it will "count" even during interrupts, price is its 4us resolution.
Well
I made some progress on project and already made the presentation to my advisor prof. I will share the code here and hope that it works for you guys too. It is not precise but if you can compansite the errors on HC-SR04 sensor with bm280 it would be work better. Compansite is important because the speed of sound also depends to the temp, humidity and presure. If you do the calibration of these, you can measure the Temp from HC-Sr04 more precisely. Here is the code and other Lib Files;
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_SSD1306.h>
/////
#define SDA_PORT PORTC
#define SDA_PIN 4 // A4
#define SCL_PORT PORTC
#define SCL_PIN 5 // A5
#define I2C_FASTMODE 1
#include <SoftI2CMaster.h> // These
#include "OLED_SoftI2C.h" // Are
#include "term8x14_font.h" // For
#include <SSD1306Ascii.h> // OLED
OLEDSoftI2C oled(0x3c); // Display
char txt[100];
/////
#define OLED_RESET 5
#define echoPin 6
#define trigPin 7
// LM35 Temp Sensor
int lm35Pin = A0;
int lm35Val = 0;
// HC-SR03 Sensor
double temp_voltage ;
double temp;
Adafruit_SSD1306 display(OLED_RESET);
void setup()
{
pinMode(trigPin,OUTPUT); // pin7
pinMode(echoPin,INPUT);
////
oled.init();
oled.clrScr();
oled.setFont(Term8x14PL);
oled.printStr(0, 0, "LM35:");
oled.printStr(0, 4, "HCSR:");
oled.setMinCharWd(8);
/////
Serial.begin(9600);
}
double tempHCSR(float distance) {
double speedOfSound, measuredHCSR_temp ;
long durationHCSR;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(2);
// Getting the value of pulse duration for speed of sound
durationHCSR = pulseIn(echoPin, HIGH);
// Speed of Sound Calculation (m/s)
speedOfSound = (2.0 * (distance)) / (durationHCSR);
Serial.println(durationHCSR);
Serial.println(speedOfSound);
// Calculating the HC-SR04 Temp
measuredHCSR_temp = (speedOfSound - 0.03314) / 0.0000606; // (Celsius)
//measuredHCSR_temp = (speedOfSound*10000.0-331.4)/0.6;
return measuredHCSR_temp;
}
void loop()
{
float measuredHCSR_temp = tempHCSR(20.0); // write the distance of wall to inside(dont change the distance while trying to get temp. Sensor has to be fixed.)
delay(20);
lm35Val = analogRead(lm35Pin); // getting the true temp value analog
delay(20);
temp_voltage = (5.0/1023.0)*lm35Val;
temp = temp_voltage /0.01;
Serial.println(temp);
Serial.println(measuredHCSR_temp);
// OLED Displays
dtostrf(temp,5,2,txt);
oled.printStr(38,0,txt);
dtostrf(measuredHCSR_temp,5,2,txt);
oled.printStr(38,4,txt);
delay(2000);
}
1xArduino Uno
1xHC-SR04 Ultrasonic Distance Measurement Sensor
1xLM35 Temperature Sensor
1x 0.96 Inch I2C Oled Display Module
Cables and Breadboard for connections. You can see the connections if you check the code.