0.3.0 SRF05

This commit is contained in:
Rob Tillaart 2024-02-10 13:14:07 +01:00
parent ed5c6c6d1d
commit 3200ea3e98
8 changed files with 186 additions and 68 deletions

View File

@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.3.0] - 2024-02-08
- add support for single pin operation (echo == trigger) Kudos to RobertPHeller!
- add **float getYards()** wrapper.
- add **void setSampleInterval(uint16_t microSeconds = 1000)** (for average & median)
- add **uint16_t getSampleInterval()**
- reduced pulseIn timeout to 200000 (30+ meter)
- minor edits.
----
## [0.2.0] - 2024-01-28 ## [0.2.0] - 2024-01-28
- add **float calculateSpeedOfSound(float temperature, float humidity)** - add **float calculateSpeedOfSound(float temperature, float humidity)**
- redo lookup table SOS temperature humidity - redo lookup table SOS temperature humidity
@ -44,7 +54,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- minor edits - minor edits
## [0.1.1] - 2021-11-18 ## [0.1.1] - 2021-11-18
- update build-CI, - update build-CI
- update readme.md - update readme.md
- minor edits - minor edits

View File

@ -18,15 +18,19 @@ Arduino library for the SRF05 distance sensor and compatibles.
This library implements a API for a PING type of sensor. This library implements a API for a PING type of sensor.
It is expected to work for quite a range of them. It is expected to work for quite a range of them.
THe current version of the library only uses the SRF04 compatibility mode which uses a Till version 0.2.0 of the library, it only supported the SRF04 compatibility mode which uses a
separate TRIGGER and ECHO pin. separate **TRIGGER** and **ECHO** pin.
It does not (yet) implement the SRF05 mode in which TRIGGER and ECHO are the same.
An important feature of this library is that it allows to adjust to the speed of sound (SOS). Version 0.3.0 implements support for the SRF05 mode in which **TRIGGER** and **ECHO** are the same.
One need to connect the MODE pin to GND to select this mode in the device.
Note that not all PING type of sensors will support the single pin mode.
See also Connection section below.
An important feature of this library is that it allows to adjust the speed of sound (SOS).
Reasons to use a different value for the speed of sound is that it varies depending on Reasons to use a different value for the speed of sound is that it varies depending on
temperature, humidity, composition of the air, air pressure, other type of gas, etc. temperature, humidity, composition of the air, air pressure, other type of gas, etc.
Default value for the speed of sound is set to 340 m/s. (air, ~15°C, sea level pressure) Default value for the speed of sound is set to **340 m/s**. (air, ~15°C, sea level pressure)
Since the version 0.2.0 the library has an interpolation formula to calculate the speed of sound Since the version 0.2.0 the library has an interpolation formula to calculate the speed of sound
given a temperature and humidity. given a temperature and humidity.
@ -40,6 +44,12 @@ the **pulseIn()** function. This has in the end the same effect as changing the
speed of sound however it is technically more correct to keep the two separated. speed of sound however it is technically more correct to keep the two separated.
#### Connection
How to connect:
- https://www.robot-electronics.co.uk/htm/srf05tech.htm
#### Effect temperature and humidity #### Effect temperature and humidity
Several correction formulas for the speed of sound are available on the internet Several correction formulas for the speed of sound are available on the internet
@ -64,7 +74,7 @@ and wind speed. The latter is a bit compensated for, as the acoustic pulse will
(table redone completely in 0.2.0) (table redone completely in 0.2.0)
Temperature in Celsius, Humidity in %, constant pressure == 1013 mBar. Temperature in Celsius, Humidity in %, constant pressure == 1013 mBar, SOS in m/s.
| temp | 0% | 10% | 20% | 30% | 40% | 50% | 60% | 70% | 80% | 90% | 100% | | temp | 0% | 10% | 20% | 30% | 40% | 50% | 60% | 70% | 80% | 90% | 100% |
|:----:|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:| |:----:|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:|
@ -107,6 +117,11 @@ This function returns a speed of sound with an overall error margin less than 1%
lower than 0.5% compared to the numbers above. lower than 0.5% compared to the numbers above.
#### Related
- https://www.robot-electronics.co.uk/htm/srf05tech.htm (good description of the sensor)
## Interface ## Interface
```cpp ```cpp
@ -115,36 +130,49 @@ lower than 0.5% compared to the numbers above.
#### Constructor #### Constructor
- **SRF05(const uint8_t trigger, const uint8_t echo, const uint8_t out = 0)** constructor to set the trigger and echo pin. - **SRF05(const uint8_t trigger, const uint8_t echo = 0)** constructor to set the trigger and echo pin.
It is not clear what the purpose of the OUT pin is, effectively it is not used yet. The echo pin can be left out, or set to the same as the trigger pin.
In total one can do it in three ways.
```cpp
const int trigger = 7;
const int echo = trigger;
SRF05 SRF(trigger, echo);
SRF05 SRF(trigger, trigger);
SRF05 SRF(trigger);
```
To select single pin mode in the hardware the MODE pin of the device must be connected to GND.
For the two pin (compatibility) mode the MODE pin must be left floating.
#### Configuration #### Configuration
- **void setSpeedOfSound(float sos)** adjust the speed of sound in meters per second (m/s). - **void setSpeedOfSound(float sos = 340)** adjust the speed of sound in meters per second (m/s).
See table above. See table above.
The function has **no range check** and accepts even negative values. The function has **no range check** and accepts even negative values.
This will cause a negative sign in the distances which can be handy sometimes when you have This will cause a negative sign in the distances which can be useful sometimes when you have
two sensors in opposite directions. two sensors in opposite directions.
- **float getSpeedOfSound()** return set value (m/s) - **float getSpeedOfSound()** return set value (m/s)
- **bool setCorrectionFactor(float factor = 1)** adjust the timing by a few percentage e.g. to adjust clocks. - **bool setCorrectionFactor(float factor = 1)** adjust the timing by a few percentage e.g. to adjust clocks.
Typical values are between 0.95 and 1.05 to correct up to 5%. Typical values are between 0.95 and 1.05 to correct up to 5%.
Should not be used to correct the speed of sound :) Should not be used to correct the speed of sound :)
Returns false if factor <= 0. Returns false if factor is negative, <= 0.
- **float getCorrectionFactor()** returns the current correction factor. - **float getCorrectionFactor()** returns the current correction factor.
#### Operational mode #### Operational mode
Normally a single read should be OK. Normally a single read should be sufficient, but the library has more modi.
- **void setModeSingle()** read a single time. - **void setModeSingle()** read a single time.
This is the default and typical the fastest. This is the default and typical the fastest.
- **void setModeAverage(uint8_t count)** read count times and take the average. - **void setModeAverage(uint8_t count)** read count times and take the average.
Note: between the reads there is a delay of 1 millisecond. Note: between the reads there is a default delay of 1000 microseconds.
- **void setModeMedian(uint8_t count)** read count times and take the median. - **void setModeMedian(uint8_t count)** read count times and take the median.
count must between 3 and 15 otherwise it is clipped. count must between 3 and 15 otherwise it is clipped.
Note: between the reads there is a delay of 1 millisecond. Note: between the reads there is a default delay of 1000 microseconds.
- **void setModeRunningAverage(float alpha)** use a running average algorithm - **void setModeRunningAverage(float alpha)** use a running average algorithm
with a weight alpha. Value for alpha depends on your application. with a weight alpha. Value for alpha depends on your application.
Alpha must be larger than zero and smaller or equal to one. Alpha == <0..1] Alpha must be larger than zero and smaller or equal to one. Alpha == <0..1]
@ -152,15 +180,18 @@ Lower alpha averages great for static distances, a higher alpha is better
suited for changing distances. suited for changing distances.
- **uint8_t getOperationalMode()** returns the operational mode 0..3. - **uint8_t getOperationalMode()** returns the operational mode 0..3.
See table below. See table below.
- **void setSampleInterval(uint16_t microSeconds = 1000)** changes the interval used
in **SRF05_MODE_AVERAGE** and **SRF05_MODE_MEDIAN**.
Default is 1000 us == 1 milliSecond. Maximum is 65535 microseconds.
- **uint16_t getSampleInterval()** return set interval.
| Operational mode | Value | Notes | | Operational mode | Value | Notes |
|:-------------------------|:-------:|:-------:| |:-------------------------|:-------:|:-------:|
| SRF05_MODE_SINGLE | 0 | | | SRF05_MODE_SINGLE | 0 |
| SRF05_MODE_AVERAGE | 1 | | | SRF05_MODE_AVERAGE | 1 | default sample interval 1000 us
| SRF05_MODE_MEDIAN | 2 | | | SRF05_MODE_MEDIAN | 2 | default sample interval 1000 us
| SRF05_MODE_RUN_AVERAGE | 3 | | | SRF05_MODE_RUN_AVERAGE | 3 |
| | other | error | | | other | error
If other modi are needed, please open an issue and I see if it fits. If other modi are needed, please open an issue and I see if it fits.
Of course one can create more elaborated processing of measurements Of course one can create more elaborated processing of measurements
@ -177,6 +208,7 @@ around this one.
- **float getMeter()** returns distance in meter. - **float getMeter()** returns distance in meter.
- **float getInch()** returns distance in inches. (1 inch = 2.54 cm). - **float getInch()** returns distance in inches. (1 inch = 2.54 cm).
- **float getFeet()** returns distance in feet. (1 feet = 12 inch). - **float getFeet()** returns distance in feet. (1 feet = 12 inch).
- **float getYards()** returns distance in yards. (1 yard = 3 feet = 36 inch).
#### Experimental - setTriggerLength #### Experimental - setTriggerLength
@ -262,10 +294,7 @@ See examples.
- DHT22 and the formula for SOS - DHT22 and the formula for SOS
- investigate effect of wind (speed of air) on the speed of sound. - investigate effect of wind (speed of air) on the speed of sound.
- investigate - investigate
- should **setSpeedOfSound(float sos)** return bool if sos <=0 ?
- value of **setTriggerLength()** - value of **setTriggerLength()**
- investigate switching between single pin (SRF05) mode and dual pin (SRF04) mode.
- need a separate constructor.
- investigate "guard time" between reads of 50 ms (20x /sec max). - investigate "guard time" between reads of 50 ms (20x /sec max).
@ -274,12 +303,16 @@ See examples.
- set default SOS to an SOS from the table instead of 340. - set default SOS to an SOS from the table instead of 340.
- function **begin(T, H)** ? - function **begin(T, H)** ?
- add example to determine the correction factor? - add example to determine the correction factor?
- delay(1) in average configurable? - add uint16_t **PulseTimeOut** = 200; // milliSeconds?
- void setPulseTimeOut(uint16_t milliSeconds = 200);
- uint16_t getPulseTimeOut();
#### Wont #### Wont
- should **setSpeedOfSound(float sos)** return bool if sos <=0 ?
- print feet as 3'2" or 3-7/8 feet (is that needed in this lib) - print feet as 3'2" or 3-7/8 feet (is that needed in this lib)
- in printHelpers ? - see printHelpers lib **printFeet(float feet)**
- fix magic conversion numbers. - fix magic conversion numbers.
- add ```float lastValue()``` ? - add ```float lastValue()``` ?
- not all paths update this variable. - not all paths update this variable.

