Jul 24

How to receive UDP data on NodeMCU + LUA + ESP8266

Category: Design,electronics   — Published by goeszen on July 24, 2017 at 4:41 pm

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)

Leave a Reply

=