-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ESP32: Sonar Module #3090
ESP32: Sonar Module #3090
Conversation
Hi @jpeletier Javier, I have a project for ESP8266 using this sonar device to measure level of water in a watertank. I wonder whether you need a Lua C module for something that can be achieved with few lines of Lua code. I extracted minimum example from my project: local PIN_T = 7 -- GPIO13 - trigger
local PIN_E = 6 -- GPIO12 - echo
local alarm_trigger = tmr_create()
local ts = 0
local function echo(level)
local delay = tmr.now()-ts
if delay < 0 then delay = (delay + 0x7FFFFFFE) + 1 end -- workaround for #1691
if delay <= 28876 then -- 5 meters
local dist = (delay - 150) * 0.017315 -- this needs proper calibration for each implementation
print("Distance: ", dist)
end
end
local function trigger()
gpio.serout(PIN_T, gpio.LOW, {50, 100}, 1, function() ts = tmr.now() end)
end
gpio.mode(PIN_E, gpio.INT)
gpio.trig(PIN_E, "down", echo)
gpio.mode(PIN_T, gpio.OUTPUT)
alarm_trigger:alarm(350, tmr.ALARM_AUTO, trigger) To get reliable measurement I am performing n (=10) measures in sequence and then I calculate median of results. Also I think you should not be using |
Note that trig callback function actually includes (as an argument) the timestamp of the edge: https://nodemcu.readthedocs.io/en/dev/modules/gpio/#gpiotrig |
@pjsg, was it there always? I had to miss it. |
It has been there for at least a year....
…On Wed, May 6, 2020, 16:51 Lukáš Voborský ***@***.***> wrote:
@pjsg <https://github.com/pjsg>, was it there always? I had to miss it.
Measurements should be more precise when using the feature.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3090 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AALQLTMTMQJGHG2OT4PA6NDRQHETJANCNFSM4M2VFNHQ>
.
|
Good. My project is older than that. |
@vsky279 Thank you for your comments. I looked at your implementation in LUA, but in the ESP32 In any case, I worry measurements will not be as accurate. Using the ESP32 RMT hardware to measure yields very accurate time measurements that are not affected by RTOS context switches. For measuring something slow like a water tank it may not be as useful, but for a fast moving object, like a robot car, I think is good to be able to take a good number of samples per second to detect if something is near or just crossed by, without overloading the VM too much. In my applications for NodeMCU, I try to leave hardware as much as possible to the C world, offloading Lua VM and keeping it for configuration and business logic. For this module, I did some research on how to drive the sonar best with an ESP32 and distilled what I thought was the best approach into this PR. Regarding your comment on userdata vs malloc/free, I took a look at PR #2854 (nice job!) and the discussion around userdata, however I don't see why the overhead of creating a Lua userdata object is necessary when the information I am using malloc/free for is tiny and unrelated to Lua. Note also that I am using Thank you again for the comments! |
@jpeletier Your motivation to have it in C Lua module seems to be reasonable. I have only one somewhere here with a camera (unfortunately not yet supported by NodeMCU) and did not found nice application for the time being. 😄 |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
dev-esp32
branch rather than formaster
.docs/*
.This PR introduces a new sonar module. This module drives the typical ultrasound based sonars, such as the HC-SR04. These sensors are activated by a "trig" pin that must be held high for a few microseconds. Then, an ultrasound is emitted and when it bounces back some surface, an echo is received. The sensor sends back to the microcontroller a pulse as long as the time it took for the echo to come back. Distance can be then calculated by multiplying the total travel time by the speed of sound.

You can learn more about this sensor in this detailed guide.
ESP32/ESP-IDF implementation details
Internally, this module uses the RMT infrared driver hardware present in ESP32 for accurate pulse measurement. Each sonar object takes two RMT channels, one for sending and another for receiving. There are 8 RMT channels in ESP32, so up to 4 sonars can be driven simultaneously. Code could be optimized to share these channels in the future.
Hardware connection:
Connecting this sensor takes 2 GPIO pins. One to send the trigger signal and the other to listen to the echo pulse.
HC-SR04 is driven by 5V, therefore care must be taken to bring down the echo signal to the 3.3V the ESP32 operates at, for example with a simple voltage divider in which
R2 = 2*R1
You can follow this schematic as a guide:
LUA API
Example
sonar.new()
Creates a sonar driver.
Syntax
sonar.new(trigPin, echoPin)
Parameters
trigPin
GPIO pin connected to HC-SR04 Trig pinechoPin
GPIO pin connected to HC-SR04 Echo pinReturns
Sonar object (sonarObj) that exports the
ping()
method.sonarObj:ping()
Sends out a sonar ping. The callback will be invoked passing the distance in mm as the only parameter, or the special constant
sonar.DISTANCE_OUT_OF_RANGE
if no obstacle is detected.Syntax
sonar.ping(callback)
Parameters
callback
: Function that will be called when the ping bounces back or no echo is detected.Returns
nothing