The problem
I tried to find reliable information on the range of the ESP-12 series modules, but was not quite happy with what I found. Neither the use of highly directional antennas (or is it "antennae"?) nor the selection of client devices seemed right to draw conclusions about the actual range.
EDIT: see the 1st part of my video
about the tester here.
EDIT: and here is the 2nd part if the
video with the results
The idea
ESP-8266 modules at both ends of the connection seemed like a good idea to me. Normally you would use a simple ping-test to see if packets are lost on the way between the modules.
ICMP
Despite the fact that the LWIP stack in NodeMCU does handle ICMP properly, I have yet to see a "Ping" program to send/revceive ICMP echo-requests/replies.
TCP
TCP connections between two NodeMCU endpoints are super easy. But the TCP protocol will do it's best to compensate the loss of packets, so we wouldn't detect missing packets until the connection breaks up completely.
UDP
UDP does not provide such a recovery mechanism for lost packets, so the application has to handle that. We can use that easily to find out when packets go missing.
The solution
Ok, so UDP it is. We'll simply connect an ESP-12e module in station-mode to an ESP-12f module in soft-ap mode and send UDP packets from the ESP-12e to the ESP-12f module.
The payload of each packet is a numer that is incremented by one for each packet. So if a packet is missing, it is easy to detect.
 |
| The ESP-modules |
What you need
The server.lua script
local LED_PIN1 = 4
gpio.mode(LED_PIN1, gpio.OUTPUT)
local sw1 = true
wifi.setmode(wifi.SOFTAP)
cfg={}
cfg.ssid="AReResearch"
wifi.ap.config(cfg)
function init_OLED(sda,scl)
sla = 0x3c
i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g.ssd1306_128x64_i2c(sla)
disp:setFont(u8g.font_6x10)
disp:setFontRefHeightExtendedText()
disp:setDefaultForegroundColor()
disp:setFontPosTop()
end
init_OLED(5,6)
err=0
cold=1
disp:firstPage()
repeat
disp:drawStr(0, 10, "AReResearch UDP-Ranger")
disp:drawStr(5, 35, "Waiting for client...")
until disp:nextPage() == false
s=net.createServer(net.UDP)
s:on("receive",function(s,c)
print("Sequence="..c.." Previous:"..cold)
if ((cold+1)~=tonumber(c)) then
err=err+1
end
disp:firstPage()
repeat
disp:drawStr(0, 10, "AReResearch UDP-Ranger")
disp:drawStr(5, 35, "Packet Nr:" .. c)
disp:drawStr(5, 45, "Errors:" .. err)
until disp:nextPage() == false
if (sw1) then
gpio.write(LED_PIN1, gpio.LOW)
else
gpio.write(LED_PIN1, gpio.HIGH)
end
sw1 = not sw1
cold=c
end)
s:listen(8888)
The client-lua script
wifi.setmode(wifi.STATION)
wifi.sta.config("AReResearch","")
wifi.sta.connect()
LED_PIN1 = 4
gpio.mode(LED_PIN1, gpio.OUTPUT)
print (wifi.sta.getip())
x=1
tmr.alarm(2, 1000, 1, function()
conn = net.createConnection(net.UDP, 0)
conn:connect(8888,"192.168.4.1")
conn:send(x)
conn:close()
conn = nil
x=x+1
print (x)
if x>1000 then x=1 end
p=tonumber(wifi.sta.status())
print (p)
if p == 5
then
gpio.write(LED_PIN1, gpio.LOW)
print ("LED OFF")
else
gpio.write(LED_PIN1, gpio.HIGH)
print ("LED ON")
end
end)
Ok, the programming is admittedly a bit sloppy. The counter will simply roll over at 1000 packets and will thus increment the "lost packets" counter by one. It is good enough for me at the moment.
 |
| Start the "server"module first |
 |
| The "client" has sent packets |
How to use this
Once the client module has connected to the "server", the server module's LED will be toggled every time a packet is received. More info in how many packets have been missed is shown on the OLED.
So it is easy to tell when the connection starts breaking up.
The results
My first test run gave me a pretty stable connection up to
300 meters. Beyond 400m I couldn't get anything at all.