Reading input pins with johnny-five and arduino

3.3k Views Asked by At

I'm working on an application using node.js and arduino.

I'm using the johnny-five framework and have uploaded the StandardFirmata sketch to my arduino, which has an arcade controller connected to it on pins 2, 3, 4 and 5.

this is my implementation:

var five = require('johnny-five');
var board

board = new five.Board();

board.on('ready', function(){
   console.log('board is ready');
   this.pinMode(2, five.Pin.INPUT);
   this.pinMode(3, five.Pin.INPUT);
   this.pinMode(4, five.Pin.INPUT);
   this.pinMode(5, five.Pin.INPUT);

   this.digitalRead(2, function(value) {
       if(value === 0)
       {
           console.log('up');
       }
   });

   this.digitalRead(3, function(value) {
       if(value === 0) {
           console.log('right');
       }
   });

   this.digitalRead(4, function(value) {
       if(value === 0) {
           console.log('left');
       }
   });

   this.digitalRead(5, function(value) {
       if(value === 0) {
           console.log('down');
       }
   });

});

Now the problem is when I pull my arcade controller down or up it logs 'up' or 'down' multiple times.. it can be 5 times, it can be 10 times. What am I doing wrong?

2

There are 2 best solutions below

0
On BEST ANSWER

That's completely correct. The values are read faster than your hand moves, so there may be many reads of the current state (whether "HIGH" or "LOW") before you change the physical state of the device. One solution is to debounce the handlers, another is store the last value and only operate on when the current value is different:

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

board.on("ready", function(){
  var directions = {
    up: { pin: 2, value: null },
    right: { pin: 3, value: null },
    left: { pin: 4, value: null },
    down: { pin: 5, value: null },
  };

  Object.keys(directions).forEach(function(key) {
    var pin = directions[key].pin;

    this.pinMode(pin, five.Pin.INPUT);
    this.digitalRead(pin, function(data) {
      // Catpure the initial pin value
      if (directions[key].value === null) {
        directions[key].value = data;
      }

      // Something changed
      if (directions[key].value !== data) {
        console.log(pin, key);
      }

      directions[key].value = data;
    });
  }, this);
});

If you have any further questions, please don't hesitate to join us in the Johnny-Five Gitter Channel.

0
On

You could also make usage of the standard bumper button class of johnny-five for that. It already has debouce implemented.

https://github.com/rwaldron/johnny-five/blob/master/docs/button-bumper.md

var five = require("johnny-five"),
    bumper, led;

five.Board().on("ready", function() {    
  bumper = new five.Button(7);
  led = new five.Led(13);

  bumper.on("hit", function() {   
    led.on();    
  }).on("release", function() {    
    led.off();    
  });
});

It would require you a refactoring of your code, but it would be much cleaner after.