OK I have hit the jackpot! I finally found the SR04 to i2c code that I knew existed out in the wild. this gives us 2 things, the ability to scale the rangefinder to work in water and the ability to run multiple rangefinders without using lots of gpio, I have edited this version to multiply the range so it shows up correctly when in water. its not as fast or accurate as serial mode but because the scaling is done before it gets to the flight controller it means it can be used for proximity and not just alarms.
yes having it on i2c opens up a lot of options, im adding another 3 under my boat looking forward left and right so I have underwater proximity alerts. you just need to change the i2c address in the arduino sketch to get around address conflicts, I have tested it running 2 so far without issue.
In order to read the sensor at maximum speed you would need read the serial stream directly from the sonar its self. currently there is no native serial driver but this is a serial lua driver that @Yuri_Rage created. its very fast but because the rangefinder is being read into lua but there is currently no lua binding for a rangefinder so it can only work within lua for actions and sending alerts and values it wont work with avoidance or anything like that currently.
local SCRIPT_NAME = 'Depthfinder'
local MAV_DEPTH_LABEL = 'DEPTH'
local BOOT_DELAY_MS = 2000
local RUN_INTERVAL_MS = 50
local SERIAL_PORT = 0
local BAUD_RATE = 9600
local FRAME_SIZE = 4
local SPEED_RATIO = 4.126
local INVALID_DEPTH = -1
local MAV_SEVERITY_WARNING = 4
local MAV_SEVERITY_INFO = 6
local port = serial:find_serial(SERIAL_PORT)
port:begin(BAUD_RATE)
port:set_flow_control(0)
local function serial_flush(bytes)
for i = 0, bytes - 1 do
port:read()
end
end
function update()
local bytes_available = port:available():toint()
if bytes_available ~= FRAME_SIZE then
serial_flush(bytes_available)
gcs:send_named_float(MAV_DEPTH_LABEL, INVALID_DEPTH)
return update, RUN_INTERVAL_MS
end
local data = 0
for i = 0, bytes_available - 1 do
data = data << 8 | port:read()
end
local sum = data & 0xFF
local l_data = data >> 8 & 0xFF
local h_data = data >> 16 & 0xFF
if (0xFF + h_data + l_data) & 0xFF ~= sum then
gcs:send_text(MAV_SEVERITY_WARNING,
string.format('%s: Bad checksum', SCRIPT_NAME))
gcs:send_named_float(MAV_DEPTH_LABEL, INVALID_DEPTH)
return update, RUN_INTERVAL_MS
end
local depth_raw = h_data << 8 | l_data
--gcs:send_named_float('RAW', depth_raw)
gcs:send_named_float(MAV_DEPTH_LABEL, depth_raw * SPEED_RATIO * 0.001)
return update, RUN_INTERVAL_MS
end
gcs:send_text(MAV_SEVERITY_INFO, string.format('%s: Script Active', SCRIPT_NAME))
return update, BOOT_DELAY_MS
I have been busy, I wasnt happy with the arduino converter as it was still getting read as a Sr04 rangefinder without all the benefits of serial mode. so this is my latest creation, Using the TFmini>maxbotix i2c adapter @ppoirier made as a start I copied in the serial sonar code from an example script i found and now its working!
I have made another version of the serial i2c adapter that should work with the rangefinder in mode 1 and mode 2, so its only pinging if requested rather than every 100ms. it should give more stable returns as it will be going through all the rangefinders sequentially rather than them all pinging constantly.
latest version is fully operational with averaging and mode selection