Avatar for allObjects

allObjects

Member since Jul 2014 • Last active Feb 2023

Espruino makes IoT as easy as 123!

Most recent activity

  • in Puck.js, Pixl.js and MDBT42
    Avatar for allObjects

    Static discharges could be an issue... capacitors can help, worst case you have to add 'transient arrestors'... but from your setup I would expect that nothing ever can touch the blank wires of your thermistor.

    Sinc you do not show any code, it is difficult to make some comments about why a puck would completely crach. I could think of some issue in setTimout() / setInterVal() usage that could lead to buffer overruns. But that is a wild guess...

  • in Projects
    Avatar for allObjects

    Hi, skimmed over your code... noticed several things... some are coding conventions which do not break the code but make it more difficult to build a mind map - map the code in the mind for grasping. Beside that, I noticed your Polygon = [] and its population w/ values for drawing. I could not figure how many points you add, but you have to be aware of the limit it has. Your may have too many points. Not all all drawn which could explain the missing parts. To get thru a polygon with too many values, you have to break it up into multiples to compose the final one. See Swiss Federal Railway Clock modeled w/ Circular Gauges. It's less about the clock, it is about the circular gauges: I use some algorithm to compose a partial circle (arc) drawn using polygons by actually drawing multiple segments of that partial circle (arc)... (the full circle is just a partial circle / arc of 360 degrees).

    Addendum: see g.drawPoly/fillPoly have a limit of 64 nodes - Your Color wheel.js uses 72 segments... which puts you already 12+% beyond the max limit. To achieve that: think about drawing two circles using Espruino's Graphics method .drawCircle(): draw the outer circle, and then clear the inner portion with another one... That way you take advantage of the best resolution with the highest speed.

  • in Projects
    Avatar for allObjects

    If you establish some pattern beforehand, you can pick by algorithm or random and push out as @Gordon sugget. When you want to move things around within chosen pattern or splice things together, you can use algorithms written in C, as I did in Efficiently moving things around in zig-zag Graphics buffer visualized w/ 24/32 bpp displays / neopixel strings. The referenced example uses the graphics buffer that is suppoted with graphics functions. The graphics functions are used to write to the buffer, and an intervalled process writes it out to the LED string(s). The arrangement of your LEDs are like the surface of a cylinder which is just lime a bent dot matrix screen on which you can draw things on.

  • in Puck.js, Pixl.js and MDBT42
    Avatar for allObjects

    Searched for this... did not found it until later, after I created a duplicate of this issue...

    Puck.js FW 2v16 not recognizing HW V1 magnetometer MAG3110, thinks it's Puck Lite 1 HW

    ...fun!

    (tested 2v00, 2v06 (was on before update), 2v11, 1v14: all okl from 2v15 on it's broken; using 1v14 until 2v17 will be out)

  • in Puck.js, Pixl.js and MDBT42
    Avatar for allObjects

    Oops...

    ...found duplicate at Puck.js v1 on 2V16 - magnetometer not recognised...

    Search is really not working in forum, and googling was not of much more helpful...

    (using 1v14 until 2v17 will be out)

  • in Puck.js, Pixl.js and MDBT42
    Avatar for allObjects

    I updated a Kickstarter Puck.js w/ most recent FW 2v16 using online Web IDE. Running the default code

    Puck.magOn();
    Puck.on('mag', function(xyz) {
      console.log(xyz);
    });
    // Turn events off with Puck.magOff();
    

    complained in the console:

    >
     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     2v16 (c) 2021 G.Williams
    >
    Uncaught Error: Magnetometer not available on Puck.js Lite 1
     at line 1 col 12
    Puck.magOn();
               ^
    > 
    

    (Definitively not a battery level issue...)

    After installing from url 2v00 - the oldest listed on the site for previous versions http://www.espruino.com/Download - above code works.

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     2v00 (c) 2018 G.Williams
    >
    { "x": -3341, "y": 3017, "z": 1275 }
    { "x": -3393, "y": 3067, "z": 1298 }
    { "x": -3398, "y": 3064, "z": 1299 }
    { "x": -3397, "y": 3067, "z": 1294 }
    

    2 questions:

    1. What is the newest verson that still recognizes the MAG3110 on my Kickstarter Puck.js V1? (*
    2. What can I do to make 2v16 recognize the MAG3110 on my Kickstarter Puck.js V1?

    *) Looks like 2V14 is last one that works... (worked thru 2v06, was on before update, then 2v11, then 2v14: all ok; 2v15 shows same issue as 2v16).

  • in News
    Avatar for allObjects

    Merry Christmas to you, Gordon!

    Second ...amazing how far we've come with Espruino... - not doing much Espruino lately, but just pulled one of my pucks from kickstarter - V1, indeed - and flashed rom 2v06 to 2v16: smooth and uneventful using the IDE from Web. It can't get easier(*). This tells a lot. Not only Bangle has matured: Whole Espruino Ecosystem is a joy to play (work) with.

    Enjoy your time off, @Gordon; I'll look down on you tomorrow! Taking a break as well and Christmas w/ Family after years.

    • ao

    (*)Getting the Coin Cell out is now the most difficult thing! - Haha....

  • 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 ]
    > 
    
Actions