I found this http://www.esp8266.com/viewtopic.php?f=23&t=9341&start=8 to work successfully. However, I don't really understand what is going on. When I tried to implement my own version, my results are all over the place.
In my version, I want to just get one result from the sensor, as opposed to the averaging of results in the example. I don't understand why my one result is always so far off and inconsistent.
Here is a direct copy of the working example code from the link:
local gpio, time_start, time_end, trigger, echo = gpio, 0, 0
local sample_count, timer_id
return function(trig_pin, echo_pin, sample_cnt, timer_id, report_cb)
trigger, echo = trig_pin or 7, echo_pin or 6
sample_count, timer_id = (sample_cnt+1) or 4, timer_id or 1
local total, i, result = 0, 0, {}
local function echo_cb(level)
if level == 1 and result[i] == 0 then
result[i] = -tmr.now()
gpio.trig(echo, "down")
elseif level == 0 and result[i] < 0 then
result[i] = tmr.now() + result[i];
gpio.trig(echo, "none")
else
gpio.trig(echo, "none") -- anything else turn off interrupts and restart at next sample
print("DEBUG INT off")
end
end
local function measure()
if i > 0 then -- process last sample
if result[i] < 0 then
result[i] = 0
i = i - 1
return -- skip a beat to allow the sonar to settle down
else
total = total + result[i];
end
if i == sample_count then
tmr.unregister(timer_id)
for j = 1, sample_count do print(("Sample %u is %u"):format(j,result[j])) end
total = total - result[1] -- substract sample one because it is usually off...
return report_cb(total / (58*(sample_count-1)))
end
end
gpio.mode(echo, gpio.INT)
gpio.trig(echo, "up", echo_cb)
gpio.write(trigger, gpio.HIGH); tmr.delay(20); gpio.write(trigger, gpio.LOW)
i = i + 1
end
for j = 0, sample_count do result[j] = 0 end -- pre-allocate result array
gpio.mode(trigger, gpio.OUTPUT)
tmr.alarm(timer_id, 60, tmr.ALARM_AUTO, measure)
measure()
end
(correct) sample output:
local x = require "test"(1,2,3,1,function(d) print(d) end)
> Sample 1 is 706
Sample 2 is 727
Sample 3 is 712
Sample 4 is 706
12
local x = require "test"(1,2,3,1,function(d) print(d) end)
> Sample 1 is 702
Sample 2 is 706
Sample 3 is 706
Sample 4 is 706
12
local x = require "test"(1,2,3,1,function(d) print(d) end)
> Sample 1 is 694
Sample 2 is 706
Sample 3 is 707
Sample 4 is 707
12
My version:
--variable declarations
local rangingStartTime, echoDuration,distance
local sensorControlPin,sensorDataPin
local function echoRising(level,timestamp)
rangingStartTime = timestamp
-- print("Rise detected at echo:"..timestamp)
end
local function echoFalling(level,timestamp)
-- print("Fall detected at echo:"..timestamp)
echoDuration = timestamp - rangingStartTime
-- print("echoDuration"..echoDuration)
-- calculate distance in cm
distance = echoDuration/58
print(distance.." cm")
end
local function echoChanged(level,timestamp)
if level==gpio.HIGH then
echoRising(level,timestamp)
gpio.trig(sensorDataPin,"low")
else
echoFalling(level,timestamp)
gpio.trig(sensorDataPin,"none")
end
end
local function startRanging()
-- send command signal to start ranging
gpio.write(sensorControlPin, gpio.HIGH)
-- timer delay 10us
tmr.delay(20)
--[exit command signal]--
gpio.write(sensorControlPin, gpio.LOW)
end
local function main()
--[ SETUP ]--
-- variable storing ranging start time
rangingStartTime = 0
sensorControlPin = 1
sensorDataPin = 2
gpio.mode(sensorControlPin, gpio.OUTPUT)
gpio.mode(sensorDataPin, gpio.INT)
-- when sensorDataPin changes, do echoChanged
gpio.trig(sensorDataPin,"high",echoChanged)
startRanging()
end
main()
(incorrect) output from my version:
dofile("hcsr04.lua")
> 46 cm
dofile(hcsr04.lua) Saturday, April 22, 2017 14:35:03
dofile("hcsr04.lua")
> 75 cm
dofile(hcsr04.lua) Saturday, April 22, 2017 14:35:04
dofile("hcsr04.lua")
> 128 cm
Also, the sensor is working properly, and I can get accurate results using the Arduino IDE.
I could use the Arduino IDE, but I really want to try something I'm not familiar with.
I know I could just copy and use the working lua code, but I'd really like to understand it better.
I've tried detecting gpio.trig on "both", removing my print statements, bringing echoRising and echoFalling into echoChanged, using tmr.now() instead of timestamp...
I'm doing something wrong and I don't know what it is.
Any assistance is greatly appreciated.