Sonar based on HC-SR04

I would like to share the results of testing a “very cheap” sonar based on HC-SR04. Earlier I added a description of using HC-SR04 for Rover. @geofrancis created a PR for use as a sonar, the forum members responded to this PR. As a result, @geofrancis shared the modified firmware(Rover 4.2).
If the vessel is just drifting, the readings correspond to reality.The results are such that when the motors are running, the readings are very unstable.
Next time I will place the sonar in the bow, removing it from the motors (and ESC) and the water flows from the screws.
If someone wants to repeat the instructions here, the only thing you need is to change the parameter "If someone wants to repeat the instructions here, the only thing you need is to change the two parameter SERVO13/14_FUNCTION = -1. In the MP there will be the parameter RNGFND_SPD_SCAL should be set to 13.44 for fresh water and 13.26 for salt water.

Special thanks to the forum members for their help - @geofrancis

My test boat :crazy_face:
During testing, I used a second sonar(Echologger ECT400) so that I could compare readings.

Log files are attached and a short Video.


What is the maximum depth you could expect from the HC-SR04? Is it 4.5m OR is that what the max would be in air? It looks like the current default is 58, and the new multiplier is 13… so that makes it closer to 1m?

Very interesting project!

58 is the default coefficient, the others are for water. the value of the maximum depth will need to be tested, I think that up to 10m should be enough power. the minimum depth is about 1.4m.

1 Like

That’s certainly very interesting! 1 to 2m of range may not be very useful in many situations but the fact that you could repurpose a regular air sonar for use in water is kind of amazing.

1 Like

@rmackay9 , 2m is just the limit of the water we have tested with so far on ardurover, im not actually sure of the maximum depth, there are videos of it going to 9+ meters.

Sound travels much further in water with the same energy due to the faster speed of sound and lack of compressibility, but the sonar is easily deafened by any local noise sources like the motors or propellers so I think it should work well when stationary, sailing or running low throttle.


It should be possible to make a lua fish finder script using sonar depth readings, the script just needs to alert for intermittent readings outside the average from the last few seconds. so if your going along with your sonar reading a constant 5m then it doesnt do anything but if you start getting intermittent readings at only 2m then chances are your getting a return from something suspended in the water like a fish.

I have received the JSN-SR20-Y1 and have been doing some testing, this is essentially a dual transducer version of the JSN-SR04T, the advantage of using dual transducers is that it doesn’t have to finish transmitting before it can receive, this means it can work at much shorter range, so far testing shows it working in as little as 15cm of water where the single transducer has a minimum range of 1.4m because it has to finish transmission before it can listen for the echos.

this could also be an ideal candidate for a plug and play solution that can be easily added to the bottom of a boat.

I 'll order for myself too )

1 Like

I have been doing some reading and apparently the accuracy of the sensors is increased dramatically in serial mode to almost millimeter precision. I think thats how it’s being done in that Russian video to get such good results.

if a serial driver was added it would make all the modern serial sr04 varients far more accurate

I opened an issue about it Serial Driver for SR04 v2 ultrasonic rangefinders · Issue #19961 · ArduPilot/ardupilot · GitHub

JSN-SR04T-2.0.pdf (348.7 KB)

I have made a lua script for testing

the idea is to setup the depth sounder as a regular SR04 then do the scaling in lua rather than the driver.

the calculated depth should show up on the status tab of mission planner.

-- height above terrain warning script

-- mindepth, script will warn if lower than this
local water_min_depth = 2

-- warning is only enabled further than this distance from home
local home_dist_enable = 1

-- must have climbed at least this distance above terrain since arming to enable warning
local height_enable = 1

-- warning repeat time in ms
local warn_ms = 10000

--ratio between speed of sound in air and water
local speed_ratio = 4.126

local height_threshold_passed = false
local last_warn = 0
function update()
  if not arming:is_armed() then
    -- not armed, nothing to do, reset height threshold
    height_threshold_passed = false
    return update, 1000

  local water_depth = rangefinder:distance_cm_orient(25) * speed_ratio (true)
  if not water_depth then
    -- could not get a valid terrain alt
    return update, 1000

  if (not height_threshold_passed) and (water_depth * 0.01 < height_enable) then
    -- not climbed far enough to enable, nothing to do
    return update, 1000
  height_threshold_passed = true

  local home_dist = ahrs:get_relative_position_NED_home()
  if home_dist then
    -- only check home dist if we have a valid home
    -- do not consider altitude above home in radius calc
    if home_dist:length() < home_dist_enable then
      -- to close to home
      return update, 1000
 gcs:send_named_float('depth', water_depth)
   if (water_depth < water_min_depth) and (vehicle:get_mode() == 10) then    -- if mode is in auto 
	vehicle:set_mode(5) --set mode to loiter
    gcs:send_text(2, string.format("Depth Warning: %0.1f meters",water_depth))
    return update, warn_ms


  return update, 1000

return update, 10000
1 Like