Jul 24
How to receive UDP data on NodeMCU + LUA + ESP8266
NodeMCU is a dev board with LUA scripting and WiFi. Here we're going to demonstrate how to have the NodeMCU connect to a local WLAN network, register itself with (default) IP 192.168.1.93 and open an UDP socket, listening for incoming UDP packets on port 3031.
Most tutorials on the Internet about NodeMCU and how to do or work with UDP are about creating a server, we here will receive UDP packets! and fill this gap.
Preparations are: you need a recent firmware, as the API for setting up and configuring an UDP socket has changed between 0.9.6, 1.5.4.1-final and master. The code published here works on "master".
So compile it yourself, or go the easy route and let it build in the cloud on nodemcu-build.com. Make sure you select the net module!
Edit the code to insert your SSID and password, so the NodeMCU is able to log itself in.
-- receive UDP data via Wifi
led = 4 -- on Pin 4
function setup_wifi(ssid, password)
wifi.setmode(wifi.STATION)
station_cfg={}
station_cfg.ssid=ssid
station_cfg.pwd=password
wifi.sta.config(station_cfg)
wifi.sta.connect()
tmr.alarm(1, 1000, 1, function()
if wifi.sta.getip()== nil then
print("Waiting for IP...")
else
tmr.stop(1)
our_ip = wifi.sta.getip() -- we store our_ip, as we need it to setup udp socket properly
print(" Your IP is ".. our_ip)
print(" Entering 'setup_udpsocket'")
setup_udpsocket()
end
end)
end
function setup_udpsocket()
print("setup_udpsocket here")
-- !! udp socket creation and receiving is different between firmwares! this here is for master
udpSocket = net.createUDPSocket()
udpSocket:listen(3031, our_ip) -- we need to pass an IP here, otherwise we end up with IP 0.0.0.0 (docs are mute about this)
udpSocket:on("receive", function(s, data, port, ip)
print(string.format("received '%s' from %s:%d", data, ip, port))
gpio.write(led, gpio.LOW) -- blink the LED on receiving data
tmr.alarm(2, 5, 1, led_off) -- 5ms
end)
port, ip = udpSocket:getaddr()
print(string.format("UDP socket listening on %s:%d", ip, port))
end
function led_off()
tmr.stop(2)
gpio.write(led, gpio.HIGH)
end
-- Main Program
gpio.mode(led, gpio.OUTPUT)
gpio.write(led, gpio.HIGH)
-- callbacks: setup_wifi -> setup_udp
-- ENTER YOUR WiFi CREDENTIALS HERE!!
setup_wifi("ssid", "password")
Fire it up, for example by saving it as init.lua or dofile().
And in another console, on a machine on the same network, execute this short Perl script:
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::INET;
my $sock = new IO::Socket::INET(
PeerAddr => '192.168.1.93',
PeerPort => 3031,
Proto => 'udp',
Timeout => 1
) or die('Error opening socket.');
my $count;
for(1..25){
$count++;
print $sock $count;
print "$count\n";
sleep(1);
}
print "done \n";
NodeMCU will blink on every UDP package received.
Some things to note:
If you created an UDP socket before, without a reset first, the ESP8266 will complain about the address being in use! (obviously) So make sure you power-cycle/reset the thing first, or close the socket.
As already pointed out in code-comments, calling udpSocket:listen() needs an IP address, or it will start listening on IP 0.0.0.0 - which doesn't work. The manual suggests that providing an IP is optional - but this won't automagically use the current own-IP - so it can't be omitted.
--
This post is part of a series of Mini Tutorials on the ESP8266:
Previous post: Convert an image for use on OLED
Next post: Arduino IDE on ESP8266 (NodeMCU dev board)
I'm tinkering here with a NodeMCU ESP8266 board.
I'm using the ESP8266 Java IDE ESPlorer.
The firmware is from the master branch, built today (see post date) powered by Lua 5.1.4 on SDK 2.1.0(116b762)