Search code examples
javascriptnode.jsarduinojohnny-five

Reading input pins with johnny-five and arduino


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?


Solution

  • 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.