Avatar for allObjects

allObjects

Member since Jul 2014 • Last active Oct 2022

Espruino makes IoT as easy as 123!

Most recent activity

  • in Bangle.js
    Avatar for allObjects

    Using @fanoush 's code imbedded in your app, the convenience singleton object for handling all RSSI stuff could look like the code below. Working thru the example you will notice that Espruino / JavaScript is completely event driven... and you can take advantage of that even in application components you write. No need to burn cycles like famous (NOP) wait loops do... ;)

    NB: Things - such as NRF.setRSSIHandler() setting method - not available in your environment - emulator or html doc in browser? ...just fake/emulate it 'intelligently' - see lines 59..71 to get meaningful values for (cross) developing and test your logic... Same goes for the missing on() and emit() for plain browser js objects - see lines 72..77. With these 'complements', the very same Espruino code runs in html5 document in browser. The html document is attached to the post, just click on its link... ;) --- *click on the second attached html / link* - first one has issues and I could not delete it because forum has issues on edit with loading... / deleting of attachments). HTML code is shown below the Espruino code.

    // for logging convenience
    var lon=0, log=function(){console.log.apply(console­,arguments);};
    
    // rssis singleton object handling all RSSI matters encapsulated
    var rssis =
      { history:   [] // [date,value] tuples of samples
      , maxHist:   10 // max count averaged samples in history
      , intTime: 5000 // ms interval time of sampling
      , samples:    5 // count of raw samples for for averaged sample
      , _intId:     0 // interval id for start/stop control
      , _cnt:       0 // for sampling control
      , _sample: function() { // --- takes samples and stores in history
          var sum = 0
            , cnt = this.samples
            , avrg, hEntry;
          NRF.setRSSIHandler((data)=>{
              lon&&log("C:",data,this._cnt);
              sum+=data;
              if (--cnt<1) {
                NRF.setRSSIHandler();
                hEntry = [new Date(), avrg = sum/this.samples];
                this.history.splice(0, 0, hEntry);
                if (this.history.length>this.maxHist) this.history.pop();
                this.emit('data', avrg, hEntry, data, this);
              }
          } );
      }
      , start: function(clearHistory,_rs) {  // --- opt clear history and take samples
          lon&&log("rssis.start",((_rs)?_rs:""), "clearHistory:", !!clearHistory);
          if (this._intId) { this.stop(); }
          if (clearHistory) { this.history = []; }
          this._intId = setInterval(this._sample.bind(this), this.intTime);
          return this.history.length;
        }
      , isSampling: function() {  // --- true when sampling, otherwise false
          return !!this._intId;
        }
      , getHistoryCnt: function() {   // --- number of history entries
          return this.history.length;
        }
      , stop: function() {        // --- stop taking samples
          lon&&log("rssis.stop");
          if (this._intId) { 
            NRF.setRSSIHandler(); // stops data handler in its tracks
            this._intId = clearInterval(this._intId); // stops sampling
          }
          return this.history.length;
        }
      , resume: function() {      // --- resume w/ not clearing history
          return this.start(0,"(resume)");
        }
      , dump: function(asHTML) { // --- return history as lines / html w/ <br>
          var x=-1,l=this.history.length,h,lines=[];
          while(++x<l){h=this.history[x];lines.pus­h(h[0].toString()+": "+h[1]);}
          lines.push(l); return (asHTML) ? lines.join("<br>")+"<br>" : lines;
        }
      };
    
    // to run in emulator or html5 doc in browser have this in place (roughly):
    var nrfDataEmulatorIntId=0; if (typeof NRF === 'undefined') { var NRF = {}; }
    NRF.setRSSIHandler = function(dataHandler) { // every 7 ms an emulated value
      if        (dataHandler && ! nrfDataEmulatorIntId) { lon&&log("P:start");
        nrfDataEmulatorIntId = setInterval((dataHandler)=>{
            var emulatedVal = Math.round((new Date().getTime() % 100) / 10) - 90;
            lon&&log("P:", emulatedVal);
            dataHandler(emulatedVal);
          },13,dataHandler);
      } else if (! dataHandler && nrfDataEmulatorIntId) { lon&&log("P:stop");
        nrfDataEmulatorIntId = clearInterval(nrfDataEmulatorIntId);
      }
    };
    if (typeof window !== 'undefined'){ lon&&log("in browser js/win"); // for html5 doc
      let addOnAndEmitTo=function(o,n){ lon&&log("add simple on/emit to "+n);o._eOE={}; 
        o.on=function(e,h){this._eOE[e]=h;};o.em­it=function(){var p=[],i,a=arguments,m,
        u; if(m=this._eOE[a[0]]){for(i=1;i<a.length­;i++)p.push(a[i]); m.apply(u,p);}}};
      if ( ! rssis.on) { addOnAndEmitTo(rssis,"rssis"); }
    }
    
    // catching rssis 'data'-event
    rssis.on("data",(avrg, historyItem, rawSample, rssisObj)=>{
      lon&&log("rssis 'data' event: ", avrg, historyItem, rawSample, rssisObj.getHistoryCnt());
    });
    
    // for dev acceleration 
    function onInit() {
      rssis.start();
    }
    
    // for dev acceleration
    setTimeout(onInit,999); // remove before upload for/with save()
    

    HTML document running the same Espruino code:

    <html>
    <head><title>RSSIs</title></head><body>
    <h3>RSSIs</h3>
    <p>Open inspector in develop tools and watch console...</p>
    <ul>
    <li><a href="#" onclick="rssis.start();" >start</a></li>
    <li><a href="#" onclick="rssis.start(1);">start with clearing history</a></li>
    <li><a href="#" onclick="rssis.stop();"  >stop</a></li>
    <li><a href="#" onclick="rssis.resume();">resume</a></li­>
    <li><a href="#" onclick="ao.h('dmp',rssis.dump(1)+ao.e('­dmp').innerHTML);";>dump</li>
    </ul>
    <hr><a href="#" onclick="ao.h('dmp','');">clear</a><pre id="dmp"></pre>
    <!--survival html5 --><script> var ao = { d: document
    , e: function(ioe) { return ("string"===typeof ioe) ? this.d.getElementById(ioe) : ioe; }
    , h: function(ioe,h) { var e = this.e(ioe); return e.innerHTML = h; return e; } }</script>
    <!-- rssis js from Espruino --> <script>
    
    // ... ... ... ... Espruino js code from above copied in here... ... ... ... 
    
    </script>
    </body>
    </html>
    
    

    The rssis singleton supports these 'methods' and other:

    • For start taking samples and store them in history, issue rssis.start();
    • To stop taking samples, issue: rssis.start();
    • To dump the history in the console (anytime), issue rssi.dump();
    • To access last data (any time, from the history):

      var h;
      if (rssis.historyCount>0) {
      h = rssis.history[0];
      console.log("RSSSI at", h[0], ": ", h[1])
      }
      

    ...or simply:

    console.log(rssis.history[0][1]);
    

    The objet even emits 'data' event when adding to the history with these parms (see line #s 24 and 60ff`):

    1. most recent averaged sample: avrg
    2. history entry: [date, avrg]
    3. most recent raw sample: data
    4. rssis singleton object

    This event can be listen to in the application in a similar way as rssis is listening to the NRF 'data' event:

    // catching rssis 'data'-event
    rssis.on("data",(avrg, historyItem, rawSample, rssisObj)=>{
      console.log("rssis 'data' event: ', avrg, historyItem, rawSample, rssisObj.getHistoryCnt());
    });
    

    With `lon=0' (logging turned off) you get only outputs like this in the console (most recent average rssi value, most recent history event with date and rssi average, most recent raw rssi sample value, and history count):

    rssis 'data' event:  -85 [
      Date: Tue Oct 4 2022 18:34:31 GMT-0700,
      -85 ] -86 1
    

    Setting lon=1 (turns logging on and) you get after uploading and console commands (latter indented) output on console like this:

    >
     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     2v15 (c) 2021 G.Williams
    >
    >
    rssis.start  clearHistory: false
    P:start
    P: -80
    C: -80 0
    P: -89
    C: -89 0
    P: -88
    C: -88 0
    P: -87
    C: -87 0
    P: -85
    C: -85 0
    P:stop
    rssis 'data' event:  -85.8 [
      Date: Tue Oct 4 2022 22:30:09 GMT-0700,
      -85.8 ] -85 1
    ----------------------->rssis.dump() // while sampling
    =[
      "Tue Oct 4 2022 22:30:09 GMT-0700: -85.8",
      1 ]
    P:start
    P: -80
    C: -80 0
    P: -89
    C: -89 0
    P: -88
    C: -88 0
    P: -86
    C: -86 0
    P: -85
    C: -85 0
    P:stop
    rssis 'data' event:  -85.6 [
      Date: Tue Oct 4 2022 22:30:14 GMT-0700,
      -85.6 ] -85 2
    P:start
    P: -81
    C: -81 0
    P: -89
    C: -89 0
    P: -88
    C: -88 0
    P: -87
    C: -87 0
    P: -85
    C: -85 0
    P:stop
    rssis 'data' event:  -86 [
      Date: Tue Oct 4 2022 22:30:19 GMT-0700,
      -86 ] -85 3
    ----------------------->rssis.stop(); // while sampling
    rssis.stop
    =3
    ----------------------->rssis.dump(); // while not sampling
    =[
      "Tue Oct 4 2022 22:30:19 GMT-0700: -86",
      "Tue Oct 4 2022 22:30:14 GMT-0700: -85.6",
      "Tue Oct 4 2022 22:30:09 GMT-0700: -85.8",
      3 ]
    ----------------------->rssis.resume(); // while stopped
    rssis.start (resume) clearHistory: false
    =3
    P:start
    P: -89
    C: -89 0
    P: -88
    C: -88 0
    P: -86
    C: -86 0
    P: -85
    C: -85 0
    P: -84
    C: -84 0
    P:stop
    rssis 'data' event:  -86.4 [
      Date: Tue Oct 4 2022 22:31:17 GMT-0700,
      -86.4 ] -84 4
    ----------------------->rssis.start(1); // while sampling
    rssis.start  clearHistory: true
    rssis.stop
    =0
    P:start
    P: -85
    C: -85 0
    P: -84
    C: -84 0
    P: -83
    C: -83 0
    P: -82
    C: -82 0
    P: -80
    C: -80 0
    P:stop
    rssis 'data' event:  -82.8 [
      Date: Tue Oct 4 2022 22:31:27 GMT-0700,
      -82.8 ] -80 1
    P:start
    P: -86
    C: -86 0
    P: -85
    C: -85 0
    P: -84
    C: -84 0
    P: -82
    C: -82 0
    P: -80
    C: -80 0
    P:stop
    rssis 'data' event:  -83.4 [
      Date: Tue Oct 4 2022 22:31:32 GMT-0700,
      -83.4 ] -80 2
    ----------------------->rssis.stop(); // while sampling
    rssis.stop
    =2
    ----------------------->rssis.dump(); while stopped
    =[
      "Tue Oct 4 2022 22:31:32 GMT-0700: -83.4",
      "Tue Oct 4 2022 22:31:27 GMT-0700: -82.8",
      2 ]
    > 
    
  • in Projects
    Avatar for allObjects

    Ic. Thanks for clarification. I think I get it: it is 'just' a SW replacement... nice! Like the Bangle.js watches: taking an existing hardware and software and replace the software. Very interesting. The word 'just' just does not do justice to the work you put in, even peeking at the Arduino implementation / its doc.

  • in JavaScript
    Avatar for allObjects

    Was thinking more along the lines of adding a ref pointer to variables. Of course this is not footprint friendly, but preserves source.

    Your replacement approach triggered another thought: in dbs, often a local index is built to save space. In code it would be a symbol index to keep the name / preserve the source but having a space to replace it on first run w/ a pointer into variable value space, that holds the value but would also hold also a pointer back to the index entry / name.

    I'm sure you already have though of many things, wandered down alleys... and kept sticking to what Espruino interpreter has come to this day. So no urgency to this.

  • in JavaScript
    Avatar for allObjects

    Speeding up variable lookup (and jump address lookup/'calculations') promise the most. Was there ever a thought to have something (changed) in the source that updates when the variable has been looked up? Of course that works only when the code is in RAM and a in/re-direction table that makes GC transparent? So it is not really a JIT compiler but more so an accelerator that does a lot of good especially in loops - similar to what pre-tokenzing does. An accelerator is not JIT compiler nor main stream, but Espruino isn't either. Such an accelerator would be unique and - after all - fit the uniqueness of Espruino (JS engine).

  • in Projects
    Avatar for allObjects

    #jeffmer, Bull's Eye! - That's all I can say...

    So: you got yourself such a device, ripped out the Arduino stuff and put in an Espruino w/ your code?

    I'm kind of curious to know whether there is still enough space left to have a Morse Code interpreter / decypher DX transmissions on SSB?

  • in General
    Avatar for allObjects

    ...here it is... it is in someone elses conversation New to Bangle.js and Espruino. Need help with graphics... Nov 2020

  • in General
    Avatar for allObjects

    Hit that limit a while ago... if your algorithm can handle a detection and cut-up in multiple 'touching' polys / segments, it is easy to live with the limitation.

    I had build a circular multi dial... and on a certain size with close to 360 degrees and expectation of decent smoothness of the 'bent bar'/bow, you run quickly into the limit. Luckily for me, I calculate max 30 points of a segment, note the angel and finish calculating the rest of the segment, draw it, and move on to the next segment until the desired angle is covered. Somewhere in the (difficult to search) forum you can find the code...

  • in General
    Avatar for allObjects

    Obviously missed this discussion / voting / weighing in...

    Not sure my comment changes much from point of view of liking or not liking github for discussion. These are the cons for the current forum:

    • not mainstream
    • created for discussing non-code things
    • no integration with a real repository
    • difficult, limited search
    • limited image integration
    • formatting has changed over time making a lot of my older, markup using entries unreadable

    I don't want to leave it at cons - and that may be reason for many to be content with the current forum:

    • easy to use for simple posts
    • file / image integration usually sufficient
  • in Puck.js, Pixl.js and MDBT42
    Avatar for allObjects

    @Jennygrist, what is the motivation to use a pico vs a puck? Pico has no communication. You would have to add that as a separate device. Just to mention one con.

  • in Bangle.js
    Avatar for allObjects

    @Gordon, what about the input controls on active overlay, especially the touch?

Actions