Skip to content

Espruino

Tristan edited this page Oct 18, 2019 · 23 revisions

Development

Watching the filesystem for changes and reuploading as necessary:

espruino -p /dev/ttyUSB0 \
    -w index.js \
    --config SAVE_ON_SEND=1 \
    --config SERIAL_THROTTLE_SEND=1 \
    --config BAUD_RATE=115200 \

I would normally save the above into a small script like watch.sh and include that in the project folder.


espruino --listconfigs

This will list all configuration options; the ones above are what I use the most.

ESP32

https://www.espruino.com/ESP32

To build your own:

# Get the Espruino source code
git clone https://github.com/espruino/Espruino.git
cd Espruino

# Download and set up the toolchain ('source' is important here)
source scripts/provision.sh ESP32

# Clean and rebuild
make clean && BOARD=ESP32 make

Or just get the prebuilt binaries from https://www.espruino.com/binaries/espruino_2v03_esp32/

esptool.py                                  \
--chip esp32                                \
--port /dev/ttyUSB0                         \
--baud 460800                               \
--before default_reset                      \
--after hard_reset write_flash              \
-z                                          \
--flash_mode dio                            \
--flash_freq 80m                            \
--flash_size detect                         \
0x1000 bootloader.bin                       \
0x8000 partitions_espruino.bin              \
0x10000 espruino_2v03_esp32.bin

Examples

Blinky

let LED1 = 2;
let on = 0;

const toggle = () => {
  on = !on;
  digitalWrite(LED1, on);
};

setInterval(toggle, 1000);

For comparison, here is the Arduino equivalent:

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Serving Webpages and Handling Forms

Adapted from https://www.espruino.com/Posting+Forms

let LED1 = 2;
let LED2 = 4;

const WIFI_NAME = "ssid";
const WIFI_KEY = "password";
let wifi;

// The last data that was POSTed to us
let postData = {};

// This serves up the webpage itself
const sendPage = res => {
  // We're using ES6 Template Literals here to make the HTML easy to read.
  const d = `
<!doctype html>
<html>
 <head>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
 </head>
 <body>
  <form action="#" method="post">
   <div class="form-group">
   <label for="mytext">Some text to send:</label>
    <input type="text" id="mytext" name="mytext" value="Testing"/><br/>
    <label for="led1">LED1 (blue):</label>
    <input type="checkbox" id="led1" name="led1" value="1" ${
      postData.led1 ? "checked" : ""
    }><br/>
    <label for="led2">LED2 (red):</label>
    <input type="checkbox" id="led2" name="led2" value="1" ${
      postData.led2 ? "checked" : ""
    }><br/>
    <button class="btn btn-primary">Submit</button>
    </div>
  </form>
 </body>
</html>`;
  res.writeHead(200, {
    "Content-Type": "text/html",
    "Content-Length": d.length
  });
  res.end(d);
};

// This handles the HTTP request itself and serves up the webpage or a
// 404 not found page
const onPageRequest = (req, res) => {
  const a = url.parse(req.url, true);
  if (a.pathname == "/") {
    // handle the '/' (root) page...
    // If we had a POST, handle the data we're being given
    if (
      req.method == "POST" &&
      req.headers["Content-Type"] == "application/x-www-form-urlencoded"
    )
      handlePOST(req, () => sendPage(res));
    else sendPage(res);
  } else {
    // Page not found - return 404
    res.writeHead(404, { "Content-Type": "text/plain" });
    res.end("404: Page " + a.pathname + " not found");
  }
};

// This handles any received data from the POST request
const handlePOST = (req, callback) => {
  let data = "";
  req.on("data", d => {
    data += d;
  });
  req.on("end", () => {
    // All data received from the client, so handle the url encoded data we got
    // If we used 'close' then the HTTP request would have been closed and we
    // would be unable to send the result page.
    postData = {};
    data.split("&").forEach(el => {
      const els = el.split("=");
      postData[els[0]] = decodeURIComponent(els[1]);
    });
    // finally our data is in postData
    console.log(postData);
    // do stuff with it!
    console.log("We got sent the text ", postData.mytext);
    digitalWrite(LED1, postData.led1);
    digitalWrite(LED2, postData.led2);
    // call our callback (to send the HTML result)
    callback();
  });
};

// This is called when we have an internet connection
const onConnected = () => {
  console.log("Connected!");
  wifi.getIP((err, ip) => {
    console.log("Connect to http://" + ip.ip);
    require("http")
      .createServer(onPageRequest)
      .listen(80);
  });
};

const onInit = () => {
  wifi = require("Wifi");
  wifi.connect(WIFI_NAME, { password: WIFI_KEY }, err => {
    if (err) {
      console.log("Connection error: " + err);
      return;
    }
    onConnected();
  });
};

MQTT

const LED1 = 2;

const ssid = "ssid";
const password = "password"
const mqtt_server = "ipAddress"

let mqtt = require("tinyMQTT").create(mqtt_server);

mqtt.on("connected", () => {
    mqtt.subscribe("espruino/led");
});

mqtt.on("message", (msg) => {
    console.log(msg.topic);
    console.log(msg.message);
    if(msg.message === "1") {
      digitalWrite(LED1, 1);
    }

    if(msg.message === "0") {
      digitalWrite(LED1, 0);
    }

});

mqtt.on("disconnected", () => {
    console.log("disconnected");
});

const wifi = require("Wifi");
wifi.connect(ssid, {password: password}, () => {
    mqtt.connect();
});
Clone this wiki locally