SharpDistSensor.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. SharpDistSensor.cpp
  3. Source: https://github.com/DrGFreeman/SharpDistSensor
  4. MIT License
  5. Copyright (c) 2018 Julien de la Bruere-Terreault <drgfreeman@tuta.io>
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in all
  13. copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. SOFTWARE.
  21. */
  22. #include <SharpDistSensor.h>
  23. /* Constructor
  24. pin: Arduino analog pin the sensor is connected to
  25. size: Window size of the median filter
  26. */
  27. SharpDistSensor::SharpDistSensor(const byte pin, const byte size) :
  28. medFilt(size, 1500)
  29. {
  30. // Arduino analog pin the sensor is connected to
  31. _pin = pin;
  32. // Window size of the median filter (1 = no filtering)
  33. _mfSize = size;
  34. // Set default sensor model to GP2Y0A60SZLF 5V
  35. setModel(GP2Y0A60SZLF_5V);
  36. }
  37. // Return the measured distance
  38. uint16_t SharpDistSensor::getDist()
  39. {
  40. // Read analog value from sensor
  41. uint16_t sensVal = analogRead(_pin);
  42. // Constrain sensor values to remain within set min-max range
  43. sensVal = constrain(sensVal, _valMin, _valMax);
  44. uint16_t dist = 0;
  45. if (_fitType == FIT_POLY)
  46. {
  47. // Calculate distance from polynomial fit function
  48. dist += _polyCoeffs[5] * pow(sensVal, 5);
  49. dist += _polyCoeffs[4] * pow(sensVal, 4);
  50. dist += _polyCoeffs[3] * pow(sensVal, 3);
  51. dist += _polyCoeffs[2] * pow(sensVal, 2);
  52. dist += _polyCoeffs[1] * sensVal;
  53. dist += _polyCoeffs[0];
  54. }
  55. else if (_fitType == FIT_POWER)
  56. {
  57. // Calculate distance from power fit function
  58. dist = _powerCoeffC * pow(sensVal, _powerCoeffP);
  59. }
  60. if (_mfSize > 1)
  61. {
  62. // Get filtered distance value
  63. dist = medFilt.in(dist);
  64. }
  65. return dist;
  66. }
  67. // Set the sensor model
  68. void SharpDistSensor::setModel(const models model)
  69. {
  70. switch (model)
  71. {
  72. case GP2Y0A60SZLF_5V:
  73. {
  74. // Set coefficients and range for Sharp GP2Y0A60SZLF 5V
  75. float coeffs[] = {1734, -9.005, 2.023E-2, -2.251E-5, 1.167E-8, -2.037E-12};
  76. setPolyFitCoeffs(6, coeffs, 30, 875);
  77. break;
  78. }
  79. case GP2Y0A710K0F_5V_DS:
  80. {
  81. // Set coefficients and range for Sharp GP2Y0A710K0F 5V
  82. float coeffs[] = {178506, -1607.72, 5.5239, -8.47601E-3, 4.87819E-6};
  83. setPolyFitCoeffs(5, coeffs, 284, 507);
  84. break;
  85. }
  86. case GP2Y0A41SK0F_5V_DS:
  87. {
  88. // Set coefficients and range for Sharp GP2Y0A41SK0F 5V
  89. float coeffs[] = {761.913, -8.13336, 4.18857E-02, -1.11338E-04, 1.46237E-07, -7.49656E-11};
  90. setPolyFitCoeffs(6, coeffs, 61, 614);
  91. break;
  92. }
  93. case GP2Y0A51SK0F_5V_DS:
  94. {
  95. // Set coefficients and range for Sharp GP2Y0A51SK0F 5V
  96. setPowerFitCoeffs(4.03576E+4, -1.26093, 70, 500);
  97. break;
  98. }
  99. }
  100. }
  101. // Set the polynomial fit function coefficients and range
  102. void SharpDistSensor::setPolyFitCoeffs(const byte nbCoeffs,
  103. const float* coeffs, const uint16_t valMin, const uint16_t valMax)
  104. {
  105. // Set fit type to FIT_POLY
  106. _fitType = FIT_POLY;
  107. // Set coefficients
  108. for (byte i = 0; i < 6; i++)
  109. {
  110. if (i < nbCoeffs)
  111. {
  112. // Coefficient is provided
  113. _polyCoeffs[i] = coeffs[i];
  114. }
  115. else
  116. {
  117. // Coefficient is not provided, set to zero
  118. _polyCoeffs[i] = 0;
  119. }
  120. }
  121. // Set analog value range
  122. setValMinMax(valMin, valMax);
  123. }
  124. // Set the power fit function coefficients and range
  125. void SharpDistSensor::setPowerFitCoeffs(const float C, const float P,
  126. const uint16_t valMin, const uint16_t valMax)
  127. {
  128. // Set fit type to FIT_POWER
  129. _fitType = FIT_POWER;
  130. // Set power fit function coefficients
  131. _powerCoeffC = C;
  132. _powerCoeffP = P;
  133. // Set analog value range
  134. setValMinMax(valMin, valMax);
  135. }
  136. // Set the analog value range for which to return a distance
  137. void SharpDistSensor::setValMinMax(const uint16_t valMin, const uint16_t valMax)
  138. {
  139. // Minimal analog value for which to return a distance
  140. _valMin = valMin;
  141. // Maximal analog value for which to return a distance
  142. _valMax = valMax;
  143. }