You are reading a single comment by @allObjects and its replies. Click here to read the full conversation.
  • I took a look at the module... and noticed, that the internally defined currentPos(ition) variable is not initialized (and how could it... it cannot, because there is no way to read the servo position to initialize it - no closed loop servo...).

    On a first call after connect, the demanded and passed on pos is gulped up for the initialization. When it then comes to calculate the pulse length for gradually moving there, the formula fails - has to fail - and no 'gradual' takes place. The failure is though very smart and catches 2 birds with one stone: servo is in demanded position and currentPos is properly initialized to match... ;-)

    Therefore, a separate, initial call has to be made to either position 0 or 1 (actually any position in between works as well), to get the currentPos initialized.

    Btw, I do not have the hardware to verify... it is just a thought experiment based on code analysis - which means, I could be totally wrong... :((((

    Here is the module code to work through the first call:

    exports.connect = function (pin) {
      var interval, currentPos;
    
      return {move:function(pos, time, callback) {
        if (time===undefined) time = 1000;
        var amt = 0;
        if (currentPos===undefined) currentPos = pos;
        if (interval) clearInterval(interval);
        var initial = currentPos;
        interval = setInterval(function() {
          if (amt>1) {
            clearInterval(interval);
            interval = undefined;
            amt = 1;
            if (callback) callback();
          }
          currentPos = pos*amt + initial*(1-amt);
          digitalPulse(pin, 1, 1+E.clip(currentPos,0,1));
          amt += 1000.0 / (20*time);
        }, 20);
      }};
    };
    

    On the very first call after connect, position 0 is demanded and to be reached in 3000[ms].

    In the code section before the interval - precisely in line 7 - the condition evaluates to true and currentPos is set to demanded pos, which is 0, and the same value is then taken on by initial.

    In the interval callback function - on first call, amt is still 0 as initialized in the begin of the call, and therefore, the block of lines 11 through 16 is skipped.

    In line 17, the 'new' currentPos is calculated for executing the first amount of movement 0 and should be a fraction according to the time given or the 1000[ms] default. But with currentPos equal 0 and taken on by initial in line 9, it IS ALREADY the demanded position 0. So the very first pulse sent in line 18 is 1[ms] and is the pulse length to tell the servo to 'go to position 0' - and the obedient servo goes right as fast it can into the the final position: 0.

    The 'after math' of the first callback invocation as any other after it - until the time is up, which is 3000[ms] / 50[ms] = 60 times - calculates an amt, but the currentPos will always be 0 because of the formula and pos AND initial do not change and are both still 0.

    In other words, with the very first pulse ever, the servo jumps right into the demanded position, and is then (again) 'going there' for the demanded time, before another the call back is checked and executed or another call is made.

    To make your code work, position to any value 0..1 before doing your sequence...

    Conclusion: works as designed!

About

Avatar for allObjects @allObjects started