You are reading a single comment by @allObjects and its replies. Click here to read the full conversation.
  • The way I understand this is: on ESP8266, Espruino has direct, synchronous and blocking access to the ip information, and therefore does not need to handle asynchronousity. An Espruino connecting to a ESP8266 has to go through the non-blocking, asynchronous serial send and receive interfaces and therefore has to use the callback to provide the information 'where to resume' with the response.

    I do not like to see different code for logically the same thing... unfortunately with MCs, hardware is so close to the application that differences in it must be (heart) felt... Just noticed that for wifi.connect() the syntax is also different - this time for no obvious hardware reasons... probably just for historical (soft/firm-ware) reasons... :( - @Gordon / @tve ?

    Having to cater for two different interfaces for getIP() leads me again to use sort of a 'pico container'/sequence controller that manages serialization of asynchronous and regular calls. With such a construct, it is possible to have the very same application code after connecting.

    Without such a controller, the code could look like below where both wifi options share one and the same code for getting and printing the IP address (see lines 2..6 in third, shared code block):

    ESPRUINO on ESP8266:

    // Espruino on ESP8266
    var creds = require("creds"), ip;
    console.log("Connectin wifi...");
    wifi.connect(creds.ssid, {password: creds.pwd}, function(err){
      app(err);
    });
    

    ESPRUINO with ESP8266:

    // Espruino with ESP8266
    var creds = require("creds"), ip;
    Serial2.setup(115200, { rx: A3, tx : A2 });
    var wifi = require("ESP8266WiFi_0v25").connect(Serial2, function(err) {
      if (err) throw err;
      wifi.reset(function(err) {
        if (err) throw err;
        console.log("Connectin wifi...");
        wifi.connect(creds.ssid,creds.pwd, function(err) {
          app(err);
        });
      });
    });
    

    Shared application code that also handles getting the IP address:

    // shared app code
    function app(err,ip) {
      // Some pretext... getting IP addr when 'with' or 'on' ESP8266
      if (err) { throw err; } else if (!ip) { console.log("Connected."); }
      if (!ip) { if (!(ip = wifi.getIP(app))) return; }
      console.log("IP: " + ip);
      // Now you can do something, like an HTTP request
      require("http").get("http://www.pur3.co.uk/hello.txt", function(res) {
        console.log("Response: ",res);
        res.on('data', function(d) {
          console.log("--->"+d);
        });
      });
    }
    

    Console output:

     1v85 Copyright 2016 G.Williams
    >echo(0);
    =undefined
    Connectin wifi...
    Connected.
    IP: 192.168.0.106
    Response:  {
      "headers": {
        "Date": "Mon, 02 May 2016 09:55:12 GMT",
        "Server": "Apache/2.2.14 (Ubuntu)",
        "Last-Modified": "Fri, 15 Nov 2013 15:42:26 GMT",
        "ETag": "\"c01036-d-4eb390b8a8d18\"",
        "Accept-Ranges": "bytes",
        "Content-Length": "13",
        "Vary": "Accept-Encoding",
        "Connection": "close",
        "Content-Type": "text/plain"
       },
      "httpVersion": "1.1",
      "statusCode": "200",
      "statusMessage": "OK"
     }
    --->Hello World!
    > 
    

    Notes:

    1. This setup maximizes the reuse and minimizes the code different to the wifi options.
    2. module "creds" is my credential module in my project sandbox modules folder (a single line with exports = { ssid: "MySSID", pwd: "myPassword" };. It enables to pull the credentials from a single point and hide them from the code
    3. the app() function or functions can be put into a module "app" as well to maximize reuse without having duplicates - copy-pastes - hanging around... (module content: exports = function(err, ip) {...}; and usage: var app = require("app");).
    4. Solution for same code for both options assumes that method .getIP() of "Wifi" module (for 'Espruino on ESP8266') does not care about arguments passed and always returns something that evaluates to true, and .getIP(...) of "ESP8266WiFi_... (for 'Espruino with ESP8266') always returns something that evaluates to false...
    5. If you do not like running functions unnecessarily nested, you can split app() into two pieces: a preText(err, ip) {...} function and an app() {...} function. preText() calls first itself as callback and then it calls app() in a timeout. That way the execution stack is completely pop-ed (as max as possible). - Don't forget to change invocation in wifi.connect(...) callback from app(err, ip); to preText(err, ip);:

      // shared preText and app code
      function preText(err,ip) {
      // Some pretext... getting IP addr when 'with' or 'on' ESP8266
      if (err) { throw err; } else if (!ip) { console.log("Connected."); }
      if (!ip) { if (!(ip = wifi.getIP(preText))) return; }
      console.log("IP: " + ip);
      setTimeout(app,0);
      }
      function app() {
      // Now you can do something, like an HTTP request
      require("http").get("http://www.pur3.co.uk/hello.txt", function(res) {
      console.log("Response: ",res);
      res.on('data', function(d) {
        console.log("--->"+d);
      });
      });
      }
      
About

Avatar for allObjects @allObjects started