Two troubles with new 1v97 v on EspruinoWiFi

Posted on
  • Hi, with new 1v97 I've got this terrific trouble with “New interpreter error: FIFO_FULL”
    I use EspruinoWiFi, which is managed through TCP client connection, to handle water valves, read water-flow sensors, read humidity sensors and so on. Therefore, with new 1v97 I have to disable all pins, that read any data! As soon as I initialize any of them WiFi is down!
    And more troubles with 1v97. When initializing tcp client connection, double event-listeners are created (two onerror, two ondata and so on).

  • Ahh, sorry - the double event listeners on TCP issue is something that we spotted yesterday and that literally just got fixed 15 minutes ago. I'll be doing a new release (1v98) with it in soon, but new firmwares from https://www.espruino.com/binaries/travis­/master/ have a fix in.

    However could you provide any more info on how the FIFO_FULL message comes about? Is it during upload? It's caused when there are too many characters/input events coming in to Espruino WiFi for it to handle.

    What was the older firmware that worked for you? The FIFO_FULL checking and message has been around for a while, but we recently added flow control to Espruino WiFi to avoid losing characters from the ESP8266, it will now stop the ESP8266 from sending data if the fifo is looking full.

    Could it be:

    • You have sensors on B6/B7 (the default UART pins), but you haven't put USB.setConsole(1) in onInit? If so they could be causing lots of garbage data to be coming in to Serial1
    • You're using setWatch on a pin that changes state very quickly, most of the time (eg. 1kHz or so)

    If you're able to share your code (or a subset of it that exhibits the problem - ideally without requiring external hardware to be connected) I can take a look and try and figure out what the problem is.

  • FIFO_FULL message comes on load.
    1v96 worked fine. At least I've never recieved this mistake. But I could not be 100% sure with 1.96 as I'm in the procees of building my system and always update the code adding new fitures

    I provide modified sample of the code which caused the problem. The solution to connect WiFi was to comment the code with flow-sensor and also do not put ANY pin in to the input mode. Flow-sensor is library written by Amperka and it woked absolutely fine with 1.96 and 1.95. I have not modified any part of this library

    var HOSTS = ["192.168.1.92", "192.168.1.93", "192.168.1.95"];
    var WIFI = [
      ["Alhimik" , { password : "" } ],  //0
      ["Alhimik_N", { password : "" }],  //1
      ["A-Alhimik ", { password : "" }]  //2
    ];
    var INIT_OPTIONS = {"HOSTS": [0], 'WIFI': 0, 'ISSTART': 0, "Name": 'EspWater'};
    var wifi = require("EspruinoWiFi");
    
    var L = {
      'LED1': require("ledHandling")(LED1),
      'LED2': require("ledHandling")(LED2),
      'A5': require("ledHandling")(A5, 1),
      'A6': require("ledHandling")(A6, 1),
      'A7': require("ledHandling")(A7),
      'B1': require("ledHandling")(B1)
    };
    
    E.on('init', function() {
      USB.setConsole();
      console.log('started');
      L.LED1.On();
      //INIT_OPTIONS.ISSTART = 1;
      setTimeout(wifiOn, 1000);
    });
    
    var wifiOn = function(){
      console.log('starting WiFi');
      console.log(WIFI[INIT_OPTIONS.WIFI][0] + ' - ' + WIFI[INIT_OPTIONS.WIFI][1]);
      wifi.connect(WIFI[INIT_OPTIONS.WIFI][0],­ WIFI[INIT_OPTIONS.WIFI][1], function(err) {
        if (err) {
          console.log("Connection error: "+err);
          L.LED1.blink(50);
          setTimeout(wifiOn, 60000);
          return;
        }
        console.log("WiFi connected!");
        L.LED1.On(0); L.LED2.blink(100);
        for (var i in INIT_OPTIONS.HOSTS) {
          setTimeout(ccon, 5000 * i, INIT_OPTIONS.HOSTS[i]);
        }
      });
      return;
    };
    
    /*********
     FLOW-Sensor
     **********/
     var flowSensor = [];
     flowSensor[0]  = require('water-flow').connect(A0, {measurePeriod: 5});
     flowSensor[1]  = require('water-flow').connect(A1, {measurePeriod: 5});
    
  • I just inlined the Amperka module (and made a version of ledHandling) and uploaded, but it uploads just fine for me with the latest EspruinoWiFi firmware:

    Modules.addCached("water-flow",function(­) {
      
    var WaterFlow = function(pin, opts) {
      this._pin = pin;
    
      this._pin.mode('input_pulldown');
    
      this._litres = 0;
      this._pulses = 0;
    
      this._pulseTimerID = null;
    
      this._speed = 0;
    
      opts = opts || {};
    
      this._avg = opts.averageLength || 10;
      this._pulsesPerLitre = opts.pulsesPerLitre || 450;
      this._minimumSpeed = opts.minimumSpeed || 1;
    
      this._litresPerPulse = 1 / this._pulsesPerLitre;
      this._speedNumerator = this._litresPerPulse * this._avg;
      this._updatePeriod = (60 * 1000) / (this._minimumSpeed * this._pulsesPerLitre);
    
      this._avgArray = new Array(this._avg); // [litres per second]
      this._avgIterator = 0;
    
      this.reset();
    
      this._watch();
    };
    
    WaterFlow.prototype._watch = function() {
      setWatch(this._onChange.bind(this), this._pin, {
        repeat: true,
        edge: 'rising',
        debounce: 1
      });
    };
    
    WaterFlow.prototype._average = function() {
    
      this._avgArray[this._avgIterator] = getTime();
    
      var last;
      if (this._avgIterator === this._avg - 1) {
        last = this._avgArray[0];
      } else {
        last = this._avgArray[this._avgIterator + 1];
      }
    
      var speed = this._speedNumerator / (this._avgArray[this._avgIterator] - last);
    
      if (++this._avgIterator === this._avg) {
        this._avgIterator = 0;
      }
    
      return speed;
    };
    
    WaterFlow.prototype._onChange = function() {
      this._pulses++;
      this._litres += this._litresPerPulse;
    
      if (this._pulseTimerID !== null) {
        clearTimeout(this._pulseTimerID);
        this._pulseTimerID = null;
        this._speed = this._average();
      }
    
      var self = this;
      this._pulseTimerID = setTimeout(function() {
        self._pulseTimerID = null;
        self._speed = 0;
        self.emit('drain');
      }, this._updatePeriod);
    
      this.emit('pulse');
    };
    
    WaterFlow.prototype.volume = function(units) {
      switch (units) {
        case 'l': return this._litres;
        case 'cm^3': return this._litres * 1000;
        case 'm^3': return this._litres / 1000;
        default: return this._litres;
      }
    };
    
    WaterFlow.prototype.reset = function() {
      var time = getTime();
      for (var i = 0; i < this._avg; ++i) {
        this._avgArray[i] = time;
      }
      this._litres = 0;
      this._pulses = 0;
    };
    
    WaterFlow.prototype.speed = function(units) {
      switch (units) {
        case 'l/min': return this._speed * 60;
        case 'cm^3/min': return this._speed * 60 * 1000;
        case 'm^3/min': return this._speed * 60 / 1000;
        default: return this._speed * 60;
      }
    };
    
    exports.connect = function(pin, opts) {
      return new WaterFlow(pin, opts);
    };
    });
    Modules.addCached("ledHandling",function­() {
      exports = function(pin) {
        return {
          blink:function(){ digitalPulse(pin,1,100); },
          On:function(){ pin.set();},
          Off:function(){ pin.reset(); },
        };
      };
    });
    
    
    var HOSTS = ["192.168.1.92", "192.168.1.93", "192.168.1.95"];
    var WIFI = [
      ["Alhimik" , { password : "" } ],  //0
      ["Alhimik_N", { password : "" }],  //1
      ["A-Alhimik ", { password : "" }]  //2
    ];
    var INIT_OPTIONS = {"HOSTS": [0], 'WIFI': 0, 'ISSTART': 0, "Name": 'EspWater'};
    var wifi = require("EspruinoWiFi");
    var L = {
      'LED1': require("ledHandling")(LED1),
      'LED2': require("ledHandling")(LED2),
      'A5': require("ledHandling")(A5, 1),
      'A6': require("ledHandling")(A6, 1),
      'A7': require("ledHandling")(A7),
      'B1': require("ledHandling")(B1)
    };
    E.on('init', function() {
      USB.setConsole();
      console.log('started');
      L.LED1.On();
      //INIT_OPTIONS.ISSTART = 1;
      setTimeout(wifiOn, 1000);
    });
    var wifiOn = function(){
      console.log('starting WiFi');
      console.log(WIFI[INIT_OPTIONS.WIFI][0] + ' - ' + WIFI[INIT_OPTIONS.WIFI][1]);
      wifi.connect(WIFI[INIT_OPTIONS.WIFI][0],­ WIFI[INIT_OPTIONS.WIFI][1], function(err) {
        if (err) {
          console.log("Connection error: "+err);
          L.LED1.blink(50);
          setTimeout(wifiOn, 60000);
          return;
        }
        console.log("WiFi connected!");
        L.LED1.On(0); L.LED2.blink(100);
        for (var i in INIT_OPTIONS.HOSTS) {
          setTimeout(ccon, 5000 * i, INIT_OPTIONS.HOSTS[i]);
        }
      });
      return;
    };
    /*********
     FLOW-Sensor
     **********/
     var flowSensor = [];
     flowSensor[0]  = require('water-flow').connect(A0, {measurePeriod: 5});
     flowSensor[1]  = require('water-flow').connect(A1, {measurePeriod: 5});
    

    I can't see anything in there that'd cause problems either - unless there was loads of water (100ml/sec) flowing through your water flow sensors.

    Can you try calling require("Storage").eraseAll()? It's possible that you had some code saved (with 'save on send, even after reset') that's doing something in the background that is causing problems.

  • Big thanks for your respond. I will have a look on the problem on weekends and will try to determine the problem more precisely.

  • I just inlined

    Hi Mr. Gordon,
    I don't know but your code is not uploading to my module (Web IDE 0.68.6, firmware 1.97) because inlined module could not be found. I tryied different minification settings but I have not found the way to upload the code.
    Regarding errors:
    1.98 solved the problem with TCP client
    1.98 (as 1.97) I still can not use pins for reading data. I start water-flow module with delay of 50000 ms to let WiFi establish connection. But when I create water-flow sensors in couple of seconds I receive FIFO_FULL message.
    I'm not profecial programmer, where should I use this: require("Storage").eraseAll()?

  • Hi again,
    Update, probably the problem with FIFO full solved.
    What I did.

    1. I added require("Storage").eraseAll() to the E.on('init', function()...
    2. I changed sensor settings to
      flowSensor[0] = require('water-flow').connect(A0, {measurePeriod: 50});
      I guess the problem that to many data come to the module. Now I clear the cash and recieve less bytes per second.
      The module started to work propely! Great!
  • Great! Sounds like there was already some code in memory from something else that might have been keeping Espruino too busy.

    where should I use this: require("Storage").eraseAll()?

    All you need to do is copy&paste it on the left-hand side. No need to add it to onInit as that'll remove any saved program code on boot (so if you power off & on the WiFi the code will be gone).

  • So, finally I did a lot of different tests with Amperka library.
    I can not fully avert "FIFO_full" error. But I managed to adapt my code (exclude some options) to avoid crash of WiFi connections.

    1. I start initialisating of sensors with delay after the module has established connection to the server
    2. I do noy use on "pulse" listener. I suppose this function consumes lots of memory
      flowSensor[0].on('pulse', function () {})
  • I would maybe avoid calling flowSensor[0].on('pulse', function () {} at all, even if the function has no code.

    It looks like Amperka's library isn't expecting the number of pulses per second that you are getting from your sensors. In fact looking at it the whole thing is really inefficient if you have even 100 pulses/second.

    You could just try using something like this instead:

    function waterFlow(pin) {
      var lastPulses = 0, pulses = 0;
      var total = 0;
      pin.mode('input_pulldown');
      setWatch(function(){pulses++},pin, {repeat: true, edge: 'rising'});
      setInterval(function() {
        total += pulses;
        lastPulses = pulses;
        pulses = 0;
      }, 10000);
      return {
        volume : function() { return total; },
        speed : function() { return lastPulses; }
      };
    };
    

    Although you'd have to apply some scale factors to volume and speed.

  • You could just try using something like this instead

    Thanks, It's quite simple and more clear for me.
    I implemented the code, but after some time I again recieve "New interpreter error: FIFO_FULL"
    It's important to mention that no sensors are connected to the pins (I do testing at home without any sensors) A0 and A1

  • It's important to mention that no sensors are connected to the pins

    Wow, ok. I must have missed that - that is very surprising then.

    So you're saying that if uploading the code from here: http://forum.espruino.com/conversations/­320598/#14228511

    Just leaving the board alone for a few minutes will cause a FIFO_FULL message? Or is there some other code I could upload to a bare Espruino WiFi to see if I can reproduce it?

  • Just leaving the board alone for a few minutes will cause a FIFO_FULL message?

    Well, After I have looked at this topic http://forum.espruino.com/conversations/­311969/ I found that there is also some logic for FIFO_FULL message to appear in my case. What I do?
    My server sends TCP request to Espruino to get consumption statistic from water-flow sensor.
    After I read data from the variable (flowSensor[0].volume()), I send data to console.log and back to the server in JSON-format through TCP connection.
    So I suppose the problem arise when simultaneously three functions execute their commands: setWatch, console.log, socket.write
    I need more tests to locolize the problem, but for now it works for 20 hours with a real waterflow sensor connected to the pin A0 with this change in the code: I execute socket.write("JSON formated data") with a delay of 200 ms.!
    If I occasionaly send simultaneously 2 TCP requests in a row, I will get FIFO_FULL error because to many instances of functions will occupy the input buffer

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

Two troubles with new 1v97 v on EspruinoWiFi

Posted by Avatar for Vladimir @Vladimir

Actions