Espruino: JavaScript for Microcontrollers
github.com
github.com
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)
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
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:
I'm curious if this will let a particularly dedicated and insane person/s port QMK to JS.
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.
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)
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.
https://www.neonious.com/lowjs/
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.
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.
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
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 agree that Rust was not a good example, sorry.
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.
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.
Merging code between different devs there was... challenging!
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...
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!)
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.
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.
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.
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.
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?
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.)
Their "bangle.js" smart watch does look pretty nice though. A lot better than the TTGO smart watches.