Merge servo and delay nodes to activate servo just long enough to move to new position based on previous position. Detach servo when timer is done.
servo-pulse
@/servo-pulse
Merge servo and delay nodes to activate servo just long enough to move to new position based on previous position. Detach servo when timer is done.
PORTnumber
Board port number the servo is connected to.
MinTnumber
Minimum Time to move servo a very short distance
MaxTnumber
Maximum Time to move servo 180 degrees
pValnumber
Previous servo position (expected position when we get pulse). -1 for position unknown and force MaxT travel time.
nValnumber
New servo Value in unit range [0.0, 1.0]. For standard servo 0.0 would be mapped to 0° and 1.0 would be 180°.
Startpulse
Start servo move and timer where delay time is calculated based of min/max times and previous/new position.
Valnumber
Copy of nVal that can be used to feed next call to servo-pulse.
ACTboolean
Outputs true when delay is in progress and servo is moving.
Donepulse
Pulses when timer has expired and servo should be done moving (and has been detached).
To use the node in your project you should have the gweimer/servo library installed. Use the “File → Add Library” menu item in XOD IDE if you don’t have it yet. See Using libraries for more info.
C++ implementation
{{#global}}
#include <Servo.h>
{{/global}}
struct State {
Servo servo;
};
{{ GENERATED_CODE }}
void evaluate(Context ctx) {
State* state = getState(ctx);
auto port = (int)getValue<input_PORT>(ctx);
if (isInputDirty<input_Start>(ctx)) {
auto pVal = getValue<input_pVal>(ctx);
auto nVal = getValue<input_nVal>(ctx);
auto minT = getValue<input_MinT>(ctx);
auto maxT = getValue<input_MaxT>(ctx);
state->servo.attach(port);
state->servo.write(nVal * 180);
TimeMs dt = maxT * 1000;
if (pVal > 0) {
nVal = nVal < 0 ? 0 : nVal > 1 ? 1 : nVal;
pVal = pVal > 1 ? 1 : pVal;
dt = ((abs(pVal - nVal) * (maxT - minT)) + minT) * 1000;
}
setTimeout(ctx, dt);
emitValue<output_ACT>(ctx, true);
//emitValue<output_Val>(ctx, nVal);
emitValue<output_Val>(ctx, dt);
} else if (isTimedOut(ctx)) {
state->servo.detach();
emitValue<output_Done>(ctx, true);
emitValue<output_ACT>(ctx, false);
}
}