intel / zephyr.js Goto Github PK
View Code? Open in Web Editor NEWJavaScript* Runtime for Zephyr* OS
License: Other
JavaScript* Runtime for Zephyr* OS
License: Other
If an input JS file has a newline, convert.sh drops it; the result is that if there is a comment, the rest of the file will end up looking like it's commented out.
This could be fixed, but we might be better off going to my Python-based implementation from scripts/jsrunner. So we would pull the conversion routine out of there into a convert.py that replaces convert.sh, review it and make sure it covers at least everything that convert.sh does now.
This should be more cross-platform than bash scripts, and easier for any schmoe like me to read and understand - hence more maintainable. Another thought is we may need to deal with Unicode JS input at some point, and Python would be better suited to that.
We are tracking here the features and enhancements which should or will be implemented in the near future.
This doesn't require hardware, just expose a service as an example.
Like issue #74. After click button more than 210 times in test cases TwoButtons.js and arduino/digital/Button.js, the output will have "exit" message and the interval events will stop arriving. We test in the latest commit: 92c2e
The 'pull' for pullup/pulldown resistors is implemented but the feature doesn't work on IO2, IO4, IO7-IO8 pins. The other pins are not sure whether the pull feature are workable.
Seems that the make system requires the JS variable. Otherwise, it fails always with:
zephyr.js/deps/zephyr/scripts/Makefile.build:45: zephyr.js/src/Makefile: No such file or directory
This is on a clean tree (new clone or git clean -dfx)
JS should be optional. In case it is missing, I think we should substitute it with empty string "".
After a while, maybe after 10 mins, the UI does not update the temperature changes any more. I see from the console that the changes are being recorded
Temperature change: 20.431640624999993 degrees Celsius
But the UI still show "24 C".
I also disconnected and reconnected but the issue remains. The LED control works fine.
eg.
var pinIn = gpio.open({ pin: 19, direction: 'in', edge: 'rising' });
pinIn.set_callback(function () { });
Underscores are seldom used in JS for web APIs: https://w3ctag.github.io/design-principles/
Also the name "set_callback" doesn't make it clear when it is called. Node.js usually uses "on()" for these.
Currently there's an issue where if we add any setInterval() calls to the WebBluetoothDemo.js, the web client will not be able to connect to the device most of the time. It will get an error of Service Not Found. We theorize that this maybe that the fiber thread may not have returned the service id that was requested since the setInterval callbacks were taking up all the resources in the task thread. We might need to fix the main event loop to address this problem.
Once in a while I get zjs_buffer_create: unable to allocate buffer
error in the WebBluetoothDemo.js and it usually recovers quickly. Unfortunately it makes the web app no longer receive temperature changes before a hard reload.
Subject says it all.
This is unlikely to have anything to do with our code, since I can use scanner tools to see that we are advertising the Physical Web URL consistently AFAICT, but it seems indeterminate when a notification will show up on a client Android device.
One question for @kenchris, with the recent patch updating the short URL, have you seen a notification for this URL? Did you register this URL with Google Physical Web as I think you did the earlier one? When I tried to use my own custom URL I never once saw it show up as a notification, but when I switched back to your original one I started seeing it. So I concluded that Google will not actually display it unless you've registered it (on admittedly scant evidence).
Today I did find this page which describes how to enable Physical Web on your device. At the very bottom of the page it describes a known issue where Android can fail to display the notification. But its workaround steps don't seem to do me any good. I thought @poussa might be interested in this.
One of the very nice features of Johnny-Five is that you can have a node.js instance running on your computer and then control your Arduino using that. That of course is not great for a shippable product :) but it is super nice for rapid development.
It would be interesting if we could enable something similar, by having something like a prototype flash image.
pin mapping is a pain, especially since they don't correspond to what is written on the board and they differ between x86 and ARC core.
Johnny-five is known for providing mappings for common devices. We could do similarly like
var pins = require("arduino101_pinmux");
aio.open(... pin: pins.A0 )
I was expecting make update to do
The git pull part missing. I ended up having an old git tree which did not have the commit id listed in repos.txt. So the tree is stuck with the cloned version.
Can we fix this?
~/repo/zephyr.js/arc (master)$ make
make[1]: Entering directory '/home/kenneth/repo/zephyr.js/deps/zephyr'
make[2]: Entering directory '/home/kenneth/repo/zephyr.js/arc/outdir'
Using /home/kenneth/repo/zephyr.js/deps/zephyr as source for kernel
GEN ./Makefile
CHK include/generated/version.h
CHK misc/generated/configs.c
CHK include/generated/offsets.h
CC ../../arc/src/../../src/zjs_ipm.o
In file included from ../../arc/src/../../src/zjs_ipm.c:8:0:
../../arc/src/../../src/zjs_util.h:3:23: fatal error: jerry-api.h: No such file or directory
#include "jerry-api.h"
^
compilation terminated.
/home/kenneth/repo/zephyr.js/deps/zephyr/scripts/Makefile.build:182: recipe for target '../../arc/src/../../src/zjs_ipm.o' failed
make[3]: *** [../../arc/src/../../src/zjs_ipm.o] Error 1
/home/kenneth/repo/zephyr.js/deps/zephyr/Makefile:876: recipe for target '../../arc/src' failed
make[2]: *** [../../arc/src] Error 2
make[2]: Leaving directory '/home/kenneth/repo/zephyr.js/arc/outdir'
Makefile:173: recipe for target 'sub-make' failed
make[1]: *** [sub-make] Error 2
make[1]: Leaving directory '/home/kenneth/repo/zephyr.js/deps/zephyr'
/home/kenneth/repo/zephyr.js/deps/zephyr/Makefile.inc:73: recipe for target 'all' failed
make: *** [all] Error 2
The below patch makes it work. Do we have a particular reason to use capital N ? Especially when we read one char at the time?
diff --git a/scripts/convert.sh b/scripts/convert.sh
index 9297a75..6020d9d 100755
--- a/scripts/convert.sh
+++ b/scripts/convert.sh
@@ -46,7 +46,7 @@ printf "const char script[] = \"" >> $OUTPUT
# No field separator, read whole file (IFS=),
# no backslash escape (-r),
# read 1 character at a time (-n1)
-while IFS= read -r -N 1 char
+while IFS= read -r -n 1 char
do
if [ "$char" = "\"" ]; then
printf "\\\\$char" >> $OUTPUT
We need to make sure we understand the external pin features of A101 more precisely. The comments on boards/arduino_101/pinmux.c seem to include everything we need to know, but we need to make sure we understand those things right.
For example, the AIO pins we've exposed so far are ain_9 - ain_14 there, aka AD5, AD0-AD4. But pins IO10-13 are also listed as ain_0 - ain_3... so does that mean they can also be analog inputs? Perhaps only from the ARC side? We need to set up some code to test out all these things and prove it to ourselves.
If you tap and release the pushbutton in this sample very quickly, you can get the message:native_clear_interval_handler: timer not found
If you do it enough times, you can get to where you have two ore more of the timer functions running at once and competing with each other for control of the LEDs.
In the arduino/digital/Button.js, we get the output information: JerryScript: can’t run javascript. Then we change the docatch to catch in the file and then the test pass.
We test in the latest commit: 92c2e
Stop and report an error; this can happen if you've made local changes to jerryscript or zephyr.
There should also be a way to override it such as:
make UPDATE=0, for when you're purposely using a different commit etc.
Node.js adaptation based on https://rawgit.com/w3c/accelerometer/gh-pages/index.html
**callback ListenerOrNull = any (...);**
interface Sensor : **EventEmitter** {
readonly attribute SensorState state;
readonly attribute SensorReading? reading;
void start();
void stop();
**void on(String eventName, ListenerOrNull listener)**
**// 'change' -> SensorReading **
**// 'statechange' -> () **
**// 'error' -> Error **
};
[Constructor(optional AccelerometerSensorOptions accelerometerSensorOptions)]
interface AccelerometerSensor : Sensor {
readonly attribute AccelerometerSensorReading? reading;
readonly attribute boolean includesGravity;
};
dictionary SensorOptions {
double? frequency;
};
dictionary AccelerometerSensorOptions : SensorOptions {
boolean includeGravity = true;
};
// throw TypeError when sensor cannot be constructed.
enum SensorState {
"idle",
"activating",
"active",
"errored"
};
[Constructor()]
interface SensorReading {
**readonly attribute double timeStamp;**
// Used to store a time value. The value could be a discrete point
// in time or the difference in time between two discrete points in
// time. The unit is milliseconds and should be accurate to 5 µs
// (microseconds). However, if the browser is unable to provide a
// time value accurate to 5 microseconds (due, for example, to
// hardware or software constraints), the browser can represent the
// value as a time in milliseconds accurate to a millisecond.
};
[Constructor(AccelerometerSensorReadingInit AccelerometerSensorReadingInit)]
interface AccelerometerSensorReading : SensorReading {
readonly attribute double accelerationX;
readonly attribute double accelerationY;
readonly attribute double accelerationZ;
};
dictionary AccelerometerSensorReadingInit {
double accelerationX = 0;
double accelerationY = 0;
double accelerationZ = 0;
};
Example:
var accelerometer = new AccelerometerSensor()
accelerometer.start();
accelerometer.on('change', function(reading) {
console.log(reading.accelerationX);
});
accelerometer.on('error', function(error) {
console.log(error.name, error.message);
});
Still having issues
arc (master)$ make BOARD=arduino_101_sss_factory
Using /home/kenneth/repo/zephyr.js/deps/zephyr/boards/arduino_101_sss/arduino_101_sss_factory_defconfig as base
Merging /home/kenneth/repo/zephyr.js/deps/zephyr/kernel/configs/nano.config
Merging prj.conf
#
# configuration written to .config
#
make[1]: Entering directory '/home/kenneth/repo/zephyr.js/deps/zephyr'
make[2]: Entering directory '/home/kenneth/repo/zephyr.js/arc/outdir'
GEN ./Makefile
scripts/kconfig/conf --silentoldconfig Kconfig
Using /home/kenneth/repo/zephyr.js/deps/zephyr as source for kernel
GEN ./Makefile
CHK include/generated/version.h
CHK misc/generated/configs.c
UPD misc/generated/configs.c
CHK include/generated/offsets.h
CC misc/generated/configs.o
LD misc/generated/built-in.o
LD misc/built-in.o
CC boards/arduino_101_sss/board.o
LD boards/arduino_101_sss/built-in.o
LD boards/built-in.o
CC src/../../src/zjs_ipm.o
/home/kenneth/repo/zephyr.js/arc/src/../../src/zjs_ipm.c:4:30: fatal error: ipm/ipm_quark_se.h: No such file or directory
#include <ipm/ipm_quark_se.h>
^
compilation terminated.
/home/kenneth/repo/zephyr.js/deps/zephyr/scripts/Makefile.build:182: recipe for target 'src/../../src/zjs_ipm.o' failed
make[3]: *** [src/../../src/zjs_ipm.o] Error 1
/home/kenneth/repo/zephyr.js/deps/zephyr/Makefile:884: recipe for target '/home/kenneth/repo/zephyr.js/arc/src' failed
make[2]: *** [/home/kenneth/repo/zephyr.js/arc/src] Error 2
make[2]: Leaving directory '/home/kenneth/repo/zephyr.js/arc/outdir'
Makefile:173: recipe for target 'sub-make' failed
make[1]: *** [sub-make] Error 2
make[1]: Leaving directory '/home/kenneth/repo/zephyr.js/deps/zephyr'
/home/kenneth/repo/zephyr.js/deps/zephyr/Makefile.inc:74: recipe for target 'all' failed
make: *** [all] Error 2
We follow the steps:
make clean
make arc JS=samples/AIO.js
make dfu-arc (after reboot)
Except the information get from output:
ipm_console0: 'ARC---------------------------------------------'
ipm_console0: 'ARC - AIO processor from sensor core (ARC)!'
Nothing else.
If you have a fresh clone or have done git clean -dfx, the make fails on first try.
$ make JS=samples/RGB.js
/home/spoussa/src/iot/zephyr/scripts/Makefile.clean:14: /home/spoussa/src/iot/zephyr.js/src/Makefile: No such file or directory
However, if you run the same command again, it works.
Trying to not specify the board as Geoff told me to in another issue:
make[1]: Entering directory '/home/kenneth/repo/zephyr.js/deps/jerryscript'
/home/kenneth/repo/zephyr.js/deps/zephyr/Makefile.inc:35: *** Board arduino_101_factory_256 not found!. Stop.
make[1]: Leaving directory '/home/kenneth/repo/zephyr.js/deps/jerryscript'
targets/zephyr/Makefile.zephyr:142: recipe for target 'build/arduino_101_factory_256/zephyr/zephyr.strip' failed
make: *** [build/arduino_101_factory_256/zephyr/zephyr.strip] Error 2
ie. setPulseWidthUS()
. @anssiko do you know of existing usage of microseconds in web APIs?
Some sensors are quite impossible to implement using I2C, GPIO etc on top of JS and that might also not be very efficient if it was possible.
For this Zephyr has the sensor subsystem: https://www.zephyrproject.org/doc/subsystems/sensor.html
This works with the very common DTH22 sensor for instance: https://www.adafruit.com/product/385
Sensors are relative easy to use in Zephyr (Might require to run on ARC, that is the only thing that I tested):
struct device *dev = device_get_binding("DHT");
while (1) {
struct sensor_value temp, press, humidity;
sensor_sample_fetch(dev);
sensor_channel_get(dev, SENSOR_CHAN_TEMP, &temp);
sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &humidity);
SYS_LOG_INF("temp: %d.%06d; "
"humidity: %d.%06d",
temp.val1, temp.val2,
humidity.val1, humidity.val2);
task_sleep(sys_clock_ticks_per_sec/5);
}
}
Unfortunately, a few changes might be required to Zephyr in order to set the pin from JS, as it is currently set by a build config CONFIG_DHT_GPIO_PIN_NUM
Here are a few of our W3C proposals for temperature and humidity sensors.
https://github.com/otcshare/thermometer/blob/gh-pages/index.html
https://github.com/otcshare/hygrometer/blob/gh-pages/index.html
These build upon: https://www.w3.org/TR/generic-sensor/#idl-index
(It is planned that the spec will align so that it will work on node.js, so I would say that it is fine replacing the EventTarget - ie onchange
, onerror
with an on("change")
and on("error")
event, at least until that gets settled)
Example code:
var sensor = new TemperatureSensor();
sensor.start();
sensor.onchange = function(event) {
console.log(event.reading.celsius);
}
sensor.onerror = function(event) {
console.log(event.error.name, event.error.message);
};
We could add the pin and sensor name as arguments to TemperatureSensor
, ie
var sensor = new TemperatureSensor({ name: "DHT", pin: pins.A1 })
Based on Generic Sensor API with Node.js adaptation and https://github.com/otcshare/hygrometer/blob/gh-pages/index.html
**callback ListenerOrNull = any (...);**
interface Sensor : **EventEmitter** {
readonly attribute SensorState state;
readonly attribute SensorReading? reading;
void start();
void stop();
**void on(String eventName, ListenerOrNull listener)**
**// 'change' -> SensorReading **
**// 'statechange' -> () **
**// 'error' -> Error **
};
[Constructor(optional SensorOptions sensorOptions)]
interface HumiditySensor : Sensor {
readonly attribute HumiditySensorReading? reading;
};
dictionary SensorOptions {
double? frequency;
};
**dictionary HumiditySensorOptions : SensorOptions {
String? controller;
unsigned short? pin;
}**
// throw TypeError when sensor cannot be constructed.
enum SensorState {
"idle",
"activating",
"active",
"errored"
};
[Constructor()]
interface SensorReading {
**readonly attribute double timeStamp;**
// Used to store a time value. The value could be a discrete point
// in time or the difference in time between two discrete points in
// time. The unit is milliseconds and should be accurate to 5 µs
// (microseconds). However, if the browser is unable to provide a
// time value accurate to 5 microseconds (due, for example, to
// hardware or software constraints), the browser can represent the
// value as a time in milliseconds accurate to a millisecond.
};
[Constructor(HumiditySensorReadingInit humiditySensorReadingInit)]
interface HumiditySensorReading : SensorReading {
readonly attribute unrestricted double? relativeHumidity;
};
dictionary HumiditySensorReadingInit {
unrestricted double? relativeHumidity;
};
Example:
var hygrometer = new HumiditySensor({ controller: "DHT", pin: pins.A1 })
hygrometer.start();
hygrometer.on('change', function(reading) {
var t = themostat.celsius;
var absoluteHumidity = 2.167 * reading.relativeHumidity * 6.112 * Math.exp(17.62 * t / 243.12 + t) / (273.15 + t);
console.log("RH: " + reading.relativeHumidity);
console.log("AH: " + absoluteHumidity);
});
hygrometer.on('error', function(error) {
console.log(error.name, error.message);
});
When you try to build for K64F now, you run into an error where gettimeofday() hasn't been declared. This is ZEP-644 in the Zephyr project. This issue is just to keep track of that one because it's blocking K64F development in Zephyr.js.
Zephyr JS build all functional modules regardless whether they are needed or not by a particular application. This will cause extra not needed information output.
Need to change to build only required modules to clean up the output.
We follow the steps:
make clean
make JS=samples/BLE.js
make dfu
The BLE.js runs fail and get the output:
Native_require_handler: module “ble” not found.
Jerryscript: canot run javascript
Develpers run this sample success. we will follow this issue and need your help to figure out the cause.
The RGB.js sample doesn't match the new promise-based gpio API.
We change the code:
var red = gpio.open({pin: pins.IO2, direction: 'out'});
to
var red = null;
gipo.open({pin: pins.IO2, direction: 'out'}).then(function(pin){
red = pin;
});
And the same change of the red, green and blue
Then move the setInterval() to the blue gpio.open statements. Then the test pass.
Clock ticks on Arduino 101 default to 100 per second, I believe, or 10ms intervals. So this is probably related to that and the fact that we currently sleep for a tick in our main loop.
@jprestwo, you might be interested to look into this.
ie in aio.js sample:
// Test code for Arduino 101 that uses the two onboard LEDs for output, and
// expects a button or similar input connected to digital pin 4.
print("Webbluetooth Demo with BLE...");
// import aio module
var aio = require("aio");
Currently the README says:
Build the *Hello World* sample
----------------------------
(For now, this assumes you have a Flyswatter JTAG device hooked up to your PC
and your Arduino 101.)
Is it possible to build without? If so now?
The Generic Sensor API is based upon ideas from Johnny-Five, and Johnny-Five allows using the same API for simple sensors such as the TMP36.
We can do the same
var thermostat = new TemperatureSensor({ controller: "TMP36", pin: pins.A1 })
thermostat.start();
thermostat.on('change', function(reading) {
console.log(reading.celsius);
});
thermostat.on('error', function(error) {
console.log(error.name, error.message);
});
Question is how to do the implementation, as it is fully doable to do it in JavaScript directly.
In commit 9fbdc67, the image made by 'make arc' does not seem to work properly. It has impact on the samples using arc, such as AIO.js, I2C.js, etc.
Node.js adaptation based on https://rawgit.com/w3c/gyroscope/gh-pages/index.html
**callback ListenerOrNull = any (...);**
interface Sensor : **EventEmitter** {
readonly attribute SensorState state;
readonly attribute SensorReading? reading;
void start();
void stop();
**void on(String eventName, ListenerOrNull listener)**
**// 'change' -> SensorReading **
**// 'statechange' -> () **
**// 'error' -> Error **
};
[Constructor(optional SensorOptions sensorOptions)]
interface GyroscopeSensor : Sensor {
readonly attribute GyroscopeSensorReading? reading;
};
dictionary SensorOptions {
double? frequency;
};
// throw TypeError when sensor cannot be constructed.
enum SensorState {
"idle",
"activating",
"active",
"errored"
};
[Constructor()]
interface SensorReading {
**readonly attribute double timeStamp;**
// Used to store a time value. The value could be a discrete point
// in time or the difference in time between two discrete points in
// time. The unit is milliseconds and should be accurate to 5 µs
// (microseconds). However, if the browser is unable to provide a
// time value accurate to 5 microseconds (due, for example, to
// hardware or software constraints), the browser can represent the
// value as a time in milliseconds accurate to a millisecond.
};
[Constructor(GyroscopeSensorReadingInit GyroscopeSensorReadingInit)]
interface GyroscopeSensorReading : SensorReading {
readonly attribute unrestricted double rotationRateX;
readonly attribute unrestricted double rotationRateY;
readonly attribute unrestricted double rotationRateZ;
};
dictionary GyroscopeSensorReadingInit {
unrestricted double rotationRateX = 0;
unrestricted double rotationRateY = 0;
unrestricted double rotationRateZ = 0;
};
Example:
var gyroscope = new GyroscopeSensor()
gyroscope.start();
gyroscope.on('change', function(reading) {
console.log(reading.rotationRateY);
});
gyroscope.on('error', function(error) {
console.log(error.name, error.message);
});
In the arduino/basics/Fade.js, the LED lightness doesn’t change.
Then we change the setPeriodCycles() to setPeriod(), setPulseWidthCycles() to setPulseWidth() in the file then the test pass.
We test in the latest commit: 92c2e
There's plenty to be confused about here. @kenchris indicated confusion about our "zjs_*_call_function" functions, whose purpose is to invoke a JS callback function at a later time, after serialization through a queue object. These functions know how to assemble the arguments for a particular JS callback.
Eventually we might have common argument patterns and reuse such functions, or even store the argument data in a declarative way so that one grand unified invoker/dispatcher function could call any JS callback appropriately.
But for now we will just try to rename them to be a little more clear about what they do. There are so many levels of callbacks here and such that there's no avoiding complexity. We could also stand to document the architecture of these callbacks somewhere to attempt to give an overview of the situtation. We drew it out on a whiteboard the other day and it was shockingly complex, but I think the complexity is all necessary.
make[3]: *** No rule to make target 'src/../../../deps/jerryscript/build/arduino_101_factory/librelease-cp_minimal.jerry-core.a', needed by 'src/built-in.o'. Stop.
/home/kenneth/repo/zephyr.js/deps/zephyr/Makefile:884: recipe for target '/home/kenneth/repo/zephyr.js/src' failed
make[2]: *** [/home/kenneth/repo/zephyr.js/src] Error 2
make[2]: Leaving directory '/home/kenneth/repo/zephyr.js/build/outdir'
Makefile:173: recipe for target 'sub-make' failed
make[1]: *** [sub-make] Error 2
make[1]: Leaving directory '/home/kenneth/repo/zephyr.js/deps/zephyr'
/home/kenneth/repo/zephyr.js/deps/zephyr/Makefile.inc:74: recipe for target 'all' failed
make: *** [all] Error 2
@jprestwo, could you look into this?
With the latest commit c2787d, if I run ButtonLEDs.js, and I have a button wired up to IO4 and watch the lights flash and click the button 5-6 times, the interval events will stop arriving. If you don't give it any button input, it works indefinitely it seems.
In the previous commit, 3bafb0, it doesn't seem to have this problem.
Currently we are returning false in all the JerryScript function handlers if there's error, but this would abort JerryScript engine and the program will just exit, iinstead, handle non-fatal errors more generously and set ret_val_p to an error or print a message instead of fatal abort, this needs to be examined in all of our code and it is case by case scenario.
Based on generic sensor API with adaptation to Node.js and https://github.com/otcshare/thermometer/blob/gh-pages/index.html
**callback ListenerOrNull = any (...);**
interface Sensor : **EventEmitter** {
readonly attribute SensorState state;
readonly attribute SensorReading? reading;
void start();
void stop();
**void on(String eventName, ListenerOrNull listener)**
**// 'change' -> SensorReading **
**// 'statechange' -> () **
**// 'error' -> Error **
};
[Constructor(optional SensorOptions sensorOptions)]
interface TemperatureSensor : Sensor {
readonly attribute TemperatureSensorReading? reading;
};
dictionary SensorOptions {
double? frequency;
};
**dictionary TemperatureSensorOptions : SensorOptions {
String? controller;
unsigned short? pin;
}**
// throw TypeError when sensor cannot be constructed.
enum SensorState {
"idle",
"activating",
"active",
"errored"
};
[Constructor()]
interface SensorReading {
**readonly attribute double timeStamp;**
// Used to store a time value. The value could be a discrete point
// in time or the difference in time between two discrete points in
// time. The unit is milliseconds and should be accurate to 5 µs
// (microseconds). However, if the browser is unable to provide a
// time value accurate to 5 microseconds (due, for example, to
// hardware or software constraints), the browser can represent the
// value as a time in milliseconds accurate to a millisecond.
};
[Constructor(TemperatureSensorReadingInit temperatureSensorReadingInit)]
interface TemperatureSensorReading : SensorReading {
readonly attribute unrestricted double? celsius;
readonly attribute unrestricted double? fahrenheit;
readonly attribute unrestricted double? kelvin;
};
dictionary TemperatureSensorReadingInit {
unrestricted double? celsius;
unrestricted double? fahrenheit;
unrestricted double? kelvin;
};
Example:
var thermostat = new TemperatureSensor({ controller: "DHT", pin: pins.A1 })
thermostat.start();
thermostat.on('change', function(reading) {
console.log(reading.celsius);
});
thermostat.on('error', function(error) {
console.log(error.name, error.message);
});
So far we've been adding descriptive strings left and right to help us debug, but we should disable the PRINT macro for "release" builds. Another idea is that we could report error numbers instead and map them to the appropriate string. We could pass an argument to PRINT with a unique ID number and then we'd be able to have an automated tool scan the source to collect the number-to-string mappings. The idea then would be some tool on the host side would be able to decode the error strings. Perhaps a script whose data source would get updated during each build.
This would alert us to when we're trying to run code against unexpected deps versions, which would be helpful.
It could even say "Version mismatch detected, build anyway? (y/n)"
readonly attribute unsigned long length;
In buffer.md, the length of Buffer should be readonly, but actually it can be modified.
var buff = new Buffer(8);
var original = buff.length;
buff.length = buff.length + 1;
print(original);
print(buff.length);
The print result is 9, not the expected 8.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.