espruino / Espruino

The Espruino JavaScript interpreter - Official Repo
http://www.espruino.com/
Other
2.79k stars 747 forks source link

Module with comment in certain spot doesn't send to Espruino #521

Closed SpenceKonde closed 9 years ago

SpenceKonde commented 9 years ago

This works:


exports.connect = function(serial,onCm,onTo,onEr) {
    return new EasyVR(serial,onCm,onTo,onEr);
};

function EasyVR(ser,onCm,onTo,onEr) {
  this.ser = ser;
  this.onCommand=onCm;
  this.onTimeout=onTo;
  this.onErr=onEr;
  this.ser.on('data',this.onData.bind(this));
  this.stop();
  this.vrstate=-1;
  this.stsr='o';
  this.rcvv="";
  this.tout=0;
  this.lstC='';
}

EasyVR.prototype.argchar=function(val) {
    if (val<-1 || val > 31) {throw "Bad arg";}
    return String.fromCharCode(0x41+val);
};

EasyVR.prototype.chararg=function(chr) {
    return chr.charCodeAt(0)-0x41;

}; 

EasyVR.prototype.onData=function(data) {
    //this=evr;

    console.log("serial data watch: "+data);
    var rcv=data.charCodeAt(0);
    console.log("serial data: "+rcv);
    if (rcv>0x60) {
        console.log("status");
        //console.log("serial lookup: "+temp);
        if (this.sts_idx[data]["len"]) {
            this.stsr=data;
            this.ser.print(' ');
            console.log("need to get data")
        } else {
            console.log("no data to get")
            this.sts_idx[data]["cb"].bind(this)();
        }
    } else {
        console.log("data");
        this.rcvv+=data;
        if (this.rcvv.length>=this.sts_idx[this.stsr]["len"]){
            console.log("running callback "+this.sts_idx[this.stsr]["cb"]);
            this.sts_idx[this.stsr]["cb"].bind(this)();
            this.rcvv="";
            this.stsr='o';
        } else {
            console.log("need more data");
            this.ser.print(' ');
        }
    }

};
EasyVR.prototype.sts_idx={
    "o":{len:0,cb:function(){
        console.log('STS_SUCCESS');
        console.log(this.lstC);
        if (this.lstC=='o')  { 
            console.log(this.vrstate);
            if (this.vrstate!=-1) {
                console.log("kicking off recognize");
                this.sendCmd('d',this.vrstate);
            }
        }
    }},
    "t":{len:0,cb:function() {
        console.log('STS_TIMEOUT');
        if (this.vrstate!=-1){
            console.log("calling onTimeout callback");
            this.onTimeout(this.vrstate);
            this.vrstate=-1;
        }
    }},
    "v":{len:0,cb:function() {
        console.log('STS_INVALID '+this.rcvv);
        if (this.vrstate!=-1){
            this.vrstate=-1;
        }
    }},
    "i":{len:0,cb:function() {
        console.log('STS_INTERR '+this.rcvv);
        if (this.vrstate!=-1){
            this.vrstate=-1;
        }
    }},
    "e":{len:2,cb:function() {
        console.log('STS_ERROR '+this.rcvv);
        if (this.vrstate!=-1){
            console.log("calling onErr callback");
            this.onErr(this.vrstate);
            this.vrstate=-1;
        }
    }},
    "s":{len:1,cb:function() {
        console.log('STS_SIMILAR '+this.rcvv);
        if (this.vrstate!=-1){
            console.log("calling onErr callback");
            this.onErr(this.vrstate);
            this.vrstate=-1;
        }
    }},
    "r":{len:1,cb:function() {
        console.log('STS_RESULT '+this.rcvv);
        if (this.vrstate!=-1){
            console.log("calling onCommand");
            console.log(r);
            var rt = this.onCommand(this.vrstate,this.chararg(this.rcvv));
            this.vrstate=-1;
            if (rt.type!==undefined) {
                this.setRecognize(rt.type,rt.timeout);
            }
        }
    }}
};

EasyVR.prototype.setRecognize=function(type,to) {
    if (this.tout) {
        clearTimeout(this.tout);
        this.tout=0;
    }
    this.vrstate=type;
    this.timeout(to);
};

EasyVR.prototype.sendCmd=function(cmd,arg) {
    //lastCmd=[cmd,arg];
    this.ser.print(cmd);
    console.log("Sending command: "+cmd);
    this.lstC=cmd;
    if (arg!==undefined){console.log("With arg: "+this.argchar(arg));this.ser.print(this.argchar(arg));}
};

EasyVR.prototype.stop=function(){
    this.sendCmd('b');
};
EasyVR.prototype.timeout=function(arg) {
    this.sendCmd('o',arg);
};

EasyVR.prototype.setStrict=function(arg) {
    this.sendCmd('v',E.clip(arg,1,5));
};

This does not:


