-
• #2
I think likely what happens is the digitalPulse in servo causes an exception which stops the next command executing which in turn causes the interval to keep on being called.
Unminified source is at : http://www.espruino.com/modules/servo.js
Is that literally all the code you have there? because I'd only expect that error if you were calling
move
with something outside the 0..1 range -
• #3
indeed, that's all my code - I just wanted to "quickly" test a servo (but nothing works quickly if I am touching it - I tend to break everything)
Amendment: I also just checked the firmware state (just to be sure): and, yes, it is 2v10
Amendment 2: just to be sure, I flashed 2v10 one more time and tried my code again - with the same result.
-
• #4
I just looked into the code you referenced - and I found a potential problem:
if (callback) callback();
Shouldn't you always
return callback()
?Amendment: I found the mistake - if a callback is given,
time
must be specified as well, otherwise the callback function is taken as thetime
argument.If you like, you may change the beginning of your
move
function like so:return {move:function(pos, time, callback) { if (typeof time === 'function') { callback = time; time = undefined; } if (typeof time !== 'number') time = 1000;
At least, you should protect the
time
argument better (an error message would be fine, but you may not have enough resources on the device for such an approach) -
• #5
I changed your code a bit, and now everything works as foreseen. Here is my complete test
//var Servo = require('servo').connect(C7, { range:2 }); function Servo_connect (pin,options) { var interval, currentPos; var offs = 1, mul = 1; if (options && options.range) { mul = options.range; offs = 1.5-(mul/2); } return {move:function(pos, time, callback) { if (typeof time === 'function') { callback = time; time = undefined; } if (typeof time !== 'number') time = 1000; var amt = 0; if (currentPos===undefined) currentPos = pos; if (interval) clearInterval(interval); var initial = currentPos; interval = setInterval(function() { currentPos = pos*amt + initial*(1-amt); digitalPulse(pin, 1, offs+E.clip(currentPos,0,1)*mul); if (amt >= 1) { clearInterval(interval); interval = undefined; if (callback) callback(); return; } else { amt += 1000.0 / (20*time); } }, 20); }}; } let Servo = Servo_connect(C7, { range:2 }); let Count = 0; function move () { if (Count < 10) { Count++; print('Count: ' + Count); Servo.move(1, 1000, move); } } move();
Since you
clearInterval
, an explicitreturn
is not necessary, but it may be a good idea to restricttime
to values > 0 in order to avoid a division by zero (or negative values) -
• #6
Sorry - missed this! So it did work ok, but it was just the usage of
move
?The
typeof time
check sounds good to me - I'll get those changes in -
• #7
Well, the primary problem was that I passed my
callback
as the second argument - where you expect atime
. And because of a proper check I did not immediately find the mistake.move
worked as intended - the endless loop was a side-effect of the wrongtime
argument.
I just tried to drive an SG90 Micro Servo with 360° gear from an Original Espruino, wired to pin C7 (as the example suggests) -
{ range:2 }
was the outcome of another test with an "ordinary" SG90.However, when uploading this code from the Web IDE it leads to an endless loop of error messages (and finally crashes the Chrome browser):
Does this code try to recursively call
Servo.move
rather than my functionmove
? But why does it then lead to an endless loop?Amendment: renaming my function
move
tomoveServo
still loops endlessly