-->
Page 1 of 2

Javascript from within the Arduino Development Environment

PostPosted: Mon Oct 07, 2019 1:43 pm
by sfranzyshen
(from the same people who brought you mongoose-os, mdash, mjs, and others ...)

Elk: a restricted single-file JS engine for embedded systems
https://github.com/cesanta/elk

it can be used from within the arduino development environment ...

Re: Javascript from within the Arduino Development Environme

PostPosted: Wed Nov 27, 2019 12:58 pm
by sfranzyshen
sfranzyshen wrote:(from the same people who brought you mongoose-os, mdash, mjs, and others ...)

Elk: a restricted single-file JS engine for embedded systems
https://github.com/cesanta/elk

it can be used from within the arduino development environment ...


I can confirm that 0.0.16 builds and runs on the esp8266 and esp32 platforms ...

Code: Select allUsing library elk at version 0.0.16 in folder: /home/name/Arduino/libraries/elk

esp8266
Code: Select allSketch uses 280664 bytes (26%) of program storage space. Maximum is 1044464 bytes.
Global variables use 28552 bytes (34%) of dynamic memory, leaving 53368 bytes for local variables. Maximum is 81920 bytes.

esp32
Code: Select allSketch uses 231185 bytes (17%) of program storage space. Maximum is 1310720 bytes.
Global variables use 16396 bytes (5%) of dynamic memory, leaving 311284 bytes for local variables. Maximum is 327680 bytes.

Test Code
Code: Select all#include "elk.h"  // Add Elk library

extern "C" void myDelay(int milli) { delay(milli); }
extern "C" void myWrite(int pin, int val) { digitalWrite(pin, val); }
extern "C" void myMode(int pin, int mode) { pinMode(pin, mode); }

struct js *js;

void setup() {
  js = js_create(malloc(700), 700);
  js_import(js, "f1", (uintptr_t) myDelay, "vi");
  js_import(js, "f2", (uintptr_t) myWrite, "vii");
  js_import(js, "f3", (uintptr_t) myMode, "vii");
  js_eval(js, "f3(2, 1);", 0);  // Set LED pin to OUTPUT mode ... tried f3(2, 2) also ...
}

void loop() {
  js_eval(js, "f1(200); f2(2, 1); f1(200); f2(2, 0);", 0);
}

Re: Javascript from within the Arduino Development Environme

PostPosted: Thu Dec 19, 2019 6:16 pm
by sfranzyshen
Elk is now up to version 0.0.18 and been confirmed working with esp32, esp8266, and uno boards. Here is the neopixel strandtest ported to elk javascript and embedded within an arduino sketch. while the sketch below doesn't work on the uno (yet!) it does work with the esp(s) ...

Code: Select all// example of using the elk javascript engine innen Arduino Environment on esp
// Adafruit_NeoPixel strandtest.ino ported to elk javascript engine ...

#include <Adafruit_NeoPixel.h>
#include <elk.h>

#define ALLOC     2048
#define LED_PIN   D2
#define LED_COUNT 8
#define DEBUG     1

