Espruino 1v81 released

Posted on
  • This one's been a while coming too, but there are some great features:


    ReferenceError is an error that now occurs when you use a variable before it has been defined. It's a standard part of JavaScript, but it may cause you problems if you're trying to upload code that worked on 1v80.

    All you need to do to fix it is to define variables before you use them with var myVariable. It's really worth it though - it'll make it far more likely that you'll find any bugs in your code.

    Better Ctrl-C behaviour

    Ctrl-C actually does useful things now - for instance if you do setInterval("a £%^& error",10) you'll get your console full of error messages... But now, if you hit Ctrl-C, the offending interval will automatically get removed!

    Pico Power consumption

    With deep sleep turned on, Pico power consumption is now down to 20uA!

    Software PWM

    You can now do PWM on all pins, including the LEDs.

    You just have to explicitly enable it with analogWrite(LED1,0.1, {soft:true}).


    Yep, Espruino now has a built in GDB-stytle debugger. For instance you can run:

    while(1) { LED2.set();LED2.reset(); }

    And can then press Ctrl-C and you'll enter the debugger, where you can step through statement by statement!

    See for more information.


    This is like dump() but it dumps the state of the interpreter to a String - so for instance you can now take that string and write it to a file or send it over the internet!

    pin.getInfo() and Serial/SPI/I2C.find(pin)

    This allows you to get more information about pins out of Espruino. For instance do you want to know LED2's output register address? try:

    poke32(LED2.getInfo().out_addr, 1);

    Or maybe you want to find out what SPI port is on B15? SPI.find(B15)

    E.on('init', ...)

    It used to be that if you wanted to run something when Espruino started, you had to make a function called onInit. Now, you can write several different init handlers:

    E.on('init', function() {
      console.log("Hello World!");

    While it's slightly more fiddly, it means you can now copy and paste multiple bits of code, and their init handlers won't overwrite each other. For instance modules can now add init handlers, so things like LCDs could even auto-initialise themselves.

    And there's plenty more too - More specific info in the ChangeLog

  • 20uA for deep sleeping Pico - incredible... thats 0.02mA = 0.00002A!

    And the icing on the cake: debugger!

  • I read the docs on E.on('init') here­it and I'm not getting "it". If I write a JavaScript, surely the script runs at line 1 onwards and hence if I wanted initialization functions, I would explicitly execute them from my script?

    Now, if I was to "guess" what is going on, what we are saying here is that E.on('init') causes functions to be registered which are saved in the "state" when a JavaScript program is saved to flash and are run when it is load from flash? Is that close to being correct?

    If so, I think we need a page of documentation (if it doesn't already exist) that describes the philosophy of save and load of programs and the state that is maintained. This would then want to be referenced in the docs for E.on('init').

  • @Kolban, the E.onInit() enables the composition of applications form independent modules and each of these modules may have some init code that has to run on (re-)power up (after having saved the code). So far, there was only one single onInit() function. That function would then have to be application composition specifically implemented. With the arrival of E.onInit(), this responsibility can now be delegated to the module itself by placing E.onInit() into each module.

    I though still have questions about how it is done when this E.onInit() code - process - needs configuration information - data - that is specific to the app - or the composition - of the set of modules. If sequencing matters - because one module may need references / data from antoher one and this reference / data becomes only available through onInit() - the old fashiioned single onInit() function may still apply. Promises can work too, but they do not have sequence in it. Therefore, I came up with a tasker as layed out in the Tasker - Task synchronizer - kind of a 'purposed' Promise conversation. The Tasker has retry options to allow for variations in timing of things....


    But it's worth reading through all the language stuff there anyway, and also the Notes page

    (sorry for the caps, it's the way the titles copy+paste :)

    Basically when you click 'upload' your script is executed on Espruino - it's not stored. When you say save it saves away the current state of everything. That's actually really important difference between Espruino and other things.

    Perhaps there should be links, but lots of things lead you to onInit/E.on('init',...) - for instance load, save, and all the stuff above. Generally you will have found out about onInit because of those.

  • @Kolban would it help if there was a version of the Espruino documentation that could be downloaded as a book, and read through end-to-end?

    I think it's getting to the stage where there's so much documention there now that people just aren't finding the important bits.

  • @Gordon There's a lot on this site for sure and sometimes you can't find way back to stuff you know you've read before. Book would be useful to many, particularly as it would probably order the process of getting up and running with Espruino through to the intermediate to advanced stuff. Big time sink though and I suspect you're not short of stuff to be doing :)

  • Maybe just getting all the pages of documentation into the site's menu would be enough?

  • Which menu? It'd be insane if they were all down the left hand side :)

    There's the Tutorials and Examples page, but that doesn't have everything.

    It'd definitely be worth having a 'table of contents' kind of page. Might be a good start for trying to organise everything ready for a printable book as well?

    As @Ollie says I have a whole load of stuff to do right now (especially with a talk and then Maker Faire Rome next week), so if anyone fancied trying it... :)

    It should be pretty easy to add something to the root of EspruinoDocs - if you look at you can include pages by keyword (eg. the actual hardware devices), then it's just a matter of getting the actual 'reference' stuff linked in by hand. There's probably a load of duplication/mis-filed stuff too now :)

    ... we could add an APPEND_EVERYTHING_ELSE keyword to the site builder as well, which would help to pick up unreferenced pages.

  • @Gordon ... personally, I'm a big fan of books in PDF format ... so yes to a book. I believe you like the notion of the documentation of a product to be self generating but my own opinion and experiences point in the other direction which is to have a separate book that is kept in sync manually. I would also suggest that any such book be "one file" (eg. an open document .odt file). That way there can be easy cross reference and searching and linking and such.

  • You're not going to convince me about non-auto-generating the documentation I'm afraid.

    If someone just copy/pasted all of the pages from into a .odt file it'd be out of date by November, and downright misleading by January next year :)

  • The main thing I find missing in a decent TOC for the web site. Some pages like internals and performance are really hard to find. The reference page also needs some love , for example, in day-to-day use I would prefer the first "page" to have a multi-column index so I can immediately click on the class I'm looking for.
    +1 On automatically generated docs. What I to look into for myself is how to write high-level comments in the source files so they get picked-up by doxygen.

  • Hi @Gordon,
    I attempted to use debugger() within a function invoqued at load time and found that the remaining of the uploaded file was "used" or, may be "consumed " out of the file being uploaded. This is not what I intended...
    Is this behaviour "normal " ?
    How can I debug in such a case?

    I subscribe to an automatically generated document, knowing that this forum, and now gitter discussions, do contain useful informations, about all the oddities any user might face.

  • Nice one, thanks. Is it possible to use Pin.getInfo (or something else) to find out if given pin is PWM -able?

  • @Gordon is there a way to get linenumber in debug output ?
    I'm testing how to get a simple debugger as plugin for webIDE.
    Right now it's more or less a collection of buttons, replacing typing commands, so nothing fancy.
    It would be a big help, to get linenumber for highlighting in editor-window.

  • @tve thanks - nice idea about the multi-line contents... I wonder if there's a nice way to do that with HTML?

    @asez73 ahh - no, you can't debug code that's run right as you upload it. Easiest way is just to run it after you've uploaded - either by manually typing the function name, or by adding a setTimeout.

    @Rollo yes - you're looking for whether it says TIM# under the list of functions that gets returned...

    @JumJum unfortunately no - Espruino doesn't know what line number anything is, as it's just uploaded in-line. I was trying to think of a nice way to handle that, but I'm not sure how :)

  • @Gordon, thanks, I had not thought to the timeout approach.
    Yet, it won't solve my problem as I am really running out of ram. I need to execute the function in question before any other thing which I placed in the following lines of the code, I then delete my function factory so as to end up the object's events handlers.
    Could it be possible to have a functionality to load files from the web ide on demand from the espruino board through USB connection?
    Obviously the web ide and the interpreter would have to be tightly integrated.

  • Line # require source maps - generated on upload - if you do not want to spend memory for every line in the running code. Source map are also useful to solve the problem of code coming from different modules. To handle the display, the editor could be used, but it should then have a multi-document interface. Debuging saved code adds another layer of requirements for infrastructure.

  • @asez73 I think that's pretty low down my priority list at the moment I'm afraid. Can you not just upload only the code that is giving you problems, and then run that with a Timeout in order to debug?

    Once the problem is solved, you can move to full code...

    But actually thinking about it - I don't see why a timeout makes your code use more memory? It'd still run as usual, do the calculations, and remove everything from memory (including the timeout) leaving you in exactly the same state.

    @allObjects a source map is an interesting idea... when a function is defined, Espruino could report back the 'JsVar ID', and the Web IDE could make a note of it in reference to the line number. Then, when debugging it could output JsVar ID+line+col and the Web IDE could work back.

    Espruino might be able to store a line number for each function, but I'm not sure whether functions in functions could get line numbers without being too slow.

    Of course as Espruino prints the whole line of text, the Web IDE could just search and match that line? There might be duplicates sometimes, but the most times it'd be able to figure out where it was.

  • I usually put setTimeout("delete onInit",500); at the end of my onInit, top get back the memory it used before the other timeout events it sets up that initialize things actually go off, so they have space to run (my desk light has to do this)

  • So how is everyone finding 1v81? There don't seem to be any glaring problems with it at the moment?

    I'm getting a new batch of Original Espruino boards made soon - anyone see any issues with flashing them with 1v81? I think the current versions ship with 1v62 or something, so could really do with an update!

  • Regarding source map and finding back into it: to my understanding, uploaded code is stored by Espruino at a particular 'source code location|address. That address of course has to be returned back to the IDE which can write the information to the map. Knowing the interpreter's pointer - program counter - at runtime and returning it on break point, that would be frequent enough. Dynamically created code for which no uploaded code and map to source exists, Espruino would have to send the dynamically created code code back to the IDE and presented as best as possible.
    If things happen to be in RAM and moved around, it get's pretty diare... on the other hand, apploading in function junks and providing an upload-time ID for the function could solve that problem.

  • Hi @Gordon, @DrAzzy,

    Yes I did the dev that way. I mean load only a part of the code and check it's functionnalities.

    However some bugs appeared since I tried to shrink down my code and changed it again.
    The problem arrises due to the fact that not all the source code can be loaded at once, even without launching anything. It has to be partly executed before the remaining part of the code is evaluated.

    A complementary need would be to use more than one source file from the webide, having a 3rd window so that I could choose what to upload easily. That's not a priority, I agree.

    The real solution is elsewhere: Use some code from flash directly, which, i guess, is on the trend of the ESP8266 and partly answered in some other discussion.

  • Hi, sorry I'm late to the party.
    Is the software PWM and the debugger available for the original espruino board too?


  • Yes, absolutely! Just update the firmware to the latest and you'll get it, as well as software I2C and SPI that have been added since 1v81 :)

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

Espruino 1v81 released

Posted by Avatar for Gordon @Gordon