• ;-) somehow, I expected your response... but did not want to make further comment before this had been cleared.

    I make you now some suggestions that take more advantage of oo and Espruino. Furthermore, you have to know that the odd 'steps' are not stable steps: when hit stop - apply 0 to all pins - at any of these, the motor will either move forward to next even 'step' or ' back to previous even 'step'. If you want to use 'stop' state (all pins 0 / off), you best compensate that internally by making for one external step two internal steps. Since you (may) expose (and use) .stop() you have to make sure that you always make an extra internal step (in the current direction) when stop hit's at an odd internal step.

    First, use Javascript's 'idea' of oo by using prototype and -second, use Espruino's support for setInterval (or setTimeout). Using prototype saves you memory. Using intervals (or timeouts) makes it possible that more than one stepper can move at one time... (your current piece of code hogs the process until all steps are done). - Times are in milliseconds [ms].

    // Stepper module - 2-phases 5-leads stepper
    
    // define 'static parts' - same for each instance
    var steps = [0b0001, 0b0011, 0b0010, 0b0110, 0b0100, 0b1100, 0b1000, 0b1001];
    var stop = 0b0000;
    var defaultIntervalTime = 10;
    var minimalIntervalTime = 4;
    
    // Class / state - constructor (with pins, intervalTime) - defines state of the individual instances
    var Stepper = function(p1,p2,p3,p4,intervalTime) {
      this.pins = [p1,p2,p3,p4];
      this.intervalTime = defaultIntervalTime;
      this.intervalTime = this._getIntervalTime(intervalTime);
      this.interval = null;
      this.stepsToGo = 0;
      this.st = 0;
    };
    
    // .connect()-style constructor (for convenience) with same parms as default contructor)
    Stepper.connect = function(p1,p2,p3,p4,intervalTime) {
      return new Stepper(p1,p2,p3,p4,intervalTime);
    };
    
    // temp stepper prototype - used 'to stick behavior' to instances
    var p = Stepper.prototype;
      
    // instance methods - defines behavior common to and reused by all the instances
    p._step = function() {
      digitalWrite(this.pins,steps[this.st = ++this.st % 8]);
      if (--this.stepsToGo < 1) { this.stop(); }
    };
    
    p.step = function(stepsToGo,intervalTime) {
      this.stepsToGo = stepsToGo * 2; 
      this.intervalTime = this._getIntervalTime(intervalTime);
      var _this = this;
      this.interval = setInterval(function(){
        _this._step(); }, this.intervalTime);
    };
    
    p.stop = function() {
      if (this.interval) { 
        clearInterval(this.interval);
        this.interval = null;
      } 
      if (this.st % 2) {
        digitalWrite(this.pins,steps[this.st = ++this.st % 8]);
        --this.stepsToGo;
      }
      digitalWrite(this.pins, stop);
    };
    
    // return a valid interval time
    p._getIntervalTime = function(intervalTime) {
      var t = ( (isNaN(intervalTime) || (intervalTime < minimalIntervalTime))
             ? this.intervalTime : intervalTime );
      return t;
    };
    
    export = Stepper;
    

    To use this Stepper class you write:

    var Stepper = require("Stepper");
    var stepper1 = new Stepper(A0,A1,A2,A3); // takes default stepping interval of 10[ms]
    var stepper2 = new Stepper(A4,A5,A6,A7,20); // takes 20[ms] as stepping interval
    stepper1.step(256); // 256 steps = full circle with your stepper, 
                          // takes 5120[ms]  (512 (internal) steps * 10[ms] = 5120[ms] = 5.12 seconds)
    stepper2.step(128); // half circle in same time
    

    Note that the code executed at every interval - this is the method ._step() - has to be as short as possible.

    Regarding naming, this may be a helpful rule-of-thumb:

    • Uppercase beginning, camel-cased names are classes names (you can then avoid Class suffix)
    • lowercase beginning, camel-cased names are methods and variable names
    • _beginning, camel-cased names are for 'private' things only 'knowlegable'/tightly coupled code code should use (even though privacy is not (easy) enforceable in JavaScript)
About

Avatar for allObjects @allObjects started