sarahghp / p5bots

Use your microcontroller with p5.js
GNU Lesser General Public License v2.1
199 stars 45 forks source link

Problem with dereferencing led blink #25

Open veillette opened 6 years ago

veillette commented 6 years ago

While running the LED example, one runs across a problem.

// Board setup — you may need to change the port
var b = p5.board('/dev/cu.usbmodem1421', 'arduino');

// Blink LED 
var led;

function setup() {
  led = b.pin(9, 'LED');

  createCanvas(300, 200);

  var innerStr = '<p style="font-family:Arial;font-size:12px">'
  innerStr += '<b>&larr;</b> LED on &nbsp; | &nbsp;';
  innerStr += '<b>&rarr;</b> LED off &nbsp; | &nbsp;';
  innerStr += '<b>&uarr;</b> Blink LED &nbsp; | &nbsp;';
  innerStr += '<b>&darr;</b> Stop Blinking </p>';

  createDiv(innerStr);
}

function keyPressed() {
  if (keyCode === LEFT_ARROW){
    led.on();
  } else if (keyCode === RIGHT_ARROW) {
    led.off();
  } else if (keyCode === UP_ARROW){
    led.blink();
  } else if (keyCode === DOWN_ARROW) {
    led.noBlink();
  }
}

I was able to run the program on a metro mini and turn off and on the LED with right and left arrow key. Pressing the up arrow will make the light blinks as expected. However, using the right and left arrow key to turn off the blink is unsuccessful.

I think the problem arises from led portion of p5bot.js

/**
 * Adds led-specific methods to pin object. Called via special.
 *
 * @param  {Object} pin
 * @return {Object} mutated pin
 */
function led(pin) {
  utils.dispatch(utils.pinInit(pin.pin, pin.mode, pin.direction));
  utils.constructFuncs(pin);

  // this is a little hacky but I am only a little sorry
  var blinkCounter = 0;

  pin.on = function() {

    function ledOn() {
      utils.socket.emit('blink cancel');
      if(this.mode !== 'pwm') {
        this.write('HIGH');
      } else {
        this.write(255);
      }
    }

    utils.dispatch(ledOn.bind(this));

  };

  pin.off = function() {

    function ledOff() {
      utils.socket.emit('blink cancel');

      if(this.mode !== 'pwm') {
        this.write('LOW');
      } else {
        this.write(0);
      }
    }

    utils.dispatch(ledOff.bind(this));

  };

  /**
   * Prepares and emits the fade event. The actual math is
   * taken care of in the server LED file.
   *
   * @param  {Number} start             Initial PWM value
   * @param  {Number} stop              End PWM value
   * @param  {Number} [totalTime=3000]  Total time for fade, in ms
   * @param  {Number} [increment=200]   Time taken for each step, in ms
   *
   */
  pin.fade = function(start, stop, totalTime, increment) {
    function ledFade() {

      this.mode = 'pwm';

      var totalTime = totalTime || 3000,
          inc       = increment || 200;
      utils.socket.emit('fade', {
        pin: this.pin,
        start: start,
        stop: stop,
        time: totalTime,
        inc: inc });
    }

    utils.dispatch(ledFade.bind(this));
  };

  pin.blink = function(length) {

    function ledBlink() {
      utils.socket.emit('blink', { pin: [this.pin], length: length, id: blinkCounter });
    }

    utils.dispatch(ledBlink.bind(this));

    ++blinkCounter;

  };

  pin.noBlink = function() {

    function ledNoBlink() {
      utils.socket.emit('blink' + blinkCounter + ' cancel');
    }

    utils.dispatch(ledNoBlink);

  };

  return pin;
}

led.on() sends utils.socket.emit('blink cancel'); but led.noblink() emitted utils.socket.emit('blink' + blinkCounter + ' cancel');.

I think that the call to dispose of the setInterval is improperly referenced for led.on() and led.off()