EasyVR.prototype.sts_idx={
    "o":{len:0,cb:function(){
        console.log('STS_SUCCESS');
        console.log(this.lstC);
        if (this.lstC=='o')  { //
            console.log(this.vrstate);
            if (this.vrstate!=-1) {
                console.log("kicking off recognize");
                this.sendCmd('d',this.vrstate);
            }
        }
    }},
...

WTF?

The only change is the addition of // to start a comment, but with that comment there, the code doesn't send. get Echo(0) showing at the prompt, and the code never runs, and it's not clear what happens...

code:


var ocm=function(menu,option) {
  console.log("menu:"+menu+" option: "+option);
  if (menu==1) {
    if (option==0) {
      console.log("LIGHTS ON");
      //do lights on calls
    } else if (option==1) {
      console.log("LIGHTS OFF");
      //do lights off calls
    } else if (option==2) {
      console.log("SWITCH :");
      digitalWrite(LED1,1);
      return {type:2,timeout:15};
    } else if (option==3) {
      console.log("DESK :");
      digitalWrite(LED1,1);
      return {type:3,timeout:15};
    } else if (option==4) {
      console.log("NIXIE :");
      digitalWrite(LED1,1);
      return {type:4,timeout:15};
    }
  } else {
    if (menu==2) { // toggle a fargo or RF controlled device
      console.log("toggle device "+option);
      if (option < 8) {
        setFargo(option,!fargo[option]);
        console.log("set fargo"+option);
      } 
    } else if (menu==3) { // control desk lamp
      console.log("desk lamp "+option);
    } else if (menu==4) { // control nixie clock
      if (option==0) { //clock on
        setDesk("nixs=1;uplcd();");
      } else if (option==1) { //clock off
        setDesk("nixs=0;uplcd();");
      } else if (option==2) { //time
        setDesk("nixs=1;MnuS=0;Mnu0=0;uplcd();");
      } else if (option==3) { //temp
        setDesk("nixs=1;MnuS=0;Mnu0=1;uplcd();");
      } else if (option==4) { //humidity
        setDesk("nixs=1;MnuS=0;Mnu0=2;uplcd();");
      //} else if (option==5) { //pressure
      //  setDesk("nixs=1;MnuS=0;Mnu0=3;uplcd();")
      } 
    }
  }
  digitalWrite(LED1,0);
  return {type:1,timeout:0};

};

var otm=function(){
  digitalWrite(LED1,0);
  this.setRecognize(1,0);
};

//My standard fargo network commands
fargosturl="http://192.168.2.12/fargostatus.php";
dateurl="http://192.168.2.12/date.php";
fargourl="http://192.168.2.14/api/relay/";
deskurl="http://192.168.2.16/code.run";
fargo=new Uint8Array(8);

function setDesk(command) {
    /*require("http").get(fargourl+(relay+1).toString()+postfix, function(res) {
        res.on('close',function () {
            if(this.code!=200) {
                console.log("Error commanding desklamp/nixie: "+this.code);
            } else {
              fargo
            }
        });
    });*/
  console.log("desk command"+command);
}

function getFargostatus() {
    var fargost="";
    require("http").get(fargosturl, function(res) {
        res.on('data',function (data) {fargost+=data;});
        res.on('close',function() {var tfs=JSON.parse(fargost); vtfs=tfs; for (var i=0;i<8;i++) { fargo[i]=tfs.relaystate[i].state;} if(MnuS==3){uplcd(1);}});
    });
}

function setFargo(relay,state) {
    var postfix = (state) ? "/on":"/off";
    require("http").get(fargourl+(relay+1).toString()+postfix, function(res) {
        res.on('close',function () {
            if(this.code!=200) {
                fargo[relay]=state;
            }
        });
    });
}

function getDate() {
    var date="";
    require("http").get(dateurl, function(res) {
        res.on('data',function (data) {date+=data;});
        res.on('close',function() {clk=new Clock(date);});
    });
    //delete getDate;
}

function onInit() {
  Serial1.setup(9600,{tx:B6,rx:B7});
  evr=require("easyvr").connect(Serial1,ocm,otm,otm);
  Serial2.setup(9600, { rx: A3, tx : A2 });
  wifi = require("ESP8266WiFi").connect(Serial2, function(err) {
  if (err) throw err;
  wifi.reset(function(err) {
    if (err) throw err;
    console.log("Connecting to WiFi");
    wifi.connect("TwilightZone","L0st1nTheZ0ne", function(err) {
      if (err) throw err;
      console.log("Connected");
      // Now you can do something, like an HTTP request
      evr.setRecognize(1,0);
      setTimeout(getFargostatus,1000);
      setInterval(getFargostatus,30000);
    });
  });
});

}
gfwilliams commented 9 years ago

This is sending the module unminified?

My guess is it's this recurring issue of USB flow control. If you turn on throttling it'll probably work?

I'm hoping to swap to ST's newer CubeMX peripheral libraries, and when that happens I should be able to implement some proper flow control that will solve this once and for all.

SpenceKonde commented 9 years ago

Minification was set to "Closure (online) - Simple Optimizations" - which is what makes this so crazy - the two versions should minify to the exact same thing!

gfwilliams commented 9 years ago

Sorry - huge delay on this.

Was this with the Pico, or the original Espruino board?

SpenceKonde commented 9 years ago

It was with a Pico. I haven't seen this behavior since.

gfwilliams commented 9 years ago

Ok, closing then - reopen if there's trouble.