Embedded Javascript

How I found running Javascript on microprocessors (can) make sense

Iain Nash

About Me

Software Engineer in NYC

@ Oscar Health

Studied Computer Engineering

 

Still often tinker with Hardware

 

My first microcontroller project:

A human-aware missile launcher

 

My latest microcontroller project:

Live heartrate and motion streaming sensor

First, an overview.

 

Then, a step by step guide to run JS on an ESP32.

Goal for today:

 

Show the current temperature on a webpage

Arduino?

C ARM Code

Compiling Custom Interpreters?!

PIC

Arduino

ESP32

void SetupUltrasonic(void) {
 T1CKPS1 = 0;
 T1CKPS0 = 1;
 TMR1CS = 0; // Internal clock (Fosc/4)
 TMR1ON = 1; // Turn on Timer 1
 TRISE = 0;
 TRISC2 = 0;
}

void DelayTime(unsigned int count) {
unsigned int i, j;
for(i=0;i<count;i++){for(j=0;j<count;j++){}}
}

unsigned long int GetUltrasonicDistance(void){
 unsigned int range, first_edge, second_edge;
 unsigned long int distance, count;
 PinDirection = 0; // Output to start sending ultrasonic sound 
 TRISC2 = 0;
 TriggerAndEchoPin = 0;
 DelayTime(TenMicroSecond);
 TriggerAndEchoPin = 1; // Generate a pulse
 DelayTime(TenMicroSecond); // Minimum pulse width
 TriggerAndEchoPin = 0; // Turn off the pulse to start sending sound
 PinDirection = 1; // Switch to input to receive echo
 TRISC2 = 1;
 CCP1IF = 0;
 CCP1CON = 0b00000101; // Input capture on every rising edge
 // Wait for rising edge
 while(CCP1IF==0){}
 first_edge = CCPR1H;
 first_edge = first_edge<<8;
 first_edge = first_edge + CCPR1L;
 CCP1IF = 0;
 CCP1CON = 0b00000100; //Input capture on every falling edge
 //DelayTime(TenMicroSecond); /minimum pulse width
 while(CCP1IF==0){} //waiting for falling edge

Arduino

void setup() {
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  Serial.begin(9600); // Starts the serial communication
}
void loop() {
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  // Calculating the distance
  distance= duration*0.034/2;
  // Prints the distance on the Serial Monitor
  Serial.print("Distance: ");
  Serial.println(distance);
}

JS

const trigger = Cfg.getPin('trigger');
const pwmMotor = Cfg.getPin('motor');

const ultrasonic = require('Ultrasonic').init(trigger);
const motor = require('Motor').init(pwmMotor);

ultrasonic.on('range', function(amount) {
  motor.setSpeed(amount > 100 ? 10 : 100);
});

ESP8266

Inexpensive network interface board

made by Expressif

 

Often used in conjuction with an Arduino / PIC

Developing on ESP8266

ESP32

  • Low cost
  • Many hardware interfaces
  • Built-in wifi and bluetooth
  • Dual-core processor running at 160/240 MHz
  • Open(ish) development toolchain
  • Many development boards

Many development boards

Lolin32 by Wemos

https://wiki.wemos.cc/products:lolin32:lolin32

Espruino

Web IDE Demo

Espruino IDE

Espruino is Full-Stack Javascript

How I found Mongoose OS

  • Worked on running JS in my free time with Espruino
    • Limited environment, somewhat unstable
    • Development was more predictable with C

Mongoose OS

IOT Operating System

Mongoose OS

Setting up a simple environment

  • Debugging serial ports, voltages
  • Assembling the boards
  • Choosing the right boards

Build (many)

simple projects

Temperature Sensor

Heart Rate Sensor

Motion Sensor

Be aware of protocols...

RPC
Cesanta
mJS

Install Options

Bash install script

 

Ubuntu Linux PPA repository

Flashing Firmware

Writing Code

let led = Cfg.get('pins.led');

GPIO.set_mode(led, GPIO.MODE_OUTPUT);

RPC.addHandler('SetLED', function(opts) {
  GPIO.write(led, opts.on);
})
// GPIO pin which has a DHT sensor data wire connected
let pin = 16; // or use config

// Initialize DHT library
let dht = DHT.create(Cfg.get('pins.temp'), DHT.DHT22);

RPC.addHandler('GetTemp', function() {
  let t = dht.getTemp();
  let h = dht.getHumidity();

  if (isNaN(h) || isNaN(t)) {
    //print('Failed to read data from sensor');
    return {temp: null, humidity: null};
  }
  
  return {temp: t, humidity: h};
});
// using js

// Publish to MQTT topic on a button press. Button is wired to GPIO pin 0
GPIO.set_button_handler(button, GPIO.PULL_UP, GPIO.INT_EDGE_NEG, 200, function() {
  let message = getInfo();
  let ok = MQTT.pub(topic, message, 1);
  print('Published:', ok, topic, '->', message);
}, null);

// Monitor network connectivity.
Event.addGroupHandler(Net.EVENT_GRP, function(ev, evdata, arg) {
  let evs = '???';
  if (ev === Net.STATUS_DISCONNECTED) {
    evs = 'DISCONNECTED';
  } else if (ev === Net.STATUS_CONNECTING) {
    evs = 'CONNECTING';
  } else if (ev === Net.STATUS_CONNECTED) {
    evs = 'CONNECTED';
  } else if (ev === Net.STATUS_GOT_IP) {
    evs = 'GOT_IP';
  }
  print('== Net event:', ev, evs);
}, null);
// using js

// Publish to MQTT topic on a button press. Button is wired to GPIO pin 0
GPIO.set_button_handler(button, GPIO.PULL_UP, GPIO.INT_EDGE_NEG, 200, function() {
  let message = getInfo();
  let ok = MQTT.pub(topic, message, 1);
  print('Published:', ok, topic, '->', message);
}, null);

// Monitor network connectivity.
Event.addGroupHandler(Net.EVENT_GRP, function(ev, evdata, arg) {
  let evs = '???';
  if (ev === Net.STATUS_DISCONNECTED) {
    evs = 'DISCONNECTED';
  } else if (ev === Net.STATUS_CONNECTING) {
    evs = 'CONNECTING';
  } else if (ev === Net.STATUS_CONNECTED) {
    evs = 'CONNECTED';
  } else if (ev === Net.STATUS_GOT_IP) {
    evs = 'GOT_IP';
  }
  print('== Net event:', ev, evs);
}, null);

Making a project

Building Firmware

Mongoose OS Libraries

Hardware Config

Protocols...

http://coecsl.ece.illinois.edu/ge423/sensorprojects/1-wire_full.doc​

Hardware Config

Go forth and create!

get in touch ~

 

github

@iainnash

 

email

iain@iain.in

Javascript on the ESP32

By Iain Nash

Javascript on the ESP32

  • 2,137