nebrius / j5-io

An abstract library for creating Raspi IO plugins
MIT License
6 stars 2 forks source link

digitalRead should only emit on change #2

Closed boneskull closed 6 years ago

boneskull commented 7 years ago

Hi,

Thanks for this plugin. I believe that the behavior of digitalRead in raspi-io-core diverges from the behavior of StandardFirmata.

From the StandardFirmata implementation, we see that Firmata will only report a value back to Johnny-Five if that value has changed.

For digital reads, Johnny-Five will typically wrap this in a 5-7ms "debounce", but otherwise its default IO module does not interfere. The rate at which a digital read will be emitted by Johnny-Five is then the responsibility of the IO module itself.

If we wire an Arduino like so:

screenshot

and use the following example code:

var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {
  var spdt = new five.Switch(8);
  spdt.on("open", function() {
    console.error('open');
  });

  spdt.on("close", function() {
    console.error('close');
  });
});

Either open or close will be output once upon board readiness, and only then again if you flip the SPDT switch (assuming a quiet circuit).

If we instead plug this breadboard into a Raspberry Pi (in my case, a Zero, using GPIO4):

image

and then run the same code, open and close are output many times per second.

cc @rwaldron if he cares to fact-check me :wink:

rwaldron commented 7 years ago

For digitalRead, that's correct.

Note: I'm sure a bunch of the other io-plugins are wrong, because I'm a terrible programmer and generally lose track of everything.

boneskull commented 7 years ago

@rwaldron I wonder if there's a reasonable way to provide a test suite to assert IO plugins adhere to a spec. And would that solution catch this issue? I suppose then a the definition of an IO plugin would need to be formalized if it hasn't already.

P.S. you are not a terrible programmer. :smile:

boneskull commented 7 years ago

It seems there'd want to be a test suite which provides a harness to which the IO module would attach itself. Then we could assert that repeated identical digital reads resulted in a single emitted event.

This is not difficult in and of itself. The problem is there'd need to be another level of abstraction which the harness could hook into (e.g. an EventEmitter). The IO modules are too low-level for this. Am I even making sense

boneskull commented 7 years ago

like I couldn't just write a test suite and harness and hand it any given IO module on any given hardware. that would be the goal! unit tests could assert proper input/output but integration tests would be necessary to catch this issue.

nebrius commented 6 years ago

Oh, wow, I'm really sorry. I somehow completely missed this issue and related PR 😱 I'll go check out the PR ASAP.

I wonder if there's a reasonable way to provide a test suite to assert IO plugins adhere to a spec.

Sooooo...notice how this module has no dependencies and doesn't read/write anything from the filesystem or do anything platform specific? The name of this module is actually more specific than the module actually it...this module can be used for any platform!

This also means we could write unit tests easily for it and push the difficult to test parts down to Raspi.js, which is considerably simpler than this module is (this module accounts for something like 1/2 the code in all of Raspi IO).