Javascript is a true full stack language. I use it everywhere. Single Page Applications running in the browser, REST API running in the server, serverless functions running in the cloud, native mobile applications running in Android or IOS, desktop applications with Electron running in Windows, Mac or Linux. I was wondering if I could use it with MicroControllers. The answer is Yes and it is called Espruino.

It is an open source library. In order to use it, first we need to install the firmware. Go to manufacturer's web site.

https://www.espruino.com/Download

And download the latest firmware with directory. When I downloaded below was the latest version:

Release: espruino_1v99_esp8266_4mb/ (Directory)

In this directory you will have below files:

  • blank.bin
  • boot_v1.6.bin
  • esp_init_data_default.bin
  • espruino_esp8266_user1.bin
  • espruino_esp8266_user2.bin

We need to erase the existing flash in order to upload the Espruino firmware. To do both, we need esptool from espressif.

Install esptool and espruino-cli

Install Python and pip (if you haven't already) and then install esptool:

pip3 install esptool

We will also need espruino cli. That's an npm package. Install it as globally.

npm install espruino -g

If npm fails, it means you don't have Node.js installed. You also need to install Node.js

After installing esptool, make sure that the installed directory exists in the PATH of environment variables.

Erase the flash in ESP8266

esptool.py --port /dev/cu.wchusbserial1420 erase_flash

You may need to change the port. For Windows, it will be something like PORT3, PORT4 etc.

Flash the Espruino firmware

Locate to the directory where you downloaded the firmware and execute below commands(most probably you will need to change the port):

esptool.py --port /dev/cu.wchusbserial1420 \
--baud 115200 write_flash \
--flash_freq 80m  -fm dio \
--flash_size 4MB \
0x0000 boot_v1.6.bin \
0x1000 espruino_esp8266_user1.bin \
0x3FC000 esp_init_data_default.bin \
0x3FE000 firmware/blank.bin \

Write and upload the program

Unlike Arduino or MicroPython, Espruino does not have a file structure. So, the file names don't matter. You can think it as any file you upload into Espruino will be treated as index.js and will overwrite the existing one. All ESP-12s have a built-in LED. Let's write the simplest Hello World application which is the blinking LED of course.

  digitalWrite(2, 0);
  setTimeout(function(){ digitalWrite(2, 1); }, 2000)

You can save above file with any file extension. You don't need loop() or init() functions (at least for above code). I saved it as index.js and executed below command to upload it into ESP8266 12E:

espruino -p /dev/cu.wchusbserial1420 b 115200 -e 'save()' index.js

Every time you upload a new file, old one will be replaced. But what if I need to execute certain tasks when ESP8266 is powered. There exists an init function. But no loop. You can create loops but you need to change the way you think if you developed ESP8266 applications using Arduino IDE and C++ before. This is JavaScript and you would want to create event driven loops.

Led example was too simple. It's so easy to create an HTTP Server using Node.js. So let's create one using Espruino and manipulate LED from browser.

E.on('init', function() {
  var WIFI_NAME = 'MYWIFI';
  var WIFI_OPTIONS = { password: 'MYPASSWORD' };

  var wifi = require('Wifi');
  wifi.connect(
    WIFI_NAME,
    WIFI_OPTIONS,
    function(err) {
      if (err) {
        console.log('Connection error: ' + err);
        return;
      }
      console.log('Connected!');
      runServer();
    }
  );
});

function runServer() {
  var http = require('http');
  http
    .createServer(function(req, res) {
      res.writeHead(200);
      var status = req.url.replace('/?', '');
      if (status === 'on') ledStatus(1);
      if (status === 'off') ledStatus(0);

      res.end('LED status = ' + status);
    })
    .listen(8080);
}

Libraries Wifi and http are part of the firmware. E.on('init', function(){}) is also a firmware function which is called after the device is powered on. I can use this as the starting point of my application. When I connect to Wifi, I will run the server.

Now we can connect to the mini web server running in our ESP8266. But one problem. It won't be very obvious what IP address you device got. You can scan the devices on your wifi with software like Who's On My Wifi. Or you can establish a serial connection via USB.

screen /dev/cu.wchusbserial1420 115200

after establishing the serial connection you will see something like below:

--] 
--] >
--]  ____                 _ 
--] |  __|___ ___ ___ _ _|_|___ ___ 
--] |  __|_ -| . |  _| | | |   | . |
--] |____|___|  _|_| |___|_|_|_|___|
--]          |_| espruino.com
--]  1v99 (c) 2018 G.Williams
--] 
--] Espruino is Open Source. Our work is supported
--] only by sales of official boards and donations:
--] http://espruino.com/Donate
--] Flash map 4MB:512/512, manuf 0xc8 chip 0x4016
--] 
--] Compacting Flash...
--] Calculating Size...
--] Writing..

Now you're ready to execute commands directly from the Espruino firmware. So to get the IP number just execute:

require('Wifi').getIP()

I got my IP address as 192.168.1.74. If you look at the code it's listening connections on port 8080.

http://192.168.1.74:8080/?on --> Turn on the LED
http://192.168.1.74:8080/?off --> Turn off the LED

Pretty simple and powerful.