• You have implemented a house full of IoT devices and have a happy automated life. The power goes off and when it comes back on the DCHP in your router reassigns IP addresses and your IoTs can’t find each other.
    These programs show how to implement UDP (User Datagram Protocol) in Espruino and use the broadcast IP address 255.255.255.255 to allow the IoT’s to discover the IP addresses.

    Place UDP.js in the project modules folder.
    Edit the UDP_HTTPserver2.js and UDP_HTTPclient3.js files and insert your router SSID and password.
    var SSID="ssis";
    var key= "router password";

    The ESP8266WiFi_0v25.js module was amended into UDP.js
    var wifi = require("UDP").connect(Serial, function(err) {
    //var wifi = require("ESP8266WiFi_0v25").connect(Seri­al, function(err) {
    The send function is currently set to print the socket number and text.

    These variables were added:
    var UDPflag=1;
    var CIPstartStr="";
    The client code was modified
    var netCallbacks = {
      create : function(host, port) {
    …
        } else {  
    console.log("Client");
          var sckt = 0;
          while (socks[sckt]!==undefined) sckt++; // find free socket
          if (sckt>=MAXSOCKETS) throw new Error("No free sockets");
          socks[sckt] = "Wait";
          sockData[sckt] = "";
    
    if(UDPflag){//UDP client
     CIPstartStr='AT+CIPSTART='+sckt+',"UDP",­'+JSON.stringify(host)+','+port+','+port­+',0\r\n';
    
    }else{//TCP client
     CIPstartStr='AT+CIPSTART='+sckt+',"TCP",­'+JSON.stringify(host)+','+port+'\r\n';
    }//end else
    at.cmd(CIPstartStr,10000, function cb(d) {
    And two commands were added,
    "SetUDP":function(){ UDPflag=1;
    },
    "SetTCP" : function(){ UDPflag=0;
    },
    
      "getIP" : function(callback) {
    

    UDP_HTTPserver2.js
    This uses the broadcast IP of 255.255.255.255 to listen for a message from a client.
    The message identifies the client, the client’s IP and the server name.
    If the server name refers to this server program then a UDP broadcast message is sent that supplies the IP address of this server.
    An HTTP server is also implemented. If you run the program, a browser can access the simple web page. (The browser needs the IP address)

    >echo(0);
    Start
    Start connection process
    Try again
    =undefined
    Reset the ESP8266
    Connecting to WiFi
    OKxx1
    OKxx2
    Server
    IP=  192.168.1.3
    LocalIP=  192.168.1.3
    WiFi Connected
    Client
    client connected
    Send 0 {"ClientName":"Bob","ClientIP":0,"Server­Name":"Bill","ServerIP":"192.168.1.3"}
    

    UDP_HTTPclient3.js
    This program uses UDP to broadcast a message containing the client name, client IP and the server name that is needed to start a connection. The program listens for the reply message and if the names match it sends an HTTP Get request to the server at the server IP returned in the UDP message. The result of the HTTP Get request are displayed

    >echo(0);
    Start
    Start connection process
    Try again
    =undefined
    Reset the ESP8266
    Connecting to WiFi
    OKxx1
    OKxx2
    IP=  192.168.1.4
    Wi-Fi Connected
    Client
    client connected
    192.168.1.4
    Send 0 {"ClientName":"Bob","ClientIP":"192.168.­1.4","ServerName":"Bill","ServerIP":0}
    >{"ClientName":"Bob","ClientIP":"192.168­.1.4","ServerName":"Bill","ServerIP":"19­2.168.1.3"}
    getReply
    Client
    Send 1 GET / HTTP/1.0
    User-Agent: Espruino 1v86
    Connection: close
    Host: 192.168.1.3:8080
    d=  <html><body style="text-align:center;margin-left:aut­o;margin-right:auto;">
    <h1>UDP Demo.</h1>
    </body>
    </html>
    

    UDP_HTTPserver2.js

    >{"ClientName":"Bob","ClientIP":"192.168­.1.4","ServerName":"Bill","ServerIP":0}
    Send 0 {"ClientName":"Bob","ClientIP":"192.168.­1.4","ServerName":"Bill","ServerIP":"192­.168.1.3"}
    Socket accept 1 "GET / " undefined
    Get
    Send 1 HTTP/1.0 200 OK
    Server: Espruino 1v86
    Content-Type: text/html
    
    <html><body style="text-align:center;margin-left:aut­o;margin-right:auto;">
    <h1>UDP Demo.</h1>
    </body>
    </html>
    
    >
    

    3 Attachments

  • Wow, nice - so you're actually managing to implement HTTP over UDP?

  • You can do both UDP and TCP at the same time.

    Wifi.at.cmd("AT+CWMODE_CUR=3\r\n", 1000, function(d){console.log(d+"xx1");});

    You call SetUDP and then setup a network with protocol 17 for UDP.
    Then you call SetTCP and setup either HTTP or a TCP network.

         wifi.SetUDP();
         var client = require("net").connect({host: BroadIP, port: UDPport,protocolVersion: 17}, function() {
    

    Use the UDP to obtain the IP address of the server and then

              wifi.SetTCP();
               getReply(console.log);
    ...
    function getReply(callback) {
      var options = {
        host: ServerIP,
        port: '8080',
        path:"/",
        method:'GET',
        headers: {
        }
      };
      console.log("getReply");
      require("http").request(options, function(res)  {
        var d = "";
        res.on('data', function(data) { d+= data; });
        res.on('close', function(data) {
          var j = JSON.parse(d);
          console.log("d= ",d);//console.log("j= ",j);
          if (callback) callback((j&&j.result)?j.result:undefine­d);
        });
      }).end();
    }//end getReply
    

    On the server side

        wifi.SetUDP();
      var client = require("net").connect({host:BroadIP,por­t:UDPport ,protocolVersion: 17}, function() {
        console.log('client connected');
        client.write(JSON.stringify(UDP1));
        client.on('data', function(data){
         ddata+=data;
         if(ddata.charAt(ddata.length-1)==='}'){
          UDP2=JSON.parse(ddata);
          console.log(">"+ddata);
          if(UDP1.ServerName===UDP2.ServerName){
           UDP2.ServerIP=UDP1.ServerIP;
           client.write(JSON.stringify(UDP2));
           ddata="";
          }//endif
         }//endif
        });//end client on data
        client.on('close',function(){console.log­("client Close");});
        client.on('end', function() {
         console.log('client disconnected');
        });//end client on end
        //client.end();
       });//end UDP client connect
    });//end wifi.getIP
    //HTTP or Network Server goes here
       wifi.SetTCP();
    serveHTML();
    //////////////////
    .....
    function serveHTML(){
    var http=require("http").createServer(onPage­Request).listen(8080);
    }//end serveFile
    
    
    function onPageRequest(req, res) { 
    //console.log("Req= ",req);
    //console.log("Header",req.headers);
    if (req.method=="POST") {
      console.log("Post");
      doPost(req,res);
    }else{
      doGet(req,res);
    }//endif
    }//end on PageRequest
    
    
  • can this UDP module be "pushed" in a central modules repo?

  • It's not really production ready at the moment - ideally Espruino's network API would change so that we could implement UDP on other platforms as well. It's a little tricky because Espruino tends to deal with characters as it gets them - whereas with UDP ideally you want to deal with each packet as it comes.

    Having said all that, you can still load it straight into your projects - just enter the full URL like this:

    var wifi = require("https://espruino.microcosm.app/­api/v1/files/bd981df5a1734c330d37a9f8486­ea8bf8d406696.js").connect(Serial, function(err) {
      ....
    });
    
  • I'm getting

    ERROR: Out of Memory!
    Uncaught Error: Function "connect" not found!
    at line 1 col 108
    ...7a9f8486ea8bf8d406696.js").connect( "someSSID", { password:"AA...

  • What board are you using this on?

    Looking at your previous posts it seems like it might be an ESP8266? Getting UDP on those requires actual firmware changes - @ClearMemory041063's code will only work when run on an Espruino board that is connected to an ESP8266.

  • Couldn't you also set up a captive portal with this?

  • I try to get the UDP_HTTPserver2.js working on ESP8266 board directly.

    Struggled for 2 hours now..... Hardware = 0 or 1 does not work of course.
    While reading .... if Gordon is right, I did change
    .... Serial.setup(115200, { rx: D2, tx : D2 }); //ESP8266

    Still not working.... I had to add extra debugging and it returns after a first AT command with an error:
    No 'ready' after AT+RST

    any help? I m so close to get Espruino-ESp8266-Alexa integration :-)

  • This UPD work was done using a Pico connected to an ESp8266. The WiFi library that loads onto the Pico was modified to do the UDP. It doesn't work on an Esp8266 loaded with Espruino.
    :(

  • @Vasily are you trying to run this on an ESP8266 itself, or on an Espruino WiFi?

    If it's on ESP8266 the latest builds have UDP support built in: https://github.com/espruino/Espruino/blo­b/master/tests/test_dgram_socket.js

  • yes, i m using esp directly
    i have 1.94 firmware version.

    the current test example is not very elaborated i will try to make it working for broadcast receive and send.
    i also found test-multi alreadt

  • example does not work on 1.94 official binary. it says, module dgram not found.

  • No. you need the cutting edge ESP8266 builds from http://www.espruino.com/binaries/travis/­master/ (it'll be in 1v95 when it's released). If you have any issues, please ask on the ESP8266 section of the forum - you're more likely to get a helpful answer from the guys that actually worked on the ESP8266 UDP stuff there :)

  • I've finally tried the master build today. Unfortunatelly it does not work when Espruino flashed directly on ESP8266 board.
    Notes: I m sure using correct version, in official v1.94 the require("dgram") was not working.

    I tried 3 tests and nothing worked.
    *** 1. test_dgram_reuseAddr.js - error returned
    Flash map 4MB:512/512, manuf 0xc8 chip 0x4014

    Uncaught InternalError: Unable to create socket
    at line 1 col 15
    srv2.bind(port);
    =undefined

    *** 2. test_dgram_socket.js - nothing returned (expected msg on send and receive)
    Flash map 4MB:512/512, manuf 0xc8 chip 0x4014

    =undefined
    server disconnected
    client disconnected

              Notes: I ve tested some extra msg-logs and removed srv.close and client.close.... IMHO, still seams that network.c fails and returns into networkGetFromVarIfOnline();
    

    *** 3. test_dgram_multi.js - nothing returned (expected msg on send and receive)
    Flash map 4MB:512/512, manuf 0xc8 chip 0x4014

    =undefined
    server 1 disconnected
    server 2 disconnected
    =undefined

              Notes: also very strange that msg "server 1/2 disconnected" received but msg "client disconnected" is not received
    

    p.s. I've tried to get connected to wifi at first, changed client.send(.... IP) to 127.0.0.1 and also to the wifi real IP after ESP is connected. Nothing changed. Would love to debug but do not know how.

  • If you have any issues, please ask on the ESP8266 section of the forum. This thread was initially about UDP on Espruino WiFi, so I don't want it sidetracked with random ESP8266 questions.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Implementing UDP on Espruino, Using UDP broadcast to find server IP.

Posted by Avatar for ClearMemory041063 @ClearMemory041063

Actions