Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Espruino: JavaScript for Microcontrollers (github.com/espruino)
108 points by tosh on Oct 15, 2020 | hide | past | favorite | 53 comments


To answer those comments suggesting that low level language would be more fitted, im going to report my own exprerience. Two years ago, i went to FOSDEM where i met Gordon the creator of Espruino. I was curious about those littles devices and decided to buy one. Back at home, i started to play with my little device (pixl.js) and i was very enthousiast to use Chrome interface to start coding little program in Javascript, uploaded instantly via bluetooth on the device. It was fun, it was entertaining, and after a few keystrokes i was able to monitor room temperature, and display it on the lcd screen (which is totally useless i admit).

But the more i played with it, the more i became curious of MCU ecosystem, given the fact that im also a mechanical keyboard enthousiast, where teensy and stm32u2 have a central place in this community (esp. when you want to build your own keyboard).

So little by little, my Espruino experience gave me confidence to continue the travel, and after two years, i migrated mostly over ESP32 and RISCV mcu, coding in C, using vscode/platform.io, clone tones of github repo, trying to understand all the hardware concept, such as bus, serial, spi, i2c, timer, scheduling, packet radio with lora (running my own ttn gw, or controlling drone with opensource project such as ExpressLRS).

Espruino opens to me a new fertile world of MCU, helped me to step up the entry barrier and last year at FOSDEM, i meet again Gordon and thank him warmly for all of this.

(signed: a +20 years linux sysadmin, who always wanted to code a little)


> [...] i was able to monitor room temperature, and display it on the lcd screen (which is totally useless i admit).

How is that useless? We've been using such a device for a long time in society (replacing the mercury ones). Sure, nowadays with smarthome you can do it on a smartphone as well.

In my household we use a Honeywell for this (non-smart) and we have a smart device under it which shows the current weather and the forecast.

Furthermore, I bought an Enviro+ [1] plus a RPi Zero a while ago, but I still gotta implement/install it.

[1] https://opencircuit.nl/Product/Enviro-plus-for-Raspberry-Pi


It was more a figure of Style. I already had electronic temperatur sensor in my room. But anyway soon after, i switched to an esp32 and a bme680 to monitor temp/pressure/air quality/humidity, uploading data to thingspeaks though wifi, and graphing those data there.


I've been looking into this recently. The one complaint I've seen about the Enviro is that the pi's CPU throws off the temperature.


A high-level language like JavaScript certainly lowers the barrier to entry, and eases the learning curve.

This year I started playing with Raspberry Pi, Arduino, various sensors and motors. So far I've mainly used Johnny Five ¹ on Node.js to orchestrate things. It was so simple to jump in, with an easy ubiquitous language, and I was able to spend time learning the actual hardware and developing the logic. For my needs, an interpreted language has been plenty capable.

As I get deeper though, I'm finding a need for near real-time control (timing, to be precise), as performant as I can make it. For that, I'm (re)turning to C, a language I last used a couple dedades ago. It's tougher going but definitely rewarding.

I'm so glad for the friendly introduction to the field, like Python and Arduino sketches. It reminds me of my pre/teen days, hacking at a personal (well, family) computer, getting familiar with a marvel of technology through exploration and discovery.

¹ https://github.com/rwaldron/johnny-five/


Agreed. Same with Arduino and C++. If you buy a random developer board you have to also buy a programmer and learn the tool chain. This is an unnecessary barrier for dabbling around to see µC are interesting to you and you can still learn the principles about µC I/O.

Even for professionals this can be interesting for prototyping (heh, not because JS is prototype based).

Even with no perfectly efficient code modern µC are very powerful while using basically no energy. Their example processors are already very powerful and certainly can run a small interpreter with no problem:

http://www.espruino.com/Order


The other interesting thing I've noticed about some of the mechanical keyboards pcbs is that they'll just expose i2c headers even with an integrated controller (gergo is like this). It's semi popular to shove oleds on them. I've been watching form afar people attempting to add track balls.

I'm curious if this will let a particularly dedicated and insane person/s port QMK to JS.


Hey everyone! I'm the creator of this. Glad to see a few of you have tried it and enjoyed it. Any questions, just let me know below and I'll do my best to answer.

Just to answer some of the stuff below:

Yes, you could write something faster and smaller in C. However chances are you'd spend a lot more time doing it, eg. https://github.com/classycodeoss/nrf52-ibeacon/blob/master/m... vs http://www.espruino.com/iBeacon

