Avatar for allObjects

allObjects

Member since Jul 2014 • Last active Nov 2017

Very excited about Espruino! JS is just a great, universal language that - for me - implements - thank's @Gordon on an ARM3/4/... MC and with a Web IDE - all essential programming concepts there are and makes them easy to use, including the hardware access. My relationship with The Flintstones is about the same as Espruino and Arduino..., or JS and C... not that C-like things are not of use or needed anymore, but I can get most of them close enough with compiled JS.

Most recent activity

  • in Projects
    Avatar for allObjects

    ...powered by Espruino.com - designed by @Gordon Williams!

    Great gadget... even with prototyping area...

    ...adding connectors to the prototyping area makes it a development board... ;-)

    Congrats, @Gordon

  • in Pico / Wifi / Original Espruino
    Avatar for allObjects

    Glad it's working for you...

    I never use the setting for save on upload... lat but not least this - in my biased view -was an afterthought to appease the Arduino tooling behavior... because it also runs down the flash EPROM... (of course, 10K writes or what ever it guarantees is a lot... but not that much for my micro-incremental dev style). Only once in a while and when I'm done I go for the save().

  • in Pico / Wifi / Original Espruino
    Avatar for allObjects

    @bosscube, could you elaborate on:

    Each time I reset the Espruino WiFi,...

    Could you list the step you perform to get there?

    Good practice is to put the onInti() into a setTimeout() in order to let the upload complete in it's own thread-share.

    setTimeout(onInit,1000);
    

    If you consider saving the code (with save()), remove this setTimeout(onInit,1000);, upload the code again, and then perform the save() in the console.

  • in Puck.js
    Avatar for allObjects

    This is just the way it works. Devices can only have one connection at a time. They advertise when they are not connected to another device. When they are connected, advertising stops.

    Not having immersed myself much into Bluetooth/BLE, this question popped-up for me:

    Can a device scan between (individual) advertisements? I know that the purpose of advertising is to say I can be connected to... and that would be not possible while a device is scanning and I know that scanning is a comparably time-consuming / lengthy / power-consuming.

  • in ESP8266
    Avatar for allObjects

    In code in post #10

    function onPageRequest(req, res) {
      var a = url.parse(req.url, true);
      res.writeHead(200, { 'Content-Type': 'text/html' });
      res.end(page);
      if (a.query) b = a.query;
    }
    

    I would change the sequence to do the request processing first (lines 2 and 5), and then the response (lines 3 and 4):

    function onPageRequest(req, res) {
      var a = url.parse(req.url, true);
      if (a.query) b = a.query;
     // ...more of request processing
      res.writeHead(200, { 'Content-Type': 'text/html' });
      res.end(page);
    }
    

    On a side note: Using single quote (') instead of double quotes (") for coding html fragments as literal Strings makes life much easier (and code much more legible): you do not need to escape the double quotes ("). Furthermore, you do not need the carriage returns and line feeds / new lines (/r, /n) in html source. This helps you preserve memory of which you are usually anyway in short supply... last but not least, mutli-line literal strings that recently became available helps even more with legibility: ;)

    var page = '<!DOCTYPE html><html><body>
    <form action="" method="post">
    First name: <input type="text" value="" name="fname"><br>
    Last name: <input type="text" value="" name="lname"><br>
    <input type="submit" value="Submit"></form>
    <p>Click on the submit button, and the input will be sent to Espruino.</p>
    </body></html>';
    

    In 1st code in post #11:
    if it is not a GET, you cannot assume that it is a POST since there are other valid http verbs/methods. Interestingly is that - last time I checked - request.method returns for method (erroneously) always "GET". Only parsed url returns the actual method!

    For some GET/POST discussion, take a look at Testing SW from Espruino book, ....code from page 246 (Espruino Pico+ESP8266).

  • in ESP8266
    Avatar for allObjects

    Here the complete code:

    // robot2.js
    var lon = false;
    var pag='
    <html><head><style>
    td {text-align:center; vertical-align:middle; }
    </style>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script>var ifrm;
    function eb(b) { ifrm.src = "/ifrm.html?e=" + b.id; }
    </script>
    </head><body onload="ifrm = document.getElementById(\'ifrm\');">
    <h3>Hello from <i><b>robot!</b></i></h3>
    <table width="100%"><tr>
    <td><button id="le"  onclick="eb(this)"><br>LEFT EYE<br><br></button></td>
    <td><button id="be"  onclick="eb(this)"><br>BOTH EYES<br><br></button></td>
    <td><button id="re"  onclick="eb(this)"><br>RIGHT EYE<br><br></button></td>
    </tr><tr>
    <td><button id="lb"  onclick="eb(this)"><br>LEFT BLINK<br><br></button></td>
    <td><button id="bl"  onclick="eb(this)"><br>BLINK<br><br></bu­tton></td>
    <td><button id="rb"  onclick="eb(this)"><br>RIGHT BLINK<br><br></button></td>
    </tr></table><table width="100%"><tr>
    <td><button id="s-3" onclick="eb(this)"><br>-f<br><br></butto­n></td>
    <td><button id="s-9" onclick="eb(this)"><br>-m<br><br></butto­n></td>
    <td><button id="s-27"onclick="eb(this)"><br>-s<br><b­r></button></td>
    <td><button id="s+0" onclick="eb(this)">Antenna<br>Spin<br>ST­OP<br></button></td>
    <td><button id="s+27"onclick="eb(this)"><br>+s<br><b­r></button></td>
    <td><button id="s+9" onclick="eb(this)"><br>+m<br><br></butto­n></td>
    <td><button id="s+3" onclick="eb(this)"><br>+f<br><br></butto­n></td>
    </tr></table>
    <iframe id="ifrm" width="100%" height="30"></iframe>
    </body></html>
    ';
    
    pinMode(LED1,"output");
    pinMode(LED2,"output");
    pinMode(A0,"output");
    pinMode(B0,"output");
    var WebServer = require('WebServer')
      , wifi = require('EspruinoWiFi')
      ;
    function onInit() {
      if (wifi)
        wifi.startAP('robot', {
          authMode:'open', password:'password'
        }, startServer);
      else
        startServer();
    }
    
    function startServer() {
      var ws = new WebServer(
    { port: 80
    , file_system: '/var/www/'
    , memory:
    {'index.html':{'type':'text/html','conte­nt': pag }
    ,'ifrm.html':{'type':'text/html','conten­t':
        '<html><body>e: XX</body></html>' }
    }});
    ws.on('start', function (WebServer) {
      if (lon) console.log('WebServer listening on port ' + WebServer.port); });
    ws.on('request', function (request, response, parsedUrl, WebServer) {
      var e = (parsedUrl.query) ? parsedUrl.query.e : null, v;
      if (lon) console.log('WebServer requested', parsedUrl, response, "e="+e);
      if (e=="le"||e=="be") { v = !digitalRead(LED2);
        digitalWrite(LED2,v); digitalWrite(B0,v); }
      if (e=="re"||e=="be") { v = !digitalRead(LED1);
        digitalWrite(LED1,v); digitalWrite(A0,v); }
      if (e=="lb") { setTimeout(blnkl,50,13); }
      if (e=="bl") { setTimeout(blnkb,50,9); }
      if (e=="rb") { setTimeout(blnkr,50,13); }
      if ((e+" ").substr(0,1)=="s") { var s = Math.round(1 * e.substr(1));
         s=(s<0&&s>-3)?-3:(s>0&&s<3)?3:s; e="s"+s; r(s); }
      response.dSnd = response.dSnd.replace("XX",e);
    });
    ws.on('error', function (err, WebServer) {
      if (lon) console.log('WebServer error', err); });
    ws.createServer();
    }
    
    function blnkl(c) { var v;
      v = !digitalRead(LED2); digitalWrite(LED2,v); digitalWrite(B0,v);
      if (c) setTimeout(blnkl, 50, c - 1);
    }
    function blnkb(c) { var v;
      v = !digitalRead(LED1); digitalWrite(LED1,v); digitalWrite(A0,v);
      v = !digitalRead(LED2); digitalWrite(LED2,v); digitalWrite(B0,v);
      if (c) setTimeout(blnkb, 50, c - 1);
    }
    function blnkr(c) { var v;
      v = !digitalRead(LED2); digitalWrite(LED2,v); digitalWrite(A0,v);
      if (c) setTimeout(blnkr, 50, c - 1);
    }
    
    // mirror stepper code from http://forum.espruino.com/comments/12187­872/
    // stepper.js
    // stPs stepper pins
    // st   step 0..8
    // stT  step Time in milliseconds [ms]
    // stI  step Interval (from setInterval() and for clearInterval()
    // sts  steps 0001,0011,0010,... pin signals
    // stBW sts - steps Backwards
    // stFW sts - steps Forward
    // dmy  ...because of (cond) ? exprT : exprF needs something to assign to
    var run = false;
    var st = 0;
    var stT = 0;
    var stI = null;
    var sts = null;
    var stSt =  0b0000;
    var stFW = [0b1000,0b1100,0b0100,0b0110,0b0010,0b00­11,0b0001,0b1001];
    var stBW = [0b1001,0b0001,0b0011,0b0010,0b0110,0b01­00,0b1100,0b1000];
    var stPs = [A4,A5,A6,A7];
    
    // setI setInterval(i,stsC) i in [ms] with (optionl) step Change (if not null), 
    // and direction info (string)
    var setI = function(t,stsN,d) {
      if (lon) console.log("t = ",t, d); 
      if (stI) clearInterval(stI);
      if (stsN) sts = stsN;
      run = true;
      stI = setInterval(stp,t);
    };
    
    // stp step
    var stp = function() { digitalWrite(stPs, sts[st = ++st % 8]); };
    
    // _sFW step ForWard
    var _sFW = function(t) {
      if (lon) console.log("FW w/ " + t);
      if (stT > 0) { setI((stT = t),null," ~F");
      } else { if (stT) { st = Math.abs(st - 7); } if (!stI) { st--; } setI((stT = t),stFW," FW"); }
    };
    
    // _sBW step BackWards
    var _sBW = function(t) {
      if (lon) console.log("BW w/ " + t);
      if (stT < 0) { setI(-(stT = t),null," ~B"); 
      } else { if (stT) { st = Math.abs(st - 7); } if (!stI) { st--; } setI(-(stT = t),stBW," BW"); }
    };
    
    // stop
    var stop = function() {
      if (lon) console.log("stop");
      if (stI) { stI = clearInterval(stI); stI = null; }
      if (lon) console.log(stI);
      run = false;
      digitalWrite(stPs, stSt);
    };
    
    
    // run function - t is stepping interval in [ms]
    var r = function(t) {  
      if (typeof t === "undefined" ) {
        if (stT) {
          if (lon) console.log((stT > 0) ? "F>B" : "B>F");
          r(-stT);
        } else {
          if (lon) console.log("What ?");
        }
      } else { 
        dmy = (t) ? (t>0) ? _sFW(t) : _sBW(t) : stop(); 
      }
    };
    

    The page has an iFrame which was used as the communication vehicle (sending a get with parms in line 9 by setting the iFrame's source (url) and url.parse in lines 61..71) so that not the whole page has to be loaded again, and also use a simpler approach than XHTMLRequest / POST / body work... It was all put together in a few hours on Sun afternoon...

  • in ESP8266
    Avatar for allObjects

    In extra post I will provide you with code from an active robot I made for my wife as stage partner for a kid summer camp themed 'Maker Fair'. The idea was to use recycled stuff... so some of my hunted and gathered items (and hoarded for decades -literally) re-found their destiny and purpose...

    The robot was blinking/flahing/steady lighting its eyes, rotating its antenna slow, medium, and fast (at one point it was also turning its head). Other options are left for the next opportunity, like driving around on his swivel wheels, moving its arms, and sensing and talking.... In the picture the - just taped on - electronics have been removed (shown in separate shot, also attached). The attached clip robotAction.mp4 shows some action...

    A Espruino-Wifi was all in one: independent Wifiu Access Point, Web Server, and Robot controller. Any Wifi device / phone can drive it through browser Web page interface.

    For driving/flashing the heavy LED lights for the eyes I used @DrAzzy 's MOSFETs from Tindies, for the Antenna (and Head Turning) I used some cheap, geared steppers. The Head Truning was done with 3 wheels running around, one driven (as shown with the 3d printed wheel... unfortunately, it had not enough grip and one driving stepper was not reliably turning / sufficient). As power supply I used these battery banks you get cheap. They can easily push some real Amps...

    The controlling Web page was just buttons with some javascript on click.

  • in Electronics
    Avatar for allObjects

    Check this ti / Texas Instruments DRV8835 out (Pololu Banana Robotics, also Adafruit)... The chip is built for low voltage driving / operating down to 2 Volts, max 11 (12) Volt motor power supply. Adafruit has also a version for higher Voltage: Toshiba TB6612 - TB6612 Datasheet. The breakout board is a bit fat compared to Puck and the Instrument Stepper, but gluing just a chip to the back of the stepper and doing some 'air-wiring' will get you down to the 'format' you are(?) looking for.

  • in ESP8266
    Avatar for allObjects

    Take a look at @ClearMemory041063's post:
    Processing POST using Forms.

    For very simple forms you can - client-side - on 'post' grab the data from the form fields and add it as url parms to a get url and do a get and then use - server-side - url.parse...

  • in Electronics
    Avatar for allObjects

    That's asking a lot of drive from a puck...

    Looking at nRF52832 SoC (puck's heart, section 20.4 Electrical Specification p151ff, a 'high-drive pin can source/sink about 15/14mA within specified voltage range. This is barely handling the resistive load of one stepper coil, which for 300R is about 15mA. Another limit is the total drive/sink current a chip's IO system can handle (all outputs together because of 'internal wiring' and dissipation limits).

    To give you some ideas, check GPS powered by Espruino pin(s) out. It is not exactly what you are trying to do, but it gives you some feel what MC pins can do...

    Because of the challenges inductive loads pose, I would them always drive with a driver chip... that's what they are there fore in the first place, and not with a MC pin, especially when having to supply switching polarity, I guess (and not just pull down a coil at one end of which the other one is connected to supply voltage).

    Next challenge is facing the limited capacity of the coin cell... you will pull (resistive) about 30mA from a 220mAh capacity. Duty cycle - and how smart the control is implemented - will of course define what you get out of the coin cell. But may be you have additional powering in mind.

Actions