GY-63_MS5611/libraries/SRF05/SRF05.cpp

279 lines
4.7 KiB
C++
Raw Normal View History

2021-05-26 05:31:36 -04:00
//
// FILE: SRF05.cpp
// AUTHOR: Rob Tillaart
2024-02-10 07:14:07 -05:00
// VERSION: 0.3.0
2021-05-26 05:31:36 -04:00
// DATE: 2021-05-17
// PURPOSE: Arduino library for the SRF05 distance sensor (and compatibles)
// URL: https://github.com/RobTillaart/SRF05
#include "SRF05.h"
/////////////////////////////////////////////////////
//
2022-11-25 13:11:37 -05:00
// CONSTRUCTORS
2021-05-26 05:31:36 -04:00
//
2024-01-30 04:29:00 -05:00
SRF05::SRF05(const uint8_t trigger, const uint8_t echo)
2021-05-26 05:31:36 -04:00
{
_trigger = trigger;
_echo = echo;
2024-01-30 04:29:00 -05:00
_mode = SRF05_MODE_SINGLE;
2024-02-10 07:14:07 -05:00
if (echo == 0)
{
_echo = _trigger;
}
2021-05-26 05:31:36 -04:00
pinMode(_trigger, OUTPUT);
digitalWrite(_trigger, LOW);
}
2024-01-30 04:29:00 -05:00
void SRF05::setSpeedOfSound(float speedOfSound)
2021-05-26 05:31:36 -04:00
{
2024-01-30 04:29:00 -05:00
_speedOfSound = speedOfSound;
2021-05-26 05:31:36 -04:00
}
2024-02-10 07:14:07 -05:00
2021-05-26 05:31:36 -04:00
float SRF05::getSpeedOfSound()
{
return _speedOfSound;
}
2023-03-16 06:50:16 -04:00
bool SRF05::setCorrectionFactor(float factor)
2022-11-25 13:11:37 -05:00
{
2023-03-16 06:50:16 -04:00
if (factor <= 0) return false;
2022-11-25 13:11:37 -05:00
_correctionFactor = factor;
2023-03-16 06:50:16 -04:00
return true;
2024-02-10 07:14:07 -05:00
}
2022-11-25 13:11:37 -05:00
float SRF05::getCorrectionFactor()
{
return _correctionFactor;
2024-02-10 07:14:07 -05:00
}
2022-11-25 13:11:37 -05:00
//////////////////////////////////////////////////
//
2023-03-16 06:50:16 -04:00
// OPERATIONAL MODE
2022-11-25 13:11:37 -05:00
//
2021-05-26 05:31:36 -04:00
void SRF05::setModeSingle()
{
2023-03-16 06:50:16 -04:00
_mode = SRF05_MODE_SINGLE;
2021-11-18 07:52:59 -05:00
_count = 1;
2021-05-26 05:31:36 -04:00
}
2021-11-18 07:52:59 -05:00
void SRF05::setModeAverage(uint8_t count)
2021-05-26 05:31:36 -04:00
{
2024-01-30 04:29:00 -05:00
_mode = SRF05_MODE_AVERAGE;
2023-03-16 06:50:16 -04:00
if (_count == 0) _count = 1;
2021-11-18 07:52:59 -05:00
_count = count;
2021-05-26 05:31:36 -04:00
}
2021-11-18 07:52:59 -05:00
void SRF05::setModeMedian(uint8_t count)
2021-05-26 05:31:36 -04:00
{
2023-03-16 06:50:16 -04:00
_mode = SRF05_MODE_MEDIAN;
2021-11-18 07:52:59 -05:00
_count = count;
if (_count < 3) _count = 3;
if (_count > 15) _count = 15;
2021-05-26 05:31:36 -04:00
}
2021-11-18 07:52:59 -05:00
2021-05-26 05:31:36 -04:00
void SRF05::setModeRunningAverage(float alpha)
{
2023-03-16 06:50:16 -04:00
_mode = SRF05_MODE_RUN_AVERAGE;
2021-11-18 07:52:59 -05:00
_count = 1;
2021-05-26 05:31:36 -04:00
_alpha = alpha;
}
2021-11-18 07:52:59 -05:00
2021-05-26 05:31:36 -04:00
uint8_t SRF05::getOperationalMode()
{
return _mode;
}
2021-11-18 07:52:59 -05:00
2021-05-26 05:31:36 -04:00
//////////////////////////////////////////////////
2022-11-25 13:11:37 -05:00
//
// MEASUREMENTS
//
2021-05-26 05:31:36 -04:00
uint32_t SRF05::getTime()
{
2023-03-16 06:50:16 -04:00
_lastTime = millis();
2021-05-26 05:31:36 -04:00
switch(_mode)
{
default:
2023-03-16 06:50:16 -04:00
case SRF05_MODE_SINGLE:
2021-05-26 05:31:36 -04:00
return _read();
2023-03-16 06:50:16 -04:00
case SRF05_MODE_AVERAGE:
2021-05-26 05:31:36 -04:00
{
float sum = 0;
2021-11-18 07:52:59 -05:00
for (uint8_t s = 0; s < _count; s++)
2021-05-26 05:31:36 -04:00
{
sum += _read();
2024-02-10 07:14:07 -05:00
delayMicroseconds(_sampleInterval);
2021-05-26 05:31:36 -04:00
}
2021-11-18 07:52:59 -05:00
return round(sum / _count);
2021-05-26 05:31:36 -04:00
}
2023-03-16 06:50:16 -04:00
case SRF05_MODE_MEDIAN:
2021-05-26 05:31:36 -04:00
{
uint32_t samples[15];
2021-11-18 07:52:59 -05:00
for (uint8_t s = 0; s < _count; s++)
2021-05-26 05:31:36 -04:00
{
samples[s] = _read();
2024-02-10 07:14:07 -05:00
delayMicroseconds(_sampleInterval);
2021-05-26 05:31:36 -04:00
}
2021-11-18 07:52:59 -05:00
_insertSort(samples, _count);
if (_count & 0x01) return samples[_count / 2];
return (samples[(_count + 1) / 2] + samples[_count / 2]) / 2;
2021-05-26 05:31:36 -04:00
}
2023-03-16 06:50:16 -04:00
case SRF05_MODE_RUN_AVERAGE:
2021-11-18 07:52:59 -05:00
_value = (1 - _alpha) * _value + _alpha * _read();
return _value;
2021-05-26 05:31:36 -04:00
}
2024-01-30 04:29:00 -05:00
return 0; // should not happen
2021-05-26 05:31:36 -04:00
}
uint32_t SRF05::getMillimeter()
{
return _speedOfSound * getTime() * 0.5e-3;
}
2021-11-18 07:52:59 -05:00
2021-05-26 05:31:36 -04:00
float SRF05::getCentimeter()
{
return _speedOfSound * getTime() * 0.5e-4;
}
2021-11-18 07:52:59 -05:00
2021-05-26 05:31:36 -04:00
float SRF05::getMeter()
{
return _speedOfSound * getTime() * 0.5e-6;
}
2021-11-18 07:52:59 -05:00
2021-05-26 05:31:36 -04:00
float SRF05::getInch()
{
return _speedOfSound * getTime() * 1.9685e-5;
}
2021-11-18 07:52:59 -05:00
2021-05-26 05:31:36 -04:00
float SRF05::getFeet()
{
return _speedOfSound * getTime() * 1.64042e-6;
}
2024-02-10 07:14:07 -05:00
float SRF05::getYards()
{
return _speedOfSound * getTime() * 0.54681e-6;
}
2023-03-16 06:50:16 -04:00
// EXPERIMENTAL
2024-01-30 04:29:00 -05:00
// distance in meters (single trip)
float SRF05::determineSpeedOfSound(float distance, uint8_t count)
2021-05-26 05:31:36 -04:00
{
float sum = 0;
2024-01-30 04:29:00 -05:00
if (count == 0) count = 1;
while (count--)
2021-05-26 05:31:36 -04:00
{
sum += _read();
2024-02-10 07:14:07 -05:00
delayMicroseconds(_sampleInterval);
2021-05-26 05:31:36 -04:00
}
2024-02-10 07:14:07 -05:00
// sos = distance travelled forth and back in micrometer
2024-01-30 04:29:00 -05:00
// divided by time in microseconds.
float sos = (count * distance * 2e6) / sum;
2021-05-26 05:31:36 -04:00
return sos;
}
2023-03-16 06:50:16 -04:00
void SRF05::setTriggerLength(uint8_t length)
{
_triggerLength = length;
}
uint8_t SRF05::getTriggerLength()
{
return _triggerLength;
}
uint32_t SRF05::lastTime()
{
return _lastTime;
}
2024-01-30 04:29:00 -05:00
float SRF05::calculateSpeedOfSound(float temperature, float humidity)
{
2024-02-10 07:14:07 -05:00
// interpolate
2024-01-30 04:29:00 -05:00
// column RNH = 0%, from formula.
float sos = 331.45 * sqrt(1 + temperature/273.15);
// column RH = 100%, interpolation from spreadsheet
float sos_100 = 332.392083694084 + 0.683791630591631 * temperature;
// interpolate the humidity between these 2
if (humidity > 0)
{
sos += (sos_100 - sos) * humidity * 0.01;
}
return sos;
}
2021-05-26 05:31:36 -04:00
//////////////////////////////////////////////////
//
2023-03-16 06:50:16 -04:00
// PRIVATE
2021-05-26 05:31:36 -04:00
//
uint32_t SRF05::_read()
{
2024-02-10 07:14:07 -05:00
// Send pulse
pinMode(_trigger, OUTPUT);
2021-05-26 05:31:36 -04:00
digitalWrite(_trigger, HIGH);
delayMicroseconds(_triggerLength);
digitalWrite(_trigger, LOW);
2024-02-10 07:14:07 -05:00
// Wait for echo
pinMode(_echo, INPUT);
uint32_t duration = pulseIn(_echo, HIGH, 200000); // was 300000 (50+ meter)
if (_correctionFactor == 1.0)
2021-05-26 05:31:36 -04:00
{
return duration;
}
return round(duration * _correctionFactor);
}
2024-02-10 07:14:07 -05:00
// for median
2021-05-26 05:31:36 -04:00
void SRF05::_insertSort(uint32_t * array, uint8_t size)
{
uint8_t t, z;
uint32_t temp;
2022-11-25 13:11:37 -05:00
for (t = 1; t < size; t++)
2021-05-26 05:31:36 -04:00
{
z = t;
temp = array[z];
2022-11-25 13:11:37 -05:00
while( (z > 0) && (temp < array[z - 1] ))
2021-05-26 05:31:36 -04:00
{
array[z] = array[z - 1];
z--;
}
array[z] = temp;
yield();
}
}
2024-02-10 07:14:07 -05:00
// -- END OF FILE --
2021-11-18 07:52:59 -05:00