Most battery powered devices spend most of their time asleep. If your device spends 1ms awake every minute instead of 0.01ms then honestly in most cases that's not a big deal, because the power consumption of everything else in the system is 100x that.

Low.js/Moddable/Jerryscript/etc are bigger, faster more complete JS engines that provide a more Node.js-style experience, but generally for more powerful devices. With Espruino we're saying if you're willing to make a few small tweaks to the way you write code then you can use amazingly low power devices: 0.003mA sleep for nRF52 vs. 80-500mA for Raspberry Pi or 0.8mA for ESP32 (with RAM retention)


Good work, stuff like Espruino and MicroPython are the modern version of 8 bit BASIC.

As I regularly mention, most microcontrollers are much more powerful than 8 and 16 bit home computers back in the day.

Good luck for your endeavors.


I haven't used any of these but recently I went down a rabbit hole of reading about prototype-based vs. class-based OOP, which took me to NewtonScript. It went prototype-based (inspired by Self, the common ancestor of NewtonScript and JavaScript) and because of this, many "classes" could have default data and functions point back into the ROM, meaning it was possible to have hand-held GUI apps and OS with 128KB of RAM. Does Espruino take advantage of this technique to save on RAM, and does using JavaScript's prototype-based OOP make it more suitable than Python for low-memory situations?


There also are low.js and Moddable:

https://www.neonious.com/lowjs/

https://www.moddable.com/

Low.js interprets the actual JS code stored on the embedded system which already contains the runtime. Moddable compiles JS to a byte code on the PC and builds an image to transfer to the embedded chip. The XS runtime of Moddable probably is closer to a full development pipeline, for people used to low-level embedded development.

Low.js was more high-level, when I tried it you did not need to know anything about embedded, just send JS code to the embedded system with low.js on it. Moddable required full knowledge of C and embedded development.

Moddable directly supports almost all of ES 2018.

Low.js uses Duktape with their own stuff added and last time I checked required transpilation of the JS code to ES5.


Moddable and Espruino have a slightly more restrictive license for when u want to maybe monetize your project.

Duktape and Jerryscript are way bigger open-source projects (on github at least). I used almost all of the interpreters to do a hello world on a microcontroller. They all work great! I found Duk to have a slightly cleaner API for bindings, for example writing to the serial port from JS land.

https://github.com/svaarala/duktape

https://github.com/jerryscript-project/jerryscript


https://github.com/mfikes/esprit targets espruino from clojurescript.


Wouldn’t microcontrollers better run with efficient and low-level languages?


We prototype everything in a higher level language first and then 'translate it' (manually) to something that fits the production platform.

For instance, for our current iteration of our product, we created a first 'visual prototype' with Flutter (this contains all algorithms and data-structures already to almost translate 1-1 to C++ and C/asm), then we worked down to C++ (next time we are going to try Rust for this phase) on a powerful mcu but with the (mostly) identical peripherals as the final product. Final step (currently ongoing) is the translation to C/asm to fit the MCU's we use (2mhz/24kb).

Over the decades we have seen that this process is the fastest and least bug prone way. We already think in low level structures and algorithm implementations when coding the high level 'visual' model (or sales/investor pitch model often) (which used to be Java desktop applications, but now with smart phones it's far closer to what the end product will be) so that when we move down towards production components (which means basically as cheap as possible BOM for 1m+ runs; every cent counts, also, we have never had the experience where, after the fact, we encountered this common thing in software; 'people are more expensive than hardware'. Even for a few cents difference we can pay more people than we needed. But yes, that means optimising every byte...), we don't have to spend that much time on those. It's just on hardware specific stuff for the C++ 'big' mcu version and then it's just bit-fiddling/optimising for the lowest level version.


Yes and much more straight forward to interface with hardware - but also requires some level of exp with said low level languages.

Arduino did a lot to reduce barrier to entry to the uC world - but even that requires you to understand a little of how C++ works once you move beyond blinky.

These (micropython, this project, Lua ) etc lower the barrier to entry even further. The trade off of course is how well they run and how much of the hardware is exposed (register manipulation etc) if you want to get to it...


I'm not a fan of Javascript on microcontollers, but you can't ask that question without asking "Okay, so which language?"

Your really small language alternatives:

1) BASIC--Okay, but not exactly mainstream nowadays

