LCOV - code coverage report
Current view: top level - AP_RangeFinder - AP_RangeFinder_MaxsonarI2CXL.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 33 36 91.7 %
Date: 2026-09-09 11:02:08 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :    This program is free software: you can redistribute it and/or modify
       3             :    it under the terms of the GNU General Public License as published by
       4             :    the Free Software Foundation, either version 3 of the License, or
       5             :    (at your option) any later version.
       6             : 
       7             :    This program is distributed in the hope that it will be useful,
       8             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
       9             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      10             :    GNU General Public License for more details.
      11             : 
      12             :    You should have received a copy of the GNU General Public License
      13             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      14             :  */
      15             : 
      16             : /*
      17             :  *       AP_RangeFinder_MaxsonarI2CXL.cpp - Arduino Library for MaxBotix I2C XL sonar
      18             :  *       Code by Randy Mackay. DIYDrones.com
      19             :  *
      20             :  *       datasheet: http://www.maxbotix.com/documents/I2CXL-MaxSonar-EZ_Datasheet.pdf
      21             :  *
      22             :  *       Sensor should be connected to the I2C port
      23             :  */
      24             : #include "AP_RangeFinder_MaxsonarI2CXL.h"
      25             : 
      26             : #if AP_RANGEFINDER_MAXSONARI2CXL_ENABLED
      27             : 
      28             : #include <AP_HAL/AP_HAL.h>
      29             : #include <AP_HAL/utility/sparse-endian.h>
      30             : 
      31             : extern const AP_HAL::HAL& hal;
      32             : 
      33             : /*
      34             :    detect if a Maxbotix rangefinder is connected. We'll detect by
      35             :    trying to take a reading on I2C. If we get a result the sensor is
      36             :    there.
      37             : */
      38           8 : bool AP_RangeFinder_MaxsonarI2CXL::init(void)
      39             : {
      40           8 :     WITH_SEMAPHORE(dev.get_semaphore());
      41             : 
      42           8 :     if (!start_reading()) {
      43           0 :         return false;
      44             :     }
      45             : 
      46             :     // give time for the sensor to process the request
      47           8 :     hal.scheduler->delay(100);
      48             : 
      49             :     uint16_t reading_cm;
      50           8 :     if (!get_reading(reading_cm)) {
      51           0 :         return false;
      52             :     }
      53             : 
      54           8 :     dev.register_periodic_callback(100000,
      55             :                                      FUNCTOR_BIND_MEMBER(&AP_RangeFinder_MaxsonarI2CXL::_timer, void));
      56             : 
      57           8 :     return true;
      58           8 : }
      59             : 
      60             : // start_reading() - ask sensor to make a range reading - must be
      61             : // called with semaphore held
      62        4510 : bool AP_RangeFinder_MaxsonarI2CXL::start_reading()
      63             : {
      64        4510 :     uint8_t cmd = AP_RANGE_FINDER_MAXSONARI2CXL_COMMAND_TAKE_RANGE_READING;
      65             : 
      66             :     // send command to take reading
      67        4510 :     return dev.transfer(&cmd, sizeof(cmd), nullptr, 0);
      68             : }
      69             : 
      70             : // read - return last value measured by sensor
      71        4502 : bool AP_RangeFinder_MaxsonarI2CXL::get_reading(uint16_t &reading_cm)
      72             : {
      73             :     // take range reading and read back results
      74             :     be16_t val;
      75        4502 :     bool ret = dev.transfer(nullptr, 0, (uint8_t *) &val, sizeof(val));
      76             : 
      77        4502 :     if (ret) {
      78             :         // combine results into distance
      79        4502 :         reading_cm = be16toh(val);
      80             :     }
      81             : 
      82             :     // trigger a new reading
      83        4502 :     start_reading();
      84             : 
      85        4502 :     return ret;
      86             : }
      87             : 
      88             : /*
      89             :   timer called at 10Hz
      90             : */
      91        4494 : void AP_RangeFinder_MaxsonarI2CXL::_timer(void)
      92             : {
      93             :     uint16_t d;
      94        4494 :     if (get_reading(d)) {
      95        4494 :         WITH_SEMAPHORE(_sem);
      96        4494 :         distance = d;
      97        4494 :         new_distance = true;
      98        4494 :         state.last_reading_ms = AP_HAL::millis();
      99        4494 :     }
     100        4494 : }
     101             : 
     102             : /*
     103             :    update the state of the sensor
     104             : */
     105       19263 : void AP_RangeFinder_MaxsonarI2CXL::update(void)
     106             : {
     107       19263 :     WITH_SEMAPHORE(_sem);
     108       19263 :     if (new_distance) {
     109        4335 :         state.distance_m = distance * 0.01f;
     110        4335 :         new_distance = false;
     111        4335 :         update_status();
     112       14928 :     } else if (AP_HAL::millis() - state.last_reading_ms > 300) {
     113             :         // if no updates for 0.3 seconds set no-data
     114           0 :         set_status(RangeFinder::Status::NoData);
     115             :     }
     116       19263 : }
     117             : 
     118             : #endif  // AP_RANGEFINDER_MAXSONARI2CXL_ENABLED

Generated by: LCOV version 1.14