Left here for archival purposes.

User avatar
By plasmaskin
#16733 Hi,

I've built a simple project with a PIR sensor. When an event is detected, the ESP8266 just does a GET on an HTTP server. The code works most of the time, except when the server (on the LAN) makes an ARP request. It goes as follows:
- ESP8266 sends a TCP SYN packet
- Server broadcasts an ARP request ("who has this IP?")
- ESP8266 keeps sending TCP SYN packets every 500ms
- Server keeps sending ARP requests
- After trying 4 times to create the connection (i.e. after 2 seconds), the ESP8266 gives up
- The ESP8266 now listens and replies to the next incoming ARP request
- The server is happy and sends a TCP SYN ACK
- This was probably too late for the ESP8266 and it responds with a TCP RST ACK

So, as long as the server doesn't have to make an ARP request, all is good. If an ARP request is sent by the server, the ESP8266 is deaf to it while it's waiting for a SYN ACK.

I'm using NodeMCU 0.9.5 build 20150318. Here is my code:
Code: Select allPIRDataPin = 2   -- GPIO4

serverIP = "192.168.1.1"
serverPort = 80
serverURL = "/"

function onPIREvent(level)
   print("Event detected:")
   connect()
end

function connect()
   local conn=net.createConnection(net.TCP, 0)
   conn:on("receive", function(conn, payload)
      print("-> Received: "..payload:sub(1, payload:find("\r\n")))
      conn:close()
      conn=nil
   end)   
   conn:connect(serverPort, serverIP)
   conn:send("GET "..serverURL.." HTTP/1.1\r\nHost: "..serverIP.."\r\n\r\n")
end

print("Setting up GPIO interrupt for PIR sensor on pin "..PIRDataPin..".")
gpio.mode(PIRDataPin, gpio.INT)
gpio.trig(PIRDataPin, "up", onPIREvent)
print("Waiting for PIR sensor event...")


If this can help, I have a PCAP that shows the issue. I don't know if the problem comes from NodeMCU or from the TCP stack of the ESP8266.
User avatar
By TerryE
#16785 Just a thought here, I would have used the connected socket but the net.c code seems to have some botch to allow you to send to the conn socket in your code, but you'd normally expect to do something like:
Code: Select all   -- ...
   conn:on("connection", function(csock) csock:send("GET "..serverURL.." HTTP/1.1\r\nHost: "..serverIP.."\r\n\r\n") end)
   conn:connect(serverPort, serverIP)


Does coding it up this way impact the manifestation of this problem?
User avatar
By plasmaskin
#16839 Thanks for the tip Terry, it seems to work fine now :D I guess that the "send" function could be called before the connection was established in my initial code.

Here is the cleaned-up code in case someone would like to play with motion detection using the ESP8266:
Code: Select allPIRDataPin = 2   -- GPIO4

serverIP = "192.168.1.1"
serverPort = 80
serverURL = "/"

function onPIREvent(level)
   print("Event detected:")
   local conn=net.createConnection(net.TCP, 0)
   conn:on("connection", function(csock)
      csock:send("GET "..serverURL.." HTTP/1.1\r\nHost: "..serverIP.."\r\n\r\n")
   end)
   conn:on("receive", function(conn, payload)
      print("-> Received: "..payload:sub(1, payload:find("\r\n")))
      conn:close()
      conn=nil
   end)   
   conn:connect(serverPort, serverIP)
end

print("Setting up GPIO interrupt for PIR sensor on pin "..PIRDataPin..".")
gpio.mode(PIRDataPin, gpio.INT)
gpio.trig(PIRDataPin, "up", onPIREvent)
print("Waiting for PIR sensor event...")


FYI, I'm powering the ESP8266 and the PIR sensor using an MB102 USB power supply as it does both 3.3V and 5V.

Thanks again for your help!
User avatar
By TerryE
#16840 That's why we answer Qs 8-) It's good to know that we're sharing knowledge. You'll need to pass the token to another poster seeking help. :)