2) Tcl--My favorite on small devices, but it's more like a Lisp than a mainstream language so there's a barrier

3) A Scheme/Lisp--again sufficiently different that it presents a barrier to entry

4) Forth--For those who don't find Lisp different enough

5) Lua--1-based in a 0-based world AND you have to add so many "extensions" that its no longer "small" when you finish.

And ... ?

As opposed to:

A) Espruino aka Javascript--everybody and their dog can put together 10 lines of Javascript and make it work. Resources are everywhere. You're probably not building anything large enough to activate most of Javascripts negatives (generally related to concurrency and building in the large)

B) Micropython -- a lot of people with scientific background can throw together a couple dozen lines of Python and connect to something in their lab. Lots of resources and help available.

MY problem is that I would like something like one of these languages but that runs in <4K RAM and <16K FLASH. I want an actual small language that runs in something smaller than an Apple IIe, thanks.


Most micro-controllers are more powerful than the PCs I used with MS-DOS on, plenty of juice on those 80x86 with 640 KB memory for high level languages.

Naturally anything performance critical back then was written in pure Assembly, but plenty of stuff was achievable with Basic, Pascal, C, Lisp, Clipper, Prolog and plenty of other stuff.

First profit from productivity in a high level language, then optimize within its capabilities, and if that still isn't enough than dive into Assembly.


Of course. But efficiency is not the only important thing in the world.

You can explore the world from different perspectives, not just from one.

Lisp was for a long time a very inefficient language, but also extremely important.

The users of early Lisp did not care so much about efficiency, they were mainly academics after all and someone else did buy the machines they used(they did cost hundreds of thousands of dollars each).

They cared about things like reusability of code, being easy to understand, not making mistakes or just exploring the new world of computers.

They invented flow control directives like "cond" and later "if", "while"..., functions, lambdas, macros, program evaluation through eval(interpretation of programs), structured text(s expressions) and complex parsing, automatic reference counting, garbage collectors, closures...and so many things that we take for granted today.

If you focus too much on something you become myopic to other things that are also important. And if you don't explore those other areas, you don't even know that they exist.


Programmers run much better with high-level languages. For quantity-1million, yes the efficiency matters. For quantity-1, the structure is very different.

There used to be (maybe still are?) "BASIC Stamp" microcontrollers that run tokenised BASIC. This is the next evolution of that.

(The C environments work, but the manufacturer-provided ones are often a bit ropey!)


FWIW, Great Cow Basic (http://gcbasic.sourceforge.net/) is available for both PIC and AVR microcontrollers and still actively maintained. I've used it a lot on several PIC projects.


Sure. But they're powerful enough that they can run higher-level languages these days, and it lowers the barrier to entry for people wanting to do hardware projects which is pretty cool.


TBH i found for some use cases JS is much better than C for MCU. Simply due the nature of javascript and it's eventloop MCU could automatically sleep without writing any additional code. While on C you have to use some kind of scheduler that switches power mode of MCU by yourself.


A programming language is just an abstraction (built on other abstraction, typically) of turning transistors on and off. JavaScript is most often run in a runtime like v8, but you could build alternate runtimes or event a compiler to target some VM bytecode or an architecture.

One of the things that makes interfacing with hardware (as a software engineer) joyful is having your toolsets match your expectations and mental models of how you want your solution to work. JavaScript was built as a language for interfaces and what is hardware? It’s a physical interface. I personally don’t find it totally unsuited for microcontrollers.


The same thinking applies to PCs and supercomputers, but sometimes we trade efficiency for convenience. That's happening in the "microcontroller" space too (which are surprisingly powerful nowadays).


In short: yes.

BUT maybe it does not matter that much for some projects and a lot of people can write some logic in js a lot faster than in C (or C++ or Rust or..).

Also, there are a lot of people who know only js and would like to "play" with some LED, fetching room temperatures, opening closing doors etc - this is a nice way to start.

There are a lot more info about performance here: https://www.espruino.com/Performance


In my opinion, life would - in the long term - be easier for these people if they were forced to learn C, C++ or Rust for their projects. But it’s been a while since I was a beginner myself, so there might be some bias here.


C, C++ and Rust are big barrier to most hobby programmers.

Python, JavaScript, and other high-level languages are way more accessible and are an order of magnitude faster to get started with.

Why waste weeks on learning C when that time could just as well be spent actually getting things done?

I also don't see how C - and especially Rust - would make embedded development any easier than using a scripting language. Tooling is often worse, skills cannot be transferred from and to other common areas (mobile, web) and development times are provably longer.

Unless your goal is to become a professional and create commercial products in the IoT/embedded space, I doubt learning and using C or C++ would be easier in any way.


I wish I could insert the hint here that I actually use C for web development without it looking like a flame bait ... :-)

