• Hello,
    I am using the AT module, and the cmd function. I need to provide the AT command which leads to the call of the call back. I mean a signature like this : cb(d, ATcommand) or similar.
    I am not expert in JS, but I guess that's a closure. Is it possible to make sure that the call back remembers the AT command which makes it called ?
    Thanks a lot
    GeekBot

  • I think I did a mistake in my code, because now I see the cb function behaving as a closure, so sorry for the noise.
    However, I don't understand the code in the function AT.cmd :
    if more info is awaited, "return cb". What does exactly this code ? How returning cb function makes the callback retriggered again. Sorry for this neophyte question...
    Thanks a lot
    GeekBot

  • @GeekBot, could you present a little bit more of your code?

  • Sorry, I understand that you can't understand what I am talking about!
    The code is the example presented here: http://www.espruino.com/AT
    The part AT.cmd...
    Thanks
    GeekBot

  • @GeekBot, asynch has its challenges, especially in a single tasked world as JavaScript lives in.

    Agreed, the example has not the best introductory comment and is a bit terse... a better - more self explanatory and comprehensive - version would be something like that:

    // (Try to) Send a simple command and wait for a response within 1 second timeout
    var t0 = getTime();
    at.cmd("AT+EO\r\n", 1 * 1000,  function(d) {
      if (d===undefined) { // we timed out!
         console.log("For what ever reason device did not respond within 1000 second.");
      } else { // we got response within timeout time
         console.log("Device response is " + d + " and was within " + (getTime() - t0) + " seconds.");
      }
    });
    

    Written in a different form:

    // definition of a callback function that takes one argument and expects t0 as global var.
    var callback = function(responseData) {
      if (responseData===undefined) { // we timed out!
         console.log("For what ever reason device did not respond within 1000 second.");
      } else { // we got response within timeout time
         console.log( "Device responded within  " +  (getTime() - t0) + " seconds with: "
                    +responseData );
      }
    };
    // (Try to) Send simple command and wait for a response within 1 second timeout
    var t0 = getTime();
    at.cmd("AT+EO\r\n", 1 * 1000,  callback);
    

    To be clear, the 1 second is true only if there is no other command going on, because the AT library can handle multiple commands which are stored in the at.waiting array - like a 'FIFO' memory/queue: first come first served - like standing in line at a grocery store (never mind the joke of 'LOST' memory: last out, still there...).

    When it is the turn of the command request - as passed with .cmd(...), at sets a timeout as specified by the request and sends the command to the device. When the device responds within the timeout time, at calls the callback with the response value (and clears the still pending timeout); and if the device does not respond within the set timeout time, at calls the callback with undefined value.

    A callback function is something like a (deferred) instruction ('callback') to your friend-and-helper ('at') while telling him/her 'to go for something' (command). When she/he gets that something, your friend-and-helper will follow the given instructions...

    Another illustration is: you leaving a or your callback number when the called person does not take - more precisely - miss the call. When the called person will see the missed call and callback number, the person will call (you) back the call(back)number and give (you) the opportunity to say what (you) wanted to (be) said in the first place... (at least you/we hope that will happen... on multiple levels...). The timeout in this example? - What about: After that some time (timeout) of the call, you will go to the bar of your choice to get a drink without your friend's input (or company).

    I hope this helps somehow... if not, tell me more about the part you would like more information about...

  • I think you're asking about the return cb bit?

    // let's say a command returns:
    a
    b
    c
    end_of_data
    something_else_from_another_fn
    
    // If you do:
    at.cmd("...", 1000,  function cb(d) {
    });
    
    // it gets called ONCE with 'a'
    
    // But if you do
    at.cmd("...", 1000,  function cb(d) {
      if (d==undefined) { timed out! }
      else if (d!="end_of_data") {
        // save data
        return cb;
     } else {
       // do stuff
     }
    });
    
    // You'll get a,b,c and end_of_data
    

    Not sure if that makes sense? Basically if the callback function returns another function, which might be itself, then that functions will keep getting called back for each new line of data. Many AT commands return >1 line of data back, so it's a nice easy way of making sure you grab that data and only that data.

  • oops... missed the detail of ... return cb;... :| ...never mind.

  • @allObjects and @Gordon, thank you very very much for your detailed explanations. They help me a lot in my JavaScript education. Now I understand the code and the way to use it properly.
    Best regards
    GeekBot

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

AT module : Call back of AT.cmd (cb) doesn't remember the ATcommand : closure ?

Posted by Avatar for GeekBot @GeekBot

Actions