View File

@ -1,7 +1,7 @@
// //
// FILE: SRF05.cpp // FILE: SRF05.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.2.0 // VERSION: 0.3.0
// DATE: 2021-05-17 // DATE: 2021-05-17
// PURPOSE: Arduino library for the SRF05 distance sensor (and compatibles) // PURPOSE: Arduino library for the SRF05 distance sensor (and compatibles)
// URL: https://github.com/RobTillaart/SRF05 // URL: https://github.com/RobTillaart/SRF05
@ -19,10 +19,12 @@ SRF05::SRF05(const uint8_t trigger, const uint8_t echo)
_trigger = trigger; _trigger = trigger;
_echo = echo; _echo = echo;
_mode = SRF05_MODE_SINGLE; _mode = SRF05_MODE_SINGLE;
if (echo == 0)
{
_echo = _trigger;
}
pinMode(_trigger, OUTPUT); pinMode(_trigger, OUTPUT);
digitalWrite(_trigger, LOW); digitalWrite(_trigger, LOW);
pinMode(_echo, INPUT);
} }
@ -31,6 +33,7 @@ void SRF05::setSpeedOfSound(float speedOfSound)
_speedOfSound = speedOfSound; _speedOfSound = speedOfSound;
} }
float SRF05::getSpeedOfSound() float SRF05::getSpeedOfSound()
{ {
return _speedOfSound; return _speedOfSound;
@ -42,13 +45,13 @@ bool SRF05::setCorrectionFactor(float factor)
if (factor <= 0) return false; if (factor <= 0) return false;
_correctionFactor = factor; _correctionFactor = factor;
return true; return true;
}; }
float SRF05::getCorrectionFactor() float SRF05::getCorrectionFactor()
{ {
return _correctionFactor; return _correctionFactor;
}; }
////////////////////////////////////////////////// //////////////////////////////////////////////////
@ -81,7 +84,6 @@ void SRF05::setModeMedian(uint8_t count)
void SRF05::setModeRunningAverage(float alpha) void SRF05::setModeRunningAverage(float alpha)
{ {
_mode = SRF05_MODE_RUN_AVERAGE; _mode = SRF05_MODE_RUN_AVERAGE;
_count = 1; _count = 1;
_alpha = alpha; _alpha = alpha;
@ -114,7 +116,7 @@ uint32_t SRF05::getTime()
for (uint8_t s = 0; s < _count; s++) for (uint8_t s = 0; s < _count; s++)
{ {
sum += _read(); sum += _read();
delay(1); delayMicroseconds(_sampleInterval);
} }
return round(sum / _count); return round(sum / _count);
} }
@ -125,7 +127,7 @@ uint32_t SRF05::getTime()
for (uint8_t s = 0; s < _count; s++) for (uint8_t s = 0; s < _count; s++)
{ {
samples[s] = _read(); samples[s] = _read();
delay(1); delayMicroseconds(_sampleInterval);
} }
_insertSort(samples, _count); _insertSort(samples, _count);
if (_count & 0x01) return samples[_count / 2]; if (_count & 0x01) return samples[_count / 2];
@ -170,6 +172,12 @@ float SRF05::getFeet()
} }
float SRF05::getYards()
{
return _speedOfSound * getTime() * 0.54681e-6;
}
// EXPERIMENTAL // EXPERIMENTAL
// distance in meters (single trip) // distance in meters (single trip)
float SRF05::determineSpeedOfSound(float distance, uint8_t count) float SRF05::determineSpeedOfSound(float distance, uint8_t count)
@ -179,7 +187,7 @@ float SRF05::determineSpeedOfSound(float distance, uint8_t count)
while (count--) while (count--)
{ {
sum += _read(); sum += _read();
delay(1); delayMicroseconds(_sampleInterval);
} }
// sos = distance travelled forth and back in micrometer // sos = distance travelled forth and back in micrometer
// divided by time in microseconds. // divided by time in microseconds.
@ -229,11 +237,16 @@ float SRF05::calculateSpeedOfSound(float temperature, float humidity)
// //
uint32_t SRF05::_read() uint32_t SRF05::_read()
{ {
// Send pulse
pinMode(_trigger, OUTPUT);
digitalWrite(_trigger, HIGH); digitalWrite(_trigger, HIGH);
delayMicroseconds(_triggerLength); delayMicroseconds(_triggerLength);
digitalWrite(_trigger, LOW); digitalWrite(_trigger, LOW);
uint32_t duration = pulseIn(_echo, HIGH, 300000);
if (_correctionFactor == 1) // Wait for echo
pinMode(_echo, INPUT);
uint32_t duration = pulseIn(_echo, HIGH, 200000); // was 300000 (50+ meter)
if (_correctionFactor == 1.0)
{ {
return duration; return duration;
} }
@ -241,6 +254,7 @@ uint32_t SRF05::_read()
} }
// for median
void SRF05::_insertSort(uint32_t * array, uint8_t size) void SRF05::_insertSort(uint32_t * array, uint8_t size)
{ {
uint8_t t, z; uint8_t t, z;
@ -260,5 +274,5 @@ void SRF05::_insertSort(uint32_t * array, uint8_t size)
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -2,7 +2,7 @@
// //
// FILE: SRF05.h // FILE: SRF05.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.2.0 // VERSION: 0.3.0
// DATE: 2021-05-17 // DATE: 2021-05-17
// PURPOSE: Arduino library for SRF05 distance sensor // PURPOSE: Arduino library for SRF05 distance sensor
// URL: https://github.com/RobTillaart/SRF05 // URL: https://github.com/RobTillaart/SRF05
@ -10,7 +10,7 @@
#include "Arduino.h" #include "Arduino.h"
#define SRF05_LIB_VERSION (F("0.2.0")) #define SRF05_LIB_VERSION (F("0.3.0"))
const uint8_t SRF05_MODE_SINGLE = 0; const uint8_t SRF05_MODE_SINGLE = 0;
@ -22,7 +22,7 @@ const uint8_t SRF05_MODE_RUN_AVERAGE = 3;
class SRF05 class SRF05
{ {
public: public:
explicit SRF05(const uint8_t trigger, const uint8_t echo); explicit SRF05(const uint8_t trigger, const uint8_t echo = 0);
// configuration // configuration
@ -40,6 +40,9 @@ public:
void setModeMedian(uint8_t count); void setModeMedian(uint8_t count);
void setModeRunningAverage(float alpha); void setModeRunningAverage(float alpha);
uint8_t getOperationalMode(); uint8_t getOperationalMode();
// interval of average and median mode
void setSampleInterval(uint16_t microSeconds = 1000);
uint16_t getSampleInterval();
// get distance // get distance
@ -49,6 +52,7 @@ public:
float getMeter(); // m float getMeter(); // m
float getInch(); // inch = 2.54 cm float getInch(); // inch = 2.54 cm
float getFeet(); // feet = 12 inch float getFeet(); // feet = 12 inch
float getYards(); // yard = 3 feet = 36 inch
// Experimental - calibration // Experimental - calibration
@ -66,6 +70,7 @@ public:
void setTriggerLength(uint8_t length = 10); void setTriggerLength(uint8_t length = 10);
uint8_t getTriggerLength(); uint8_t getTriggerLength();
// TIMING // TIMING
uint32_t lastTime(); uint32_t lastTime();
@ -83,9 +88,11 @@ private:
float _alpha = 1.0; float _alpha = 1.0;
float _value = 0; float _value = 0;
float _correctionFactor = 1; float _correctionFactor = 1;
uint8_t _triggerLength = 10; uint8_t _triggerLength = 10; // microSeconds
float _speedOfSound = 340; // 15°C 0%RH Sea level float _speedOfSound = 340; // 15°C 0%RH Sea level
uint32_t _lastTime = 0; uint32_t _lastTime = 0;
uint16_t _sampleInterval = 1000; // microSeconds
uint32_t _read(); uint32_t _read();
void _insertSort(uint32_t * array, uint8_t size); void _insertSort(uint32_t * array, uint8_t size);

View File

@ -0,0 +1,49 @@
//
// FILE: SRF05_demo_single_pin.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo distance sensor
// URL: https://github.com/RobTillaart/SRF05
#include "SRF05.h"
const int trigger = 7;
const int echo = trigger;
// SRF05 SRF(trigger, echo); // alternative
// SRF05 SRF(trigger, trigger); // alternative
SRF05 SRF(trigger);
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println(__FILE__);
Serial.print("SRF05_LIB_VERSION: ");
Serial.println(SRF05_LIB_VERSION);
Serial.println();
SRF.setCorrectionFactor(1.035);
}
void loop()
{
Serial.println(SRF.getTime());
delay(100);
Serial.println(SRF.getMillimeter());
delay(100);
Serial.println(SRF.getCentimeter(), 1);
delay(100);
Serial.println(SRF.getMeter(), 2);
delay(100);
Serial.println(SRF.getInch(), 1);
delay(100);
Serial.println(SRF.getFeet(), 2);
delay(1000);
Serial.println();
}
// -- END OF FILE --

View File

@ -17,14 +17,19 @@ setModeMedian KEYWORD2
setModeRunningAverage KEYWORD2 setModeRunningAverage KEYWORD2
getOperationalMode KEYWORD2 getOperationalMode KEYWORD2
setSampleInterval KEYWORD2
getSampleInterval KEYWORD2
getTime KEYWORD2 getTime KEYWORD2
getMillimeter KEYWORD2 getMillimeter KEYWORD2
getCentimeter KEYWORD2 getCentimeter KEYWORD2
getMeter KEYWORD2 getMeter KEYWORD2
getInch KEYWORD2 getInch KEYWORD2
getFeet KEYWORD2 getFeet KEYWORD2
getYards KEYWORD2
determineSpeedOfSound KEYWORD2 determineSpeedOfSound KEYWORD2
setTriggerLength KEYWORD2 setTriggerLength KEYWORD2
getTriggerLength KEYWORD2 getTriggerLength KEYWORD2

View File

@ -15,7 +15,7 @@
"type": "git", "type": "git",
"url": "https://github.com/RobTillaart/SRF05.git" "url": "https://github.com/RobTillaart/SRF05.git"
}, },
"version": "0.2.0", "version": "0.3.0",
"license": "MIT", "license": "MIT",
"frameworks": "*", "frameworks": "*",
"platforms": "*", "platforms": "*",

View File

@ -1,5 +1,5 @@
name=SRF05 name=SRF05
version=0.2.0 version=0.3.0
author=Rob Tillaart <rob.tillaart@gmail.com> author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com> maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for SRF05 distance sensor sentence=Arduino library for SRF05 distance sensor