I agree that Rust was not a good example, sorry.


Technically yes.

But in term of development running JS allows devs to code on their PCs and to run some tests on PCs. So once code is ready on some level to be deployed on microcontroller.


The same is true for C.


20 years ago i wrote code for MicroChip PIC series and we're developing using Assembler for maximum performance and minimum codesize.

Merging code between different devs there was... challenging!


I’m working with Espruino at the moment. Being able to access an embedded JS REPL over pretty much any protocol opens up all kinds of weird new programming experiences. I’ll leave what those might be to your imagination!


If it's about the REPL then you could also have a look at Forth. It seems that in Espurino you have to pay attention to quite a lot of things to achieve a decent performance: http://www.espruino.com/Performance


That's also the feature I love when using MicroPython. Having a REPL on the microcontroller itself, that can be accessed through serial-over-bluetooth? Awesome.


NodeMCU also has a Lua REPL but you need an USB wire. Itcs very cool, I'm currently playing with it. There is also some Lua OTA example in the firmware.


Can someone with a low enough level of programming knowledge do anything in Javascript that is not already really easy in C?

Sure, some things like interrupts and PWM control take a bit more work in C (although most uCs have libraries to encapsulate this) but if someone is that noob, are they really programming interrupts and PWM?


String manipulation and dynamic memory allocation are kind of awful in C (this coming from someone that's written a web browser in the language.)

I'm not sure javascript would be my first choice of a replacement (really scheme is pretty amazing, and more general than C even. With a tiny amount of work you can even avoid the garbage collector and get pretty much every advantage C had with a more minimalist, general, and expressive language) but it's very popular and has most "normal" things that c lacks. Arguably these aren't thins you should be doing on a "micro controller" (IMO you're generally best off sticking to state machines and avoiding dynamic memory allocation.)


Its about accessibility for developers (js developers here).


Espruino claims to do automatic power management.


Yes, write programs without security vulnetabilities related to parsing untrusted inputs.


I think it's pretty interesting but the hardware seems to be veery limited. It's like a light version of Arduino stuff.


It supports a variety of platforms including the latest ESP32s which are fairly capable. Anything higher than that and you are talking about an SBC at which point you can use any language you like.


No, it's really much closer to a light version of NodeJS.


I bought an espruino once and built some basic LED lights setup. I switched to Arduino (Arduino as in arduous) however, for the larger ecosystem of libraries. It was easier to learn basic C than to redo Fastled library in javascript. For everything that does not require a library, I liked espruino a lot.


There are a lot of micropython boards available, not sure why I'd choose this over any of the many boards that work with micropython.

Their "bangle.js" smart watch does look pretty nice though. A lot better than the TTGO smart watches.


Any thoughts on the development experience of this versus the Elixir based Nerves project, putting aside obvious platform differences (i.e. the BEAM being concurrent and resilient by design vs JS having a ton of libraries, etc.)?


I haven't seen the puck.js before but I really like that form factor. Are there any similar boards out there with the same sensors that also have wifi?


You might want to look into what https://m5stack.com/ does. They deliver ESP32s under nice form factors. The chip can run Espruino apparently: http://www.espruino.com/FAQ#is-espruino-related-to-esp8266-e...


I have been wondering for years if I should buy some for hobbyist projects. I hope some HN reader can share a bit of their experiences.


I've had a lot of fun using Espruino on the ESP8266 platform for various sensor applications. The biggest hurdle was keeping things simple. It's easy to get creative with JavaScript resulting in memory overflows and hard to debug issues. I eventually switched to Node.js on the Raspberry PI as my use case did not require low power / small form factor.


Playing with the bangle.js espruino watch has been great fun. Nice hardware (much nicer than the esp32 based lilygo), and there's a coolness factor in programming your own watch to work exactly as you please.


What issues did you have with the Lilygo? A watch with an integrated ESP32 sounds nice to my ears.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: