Skip to content
This repository has been archived by the owner on Aug 5, 2022. It is now read-only.

Support Generic Sensor APIs for common sensors #96

Closed
kenchris opened this issue Aug 8, 2016 · 5 comments
Closed

Support Generic Sensor APIs for common sensors #96

kenchris opened this issue Aug 8, 2016 · 5 comments

Comments

@kenchris
Copy link
Contributor

kenchris commented Aug 8, 2016

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 })
@grgustaf
Copy link
Contributor

I had just noticed the DHT22 on adafruit yesterday and wondered how we would support something like that. So this sounds great, I'd like to look at it myself if I can finish up the stuff I'm doing right now.

@kenchris
Copy link
Contributor Author

kenchris commented Aug 10, 2016

Be aware that there are two versions (one external, and one which requires external pullup resistor or the communication channel won't work at all).

The Generic Sensor API will have to be adjusted for Node.js (We had planned to do that, but the funding to the guy contracted to do it was cut - so I don't know the status). The big issue is that there are no DOMString (just String which is basically the same), no DOMHighResTimers (can be emulated with double) and no EventTarget (but an EventEmitter which works quite differently) in node.js.

Here is how the temperature API would look with EventEmitter (my adjustments). Changes are market by ** ... **

**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);
});

@kenchris
Copy link
Contributor Author

This here is the one with internal pullup: https://www.adafruit.com/products/393
And the one without: https://www.adafruit.com/products/385

As the Arduino 101 has a six-axis accelerometer and gyroscope we can also implement:

https://rawgit.com/w3c/gyroscope/gh-pages/index.html
https://rawgit.com/w3c/accelerometer/gh-pages/index.html

in a similar fashion, without needing a special option to select controller.

@kenchris
Copy link
Contributor Author

Going to split this out into other bugs and just let this be about the actual Sensor objects

@grgustaf grgustaf self-assigned this Aug 10, 2016
@grgustaf grgustaf assigned jimmy-huang and unassigned grgustaf Dec 1, 2016
@grgustaf
Copy link
Contributor

Closing because the basic API is there and the A101 built-in sensors are supported. Other issues have been opened for the DHT22 specifically.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants