GY-63_MS5611/libraries/SRF05/SRF05.cpp
2024-02-10 13:14:07 +01:00

279 lines
4.7 KiB
C++

//
// FILE: SRF05.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.3.0
// DATE: 2021-05-17
// PURPOSE: Arduino library for the SRF05 distance sensor (and compatibles)
// URL: https://github.com/RobTillaart/SRF05
#include "SRF05.h"
/////////////////////////////////////////////////////
//
// CONSTRUCTORS
//
SRF05::SRF05(const uint8_t trigger, const uint8_t echo)
{
_trigger = trigger;
_echo = echo;
_mode = SRF05_MODE_SINGLE;
if (echo == 0)
{
_echo = _trigger;
}
pinMode(_trigger, OUTPUT);
digitalWrite(_trigger, LOW);
}
void SRF05::setSpeedOfSound(float speedOfSound)
{
_speedOfSound = speedOfSound;
}
float SRF05::getSpeedOfSound()
{
return _speedOfSound;
}
bool SRF05::setCorrectionFactor(float factor)
{
if (factor <= 0) return false;
_correctionFactor = factor;
return true;
}
float SRF05::getCorrectionFactor()
{
return _correctionFactor;
}
//////////////////////////////////////////////////
//
// OPERATIONAL MODE
//
void SRF05::setModeSingle()
{
_mode = SRF05_MODE_SINGLE;
_count = 1;
}
void SRF05::setModeAverage(uint8_t count)
{
_mode = SRF05_MODE_AVERAGE;
if (_count == 0) _count = 1;
_count = count;
}
void SRF05::setModeMedian(uint8_t count)
{
_mode = SRF05_MODE_MEDIAN;
_count = count;
if (_count < 3) _count = 3;
if (_count > 15) _count = 15;
}
void SRF05::setModeRunningAverage(float alpha)
{
_mode = SRF05_MODE_RUN_AVERAGE;
_count = 1;
_alpha = alpha;
}
uint8_t SRF05::getOperationalMode()
{
return _mode;
}
//////////////////////////////////////////////////
//
// MEASUREMENTS
//
uint32_t SRF05::getTime()
{
_lastTime = millis();
switch(_mode)
{
default:
case SRF05_MODE_SINGLE:
return _read();
case SRF05_MODE_AVERAGE:
{
float sum = 0;
for (uint8_t s = 0; s < _count; s++)
{
sum += _read();
delayMicroseconds(_sampleInterval);
}
return round(sum / _count);
}
case SRF05_MODE_MEDIAN:
{
uint32_t samples[15];
for (uint8_t s = 0; s < _count; s++)
{
samples[s] = _read();
delayMicroseconds(_sampleInterval);
}
_insertSort(samples, _count);
if (_count & 0x01) return samples[_count / 2];
return (samples[(_count + 1) / 2] + samples[_count / 2]) / 2;
}
case SRF05_MODE_RUN_AVERAGE:
_value = (1 - _alpha) * _value + _alpha * _read();
return _value;
}
return 0; // should not happen
}
uint32_t SRF05::getMillimeter()
{
return _speedOfSound * getTime() * 0.5e-3;
}
float SRF05::getCentimeter()
{
return _speedOfSound * getTime() * 0.5e-4;
}
float SRF05::getMeter()
{
return _speedOfSound * getTime() * 0.5e-6;
}
float SRF05::getInch()
{
return _speedOfSound * getTime() * 1.9685e-5;
}
float SRF05::getFeet()
{
return _speedOfSound * getTime() * 1.64042e-6;
}
float SRF05::getYards()
{
return _speedOfSound * getTime() * 0.54681e-6;
}
// EXPERIMENTAL
// distance in meters (single trip)
float SRF05::determineSpeedOfSound(float distance, uint8_t count)
{
float sum = 0;
if (count == 0) count = 1;
while (count--)
{
sum += _read();
delayMicroseconds(_sampleInterval);
}
// sos = distance travelled forth and back in micrometer
// divided by time in microseconds.
float sos = (count * distance * 2e6) / sum;
return sos;
}
void SRF05::setTriggerLength(uint8_t length)
{
_triggerLength = length;
}
uint8_t SRF05::getTriggerLength()
{
return _triggerLength;
}
uint32_t SRF05::lastTime()
{
return _lastTime;
}
float SRF05::calculateSpeedOfSound(float temperature, float humidity)
{
// interpolate
// 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;
}
//////////////////////////////////////////////////
//
// PRIVATE
//
uint32_t SRF05::_read()
{
// Send pulse
pinMode(_trigger, OUTPUT);
digitalWrite(_trigger, HIGH);
delayMicroseconds(_triggerLength);
digitalWrite(_trigger, LOW);
// Wait for echo
pinMode(_echo, INPUT);
uint32_t duration = pulseIn(_echo, HIGH, 200000); // was 300000 (50+ meter)
if (_correctionFactor == 1.0)
{
return duration;
}
return round(duration * _correctionFactor);
}
// for median
void SRF05::_insertSort(uint32_t * array, uint8_t size)
{
uint8_t t, z;
uint32_t temp;
for (t = 1; t < size; t++)
{
z = t;
temp = array[z];
while( (z > 0) && (temp < array[z - 1] ))
{
array[z] = array[z - 1];
z--;
}
array[z] = temp;
yield();
}
}
// -- END OF FILE --