struct  js *js = js_create(malloc(ALLOC), ALLOC);
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  jsval_t v;

  Serial.begin(115200);
  Serial.println();
 
  if(DEBUG) {
    Serial.println("Starting ...");
  }

  js_import(js, "delay", (uintptr_t) Sys_delay, "vi");
  js_import(js, "print", (uintptr_t) Sys_print, "vj");
  js_import(js, "show", (uintptr_t) Neo_show, "v");
  js_import(js, "clear", (uintptr_t) Neo_clear, "v");
  js_import(js, "setPixelColor", (uintptr_t) Neo_setPixelColor, "viiii");
  js_import(js, "WheelR", (uintptr_t) Neo_WheelR, "ii");
  js_import(js, "WheelG", (uintptr_t) Neo_WheelG, "ii");
  js_import(js, "WheelB", (uintptr_t) Neo_WheelB, "ii");
  js_import(js, "jsinfo", (uintptr_t) js_info, "sm");
  js_import(js, "numPixels", (uintptr_t) Neo_numPixels, "i");

  v = js_eval(js, "let colorWipe = function(d, r, g, b) { let i = 0; while (i < numPixels()) { setPixelColor(i, r, g, b); show(); delay(d); i++; } delay(d * numPixels()); return i; };", 0);
  if(DEBUG) {
    Serial.print("let colorWipe result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);

  v = js_eval(js, "let theaterChase = function(d, r, g, bl) { let a = 0, b, c; while(a < 10) { b = 0; while(b < 3) { clear(); c = b; while(c < numPixels()) { setPixelColor(c, r, g, bl); c += 3; } show(); delay(d); b++; } a++; } return a; };", 0);
  if(DEBUG) {
    Serial.print("let theaterChase result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);
 
  v = js_eval(js, "let theaterChaseRainbow = function(wait) { let j = 0, q, i, p, r; while(j < 256) { q = 0; while(q < 3) { i = 0; while(i < numPixels()) { p = (i + j) % 255; r = i + q; setPixelColor(r, WheelR(p), WheelG(p), WheelB(p)); i = i + 3; } show(); delay(wait); i = 0; while(i < numPixels()) { r = i + q; setPixelColor(r, 0, 0, 0); i = i + 3; } q++; } j++; } return j; }; ", 0);
  if(DEBUG) {
    Serial.print("let theaterChaseRainbow result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);

  v = js_eval(js, "let rainbowCycle = function(wait) { let j = 0, i, p; while(j < 256 * 5) { i = 0; while(i < numPixels()) { p = ((i * 256 / numPixels()) + j) & 255; setPixelColor(i, WheelR(p), WheelG(p), WheelB(p)); i++; } show(); delay(wait); j++; } return j; };", 0);
  if(DEBUG) {
    Serial.print("let rainbowCycle result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);
 
  v = js_eval(js, "let rainbow = function(d) { let j = 0, i, p; while(j < 256) { i = 0; while(i < numPixels()) { p = (i + j) & 255; setPixelColor(i, WheelR(p), WheelG(p), WheelB(p)); i++; } show(); delay(d); j++; } return j; };", 0);
  if(DEBUG) {
    Serial.print("let rainbow result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);
   
  strip.begin();
  strip.show();
  strip.setBrightness(50);

  if(DEBUG) {
    v = js_eval(js, "print('VM Ready ...'); print(jsinfo(null));", 0);
    Serial.print("jsinfo() result: "); Serial.println(js_str(js, v));
    js_gc(js, v);
    Serial.println("Setup Complete ...");
  }
}

extern "C" void Neo_show() { strip.show(); }
extern "C" void Neo_clear() { strip.clear(); }
extern "C" void Neo_setPixelColor(uint16_t n, int r, int g, int b) { strip.setPixelColor(n, strip.Color(r, g, b)); }
extern "C" void Sys_delay(unsigned long milli) { delay(milli); }
extern "C" void Sys_print(jsval_t v) { Serial.println(js_str(js, v)); }
extern "C" int Neo_WheelR(int wheelpos) { return WheelR(wheelpos); }
extern "C" int Neo_WheelG(int wheelpos) { return WheelG(wheelpos); }
extern "C" int Neo_WheelB(int wheelpos) { return WheelB(wheelpos); }
extern "C" int Neo_numPixels(void) { return strip.numPixels(); }

int WheelR(int WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return (255 - WheelPos * 3);
  }
  if(WheelPos < 170) {
    return (0);
  }
  WheelPos -= 170;
  return (WheelPos * 3);
}

int WheelG(int WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return (0);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return (WheelPos * 3);
  }
  WheelPos -= 170;
  return (255 - WheelPos * 3);
}

int WheelB(int WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return (WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return (255 - WheelPos * 3);
  }
  return (0);
}

void loop() {
  jsval_t v;
 
  if(DEBUG) {
    Serial.println("Looping ...");
  }
 
  v = js_eval(js, "colorWipe(50, 255, 0, 0);", 0);
  if(DEBUG) {
    Serial.print("colorWipe() red result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);

  v = js_eval(js, "colorWipe(50, 0, 255, 0);", 0);
  if(DEBUG) {
    Serial.print("colorWipe() green result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);

  v = js_eval(js, "colorWipe(50, 0, 0, 255);", 0);
  if(DEBUG) {
    Serial.print("colorWipe() blue result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);
 
  v = js_eval(js, "theaterChase(50, 127, 127, 127);", 0);
  if(DEBUG) {
    Serial.print("theaterChase() white result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);
 
  v = js_eval(js, "theaterChase(50, 127, 0, 0);", 0);
  if(DEBUG) {
    Serial.print("theaterChase() red result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);
 
  v = js_eval(js, "theaterChase(50, 0, 0, 127);", 0);
  if(DEBUG) {
    Serial.print("theaterChase() blue result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);
   
  v = js_eval(js, "rainbow(30);", 0);
  if(DEBUG) {
    Serial.print("rainbow() result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);

  v = js_eval(js, "rainbowCycle(20);", 0); 
  if(DEBUG) {
    Serial.print("rainbowCycle() result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);

  v = js_eval(js, "theaterChaseRainbow(50);", 0);
  if(DEBUG) {
    Serial.print("theaterChaseRainbow() result: "); Serial.println(js_str(js, v));
  }
  js_gc(js, v);
 
}

Re: Javascript from within the Arduino Development Environme

PostPosted: Wed Jan 01, 2020 1:08 am
by sfranzyshen
Here's my latest example of mixing Arduino & Javascript ... it demonstrates how to combine Arduino drivers and libraries into a sketch, then map the functions into a javascript vm ... allowing for quick, interactive, live coding

... this example combines the Adafruit NeoPixel Driver with the Elk JavaScript engine to create a ‘JavaScript’ scriptable NeoPixel LED Controller with an easy to use Web UI.

https://melodytoys.github.io/NeoJS/